Memory leak, but otherwise working

This commit is contained in:
Dynamitos
2023-11-16 22:58:47 +01:00
parent 35966cb5b7
commit 3dc5855d6c
27 changed files with 558 additions and 674 deletions
+57 -57
View File
@@ -13,72 +13,72 @@ struct SkyboxData
layout(set=1)
ParameterBlock<SkyboxData> pSkyboxData;
float3 vertices[] = {
// Back
float3(-512, -512, 512),
float3(-512, 512, 512),
float3( 512, -512, 512),
float3( 512, -512, 512),
float3(-512, 512, 512),
float3( 512, 512, 512),
// Front
float3( 512, -512, -512),
float3( 512, 512, -512),
float3(-512, -512, -512),
float3(-512, -512, -512),
float3( 512, 512, -512),
float3(-512, 512, -512),
// Top
float3(-512, -512, -512),
float3(-512, -512, 512),
float3( 512, -512, -512),
float3( 512, -512, -512),
float3(-512, -512, 512),
float3( 512, -512, 512),
// Bottom
float3(-512, 512, 512),
float3(-512, 512, -512),
float3( 512, 512, 512),
float3( 512, 512, 512),
float3(-512, 512, -512),
float3( 512, 512, -512),
// Left
float3(-512, -512, -512),
float3(-512, 512, -512),
float3(-512, -512, 512),
float3(-512, -512, 512),
float3(-512, 512, -512),
float3(-512, 512, 512),
// Right
float3( 512, -512, 512),
float3( 512, 512, 512),
float3( 512, -512, -512),
float3( 512, -512, -512),
float3( 512, 512, 512),
float3( 512, 512, -512),
};
[shader("vertex")]
VertexShaderOutput vertexMain(
uint vertexIndex : SV_VertexId)
{
const float3 vertices[] = {
// Back
float3(-512, -512, 512),
float3(-512, 512, 512),
float3( 512, -512, 512),
float3( 512, -512, 512),
float3(-512, 512, 512),
float3( 512, 512, 512),
// Front
float3( 512, -512, -512),
float3( 512, 512, -512),
float3(-512, -512, -512),
float3(-512, -512, -512),
float3( 512, 512, -512),
float3(-512, 512, -512),
// Top
float3(-512, -512, -512),
float3(-512, -512, 512),
float3( 512, -512, -512),
float3( 512, -512, -512),
float3(-512, -512, 512),
float3( 512, -512, 512),
// Bottom
float3(-512, 512, 512),
float3(-512, 512, -512),
float3( 512, 512, 512),
float3( 512, 512, 512),
float3(-512, 512, -512),
float3( 512, 512, -512),
// Left
float3(-512, -512, -512),
float3(-512, 512, -512),
float3(-512, -512, 512),
float3(-512, -512, 512),
float3(-512, 512, -512),
float3(-512, 512, 512),
// Right
float3( 512, -512, 512),
float3( 512, 512, 512),
float3( 512, -512, -512),
float3( 512, -512, -512),
float3( 512, 512, 512),
float3( 512, 512, -512),
};
VertexShaderOutput output;
float3x3 cameraRotation = float3x3(pViewParams.viewMatrix);
float4 worldPos = float4(mul(cameraRotation, vertices[vertexIndex]), 1.0f);
//clip(dot(worldPos, clipPlane));
output.clipPos = mul(pViewParams.projectionMatrix, worldPos);
output.texCoords = normalize(input.position);
output.texCoords = normalize(vertices[vertexIndex]);
return output;
}
+1 -2
View File
@@ -216,9 +216,8 @@ int main()
mainWindowInfo.title = "SeeleEngine";
mainWindowInfo.width = 1280;
mainWindowInfo.height = 720;
mainWindowInfo.bFullscreen = false;
mainWindowInfo.numSamples = 1;
mainWindowInfo.pixelFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM;
mainWindowInfo.preferredFormat = Gfx::SE_FORMAT_B8G8R8A8_SRGB;
auto window = windowManager->addWindow(graphics, mainWindowInfo);
ViewportCreateInfo sceneViewInfo;
sceneViewInfo.dimensions.size.x = 1280;
+4 -2
View File
@@ -746,12 +746,14 @@ public:
}
StaticArray(std::initializer_list<T> init)
{
assert(init.size() == N);
auto beg = init.begin();
for (size_t i = 0; i < N; ++i)
{
_data[i] = *beg;
beg++;
if (init.size() == N)
{
beg++;
}
}
}
~StaticArray()
-1
View File
@@ -179,7 +179,6 @@ public:
, _size(std::move(other._size))
, allocator(std::move(other.allocator))
{
other.clear();
}
List(List&& other, const Allocator& alloc)
: root(std::move(other.root))
+1 -30
View File
@@ -260,18 +260,6 @@ public:
markIteratorsDirty();
return getNode(root)->pair.value;
}
constexpr mapped_type& operator[](key_type&& key)
{
root = splay(root, std::move(key));
if (!isValid(root) || !equal(getNode(root)->pair.key, key))
{
root = insert(root, std::move(key));
_size++;
}
markIteratorsDirty();
return getNode(root)->pair.value;
}
constexpr const mapped_type& operator[](const key_type& key) const
{
size_t it = root;
@@ -288,23 +276,6 @@ public:
}
return getNode(it)->pair.value;
}
constexpr const mapped_type& operator[](key_type&& key) const
{
size_t it = root;
while (!equal(getNode(it)->pair.key, key))
{
if (comp(key, getNode(it)->pair.key))
{
it = getNode(it)->leftChild;
}
else
{
it = getNode(it)->rightChild;
}
}
return getNode(it)->pair.value;
}
constexpr mapped_type& at(const key_type& key)
{
root = splay(root, key);
@@ -361,6 +332,7 @@ public:
{
root = remove(root, key);
refreshIterators();
assert(root != SIZE_MAX || _size == 0);
return iterator(root, &nodeContainer);
}
constexpr iterator erase(key_type&& key)
@@ -528,7 +500,6 @@ private:
endIndex = getNode(endIndex)->rightChild;
}
return Iterator(endIndex, &nodeContainer, std::move(endTraversal));
}
Array<Node, NodeAlloc> nodeContainer = Array<Node, NodeAlloc>();
size_t root;
+5 -2
View File
@@ -28,7 +28,9 @@ target_sources(Engine
Texture.h
Texture.cpp
VertexData.h
VertexData.cpp)
VertexData.cpp
Window.h
Window.cpp)
target_sources(Engine
PUBLIC FILE_SET HEADERS
@@ -47,7 +49,8 @@ target_sources(Engine
Shader.h
StaticMeshVertexData.h
Texture.h
VertexData.h)
VertexData.h
Window.h)
add_subdirectory(RenderPass/)
add_subdirectory(Vulkan/)
+4 -4
View File
@@ -8,12 +8,12 @@ LegacyPipelineCreateInfo::LegacyPipelineCreateInfo()
: topology(Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
, multisampleState(MultisampleState{
.samples = 1,
})
})
, rasterizationState(RasterizationState{
.polygonMode = Gfx::SE_POLYGON_MODE_FILL,
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
.frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE,
})
})
, depthStencilState(DepthStencilState{
.depthTestEnable = true,
.depthWriteEnable = true,
@@ -21,7 +21,7 @@ LegacyPipelineCreateInfo::LegacyPipelineCreateInfo()
.stencilTestEnable = false,
.minDepthBounds = 0.0f,
.maxDepthBounds = 1.0f,
})
})
, colorBlend(ColorBlendState{
.logicOpEnable = false,
.attachmentCount = 0,
@@ -40,7 +40,7 @@ LegacyPipelineCreateInfo::LegacyPipelineCreateInfo()
1.0f,
1.0f,
},
})
})
{
}
+1 -2
View File
@@ -36,9 +36,8 @@ struct WindowCreateInfo
int32 width;
int32 height;
const char *title;
bool bFullscreen;
Gfx::SeSampleCountFlags numSamples;
Gfx::SeFormat pixelFormat;
Gfx::SeFormat preferredFormat = Gfx::SE_FORMAT_MAX_ENUM;
void *windowHandle;
};
struct ViewportCreateInfo
+4 -3
View File
@@ -48,9 +48,6 @@ void BasePass::beginFrame(const Component::Camera& cam)
RenderPass::beginFrame(cam);
lightCullingLayout->reset();
descriptorSets[INDEX_VIEW_PARAMS] = viewParamsSet;
descriptorSets[INDEX_LIGHT_ENV] = scene->getLightEnvironment()->getDescriptorSet();
descriptorSets[INDEX_LIGHT_CULLING] = lightCullingLayout->allocateDescriptorSet();
}
void BasePass::render()
@@ -68,6 +65,10 @@ void BasePass::render()
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
descriptorSets[INDEX_VIEW_PARAMS] = viewParamsSet;
descriptorSets[INDEX_LIGHT_ENV] = scene->getLightEnvironment()->getDescriptorSet();
descriptorSets[INDEX_LIGHT_CULLING] = lightCullingLayout->allocateDescriptorSet();
descriptorSets[INDEX_LIGHT_CULLING]->updateBuffer(0, oLightIndexList);
descriptorSets[INDEX_LIGHT_CULLING]->updateBuffer(1, tLightIndexList);
descriptorSets[INDEX_LIGHT_CULLING]->updateTexture(2, oLightGrid);
@@ -145,8 +145,8 @@ void DepthPrepass::publishOutputs()
// still match the size of the whole image or their coordinate systems go out of sync
TextureCreateInfo depthBufferInfo = {
.format = Gfx::SE_FORMAT_D32_SFLOAT,
.width = viewport->getOwner()->getWidth(),
.height = viewport->getOwner()->getHeight(),
.width = viewport->getOwner()->getFramebufferWidth(),
.height = viewport->getOwner()->getFramebufferHeight(),
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
};
depthBuffer = graphics->createTexture2D(depthBufferInfo);
@@ -51,7 +51,6 @@ void SkyboxRenderPass::render()
renderCommand->setViewport(viewport);
renderCommand->bindPipeline(pipeline);
renderCommand->bindDescriptor({viewParamsSet, skyboxDataSet, textureSet});
renderCommand->bindVertexBuffer({ cubeBuffer });
renderCommand->draw(36, 1, 0, 0);
graphics->executeCommands(Array{ renderCommand });
graphics->endRenderPass();
-34
View File
@@ -3,40 +3,6 @@
using namespace Seele;
using namespace Seele::Gfx;
Window::Window(const WindowCreateInfo& createInfo)
: windowState(createInfo)
{
}
Window::~Window()
{
}
Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo)
: sizeX(std::min(owner->getWidth(), viewportInfo.dimensions.size.x))
, sizeY(std::min(owner->getHeight(), viewportInfo.dimensions.size.y))
, offsetX(viewportInfo.dimensions.offset.x)
, offsetY(viewportInfo.dimensions.offset.y)
, fieldOfView(viewportInfo.fieldOfView)
, owner(owner)
{
}
Viewport::~Viewport()
{
}
Matrix4 Viewport::getProjectionMatrix() const
{
if (fieldOfView > 0.0f)
{
return glm::perspective(fieldOfView, sizeX / static_cast<float>(sizeY), 0.1f, 1000.0f);
}
else
{
return glm::ortho(0.0f, (float)sizeX, (float)sizeY, 0.0f);
}
}
RenderTargetAttachment::RenderTargetAttachment(PTexture2D texture,
SeAttachmentLoadOp loadOp,
SeAttachmentStoreOp storeOp,
+3 -62
View File
@@ -1,71 +1,12 @@
#pragma once
#include "Resources.h"
#include "Texture.h"
#include "Window.h"
namespace Seele
{
namespace Gfx
{
class Window
{
public:
Window(const WindowCreateInfo &createInfo);
virtual ~Window();
virtual void beginFrame() = 0;
virtual void endFrame() = 0;
virtual void onWindowCloseEvent() = 0;
virtual PTexture2D getBackBuffer() = 0;
virtual void setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback) = 0;
virtual void setMouseMoveCallback(std::function<void(double, double)> callback) = 0;
virtual void setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback) = 0;
virtual void setScrollCallback(std::function<void(double, double)> callback) = 0;
virtual void setFileCallback(std::function<void(int, const char**)> callback) = 0;
virtual void setCloseCallback(std::function<void()> callback) = 0;
constexpr SeFormat getSwapchainFormat() const
{
return windowState.pixelFormat;
}
constexpr SeSampleCountFlags getNumSamples() const
{
return windowState.numSamples;
}
constexpr uint32 getWidth() const
{
return windowState.width;
}
constexpr uint32 getHeight() const
{
return windowState.height;
}
protected:
WindowCreateInfo windowState;
};
DEFINE_REF(Window)
class Viewport
{
public:
Viewport(PWindow owner, const ViewportCreateInfo &createInfo);
virtual ~Viewport();
virtual void resize(uint32 newX, uint32 newY) = 0;
virtual void move(uint32 newOffsetX, uint32 newOffsetY) = 0;
constexpr PWindow getOwner() const {return owner;}
constexpr uint32 getWidth() const {return sizeX;}
constexpr uint32 getHeight() const {return sizeY;}
constexpr uint32 getOffsetX() const {return offsetX;}
constexpr uint32 getOffsetY() const {return offsetY;}
Matrix4 getProjectionMatrix() const;
protected:
uint32 sizeX;
uint32 sizeY;
uint32 offsetX;
uint32 offsetY;
float fieldOfView;
PWindow owner;
};
DEFINE_REF(Viewport)
class RenderTargetAttachment
{
public:
@@ -133,11 +74,11 @@ public:
}
virtual uint32 getWidth() const
{
return owner->getWidth();
return owner->getFramebufferWidth();
}
virtual uint32 getHeight() const
{
return owner->getHeight();
return owner->getFramebufferHeight();
}
private:
PWindow owner;
+8 -11
View File
@@ -44,8 +44,9 @@ Allocation::Allocation(PGraphics graphics, PAllocator pool, VkDeviceSize size, u
VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo)
: device(graphics->getDevice())
, pool(pool)
, bytesAllocated(0)
, bytesAllocated(size)
, bytesUsed(0)
, mappedPointer(nullptr)
, canMap((properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
, isMapped(false)
, properties(properties)
@@ -59,9 +60,7 @@ Allocation::Allocation(PGraphics graphics, PAllocator pool, VkDeviceSize size, u
};
isDedicated = dedicatedInfo != nullptr;
VK_CHECK(vkAllocateMemory(device, &allocInfo, nullptr, &allocatedMemory));
bytesAllocated = size;
freeRanges[0] = size;
}
Allocation::~Allocation()
@@ -95,6 +94,7 @@ OSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice
VkDeviceSize allocatedSize = requestedSize + (alignedOffset - lower);
if (size >= allocatedSize)
{
//std::cout << "Allocating " << lower << "-" << lower + allocatedSize << std::endl;
VkDeviceSize newSize = size - allocatedSize;
VkDeviceSize newLower = lower + allocatedSize;
OSubAllocation alloc = new SubAllocation(this, requestedSize, lower, allocatedSize, alignedOffset);
@@ -113,6 +113,7 @@ OSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice
void Allocation::markFree(PSubAllocation allocation)
{
//std::cout << "Freeing " << allocation->allocatedOffset << "-" << allocation->allocatedOffset + allocation->allocatedSize << std::endl;
assert(activeAllocations.find(allocation) != activeAllocations.end());
VkDeviceSize lowerBound = allocation->allocatedOffset;
VkDeviceSize upperBound = allocation->allocatedOffset + allocation->allocatedSize;
@@ -121,7 +122,7 @@ void Allocation::markFree(PSubAllocation allocation)
{
if (lower + size == lowerBound)
{
freeRanges[lower] = upperBound;
freeRanges[lower] = size + allocation->allocatedSize;
freeRanges.erase(lowerBound);
lowerBound = lower;
break;
@@ -134,10 +135,6 @@ void Allocation::markFree(PSubAllocation allocation)
}
activeAllocations.remove(allocation, false);
bytesUsed -= allocation->allocatedSize;
if (bytesUsed == 0)
{
pool->free(this);
}
}
void Allocation::flushMemory()
@@ -205,7 +202,7 @@ OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2
{
OAllocation newAllocation = new Allocation(graphics, this, requirements.size, memoryTypeIndex, properties, dedicatedInfo);
heaps[heapIndex].inUse += newAllocation->bytesAllocated;
std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl;
std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize * 100 << "%" << std::endl;
heaps[heapIndex].allocations.add(std::move(newAllocation));
return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment);
}
@@ -225,7 +222,7 @@ OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2
// no suitable allocations found, allocate new block
OAllocation newAllocation = new Allocation(graphics, this, (requirements.size > DEFAULT_ALLOCATION) ? requirements.size : DEFAULT_ALLOCATION, memoryTypeIndex, properties, nullptr);
heaps[heapIndex].inUse += newAllocation->bytesAllocated;
std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl;
std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize * 100 << "%" << std::endl;
heaps[heapIndex].allocations.add(std::move(newAllocation));
return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment);
}
@@ -240,7 +237,7 @@ void Allocator::free(PAllocation allocation)
if (heaps[heapIndex].allocations[alloc] == allocation)
{
heaps[heapIndex].inUse -= allocation->bytesAllocated;
std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl;
std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize * 100 << "%" << std::endl;
heaps[heapIndex].allocations.removeAt(alloc, false);
return;
}
+5 -5
View File
@@ -24,14 +24,14 @@ target_sources(Engine
Queue.cpp
RenderPass.h
RenderPass.cpp
RenderTarget.h
RenderTarget.cpp
Resources.h
Resources.cpp
Shader.h
Shader.cpp
Texture.h
Texture.cpp)
Texture.cpp
Window.h
Window.cpp)
target_sources(Engine
PUBLIC FILE_SET HEADERS
@@ -48,8 +48,8 @@ target_sources(Engine
PipelineCache.h
Queue.h
RenderPass.h
RenderTarget.h
Resources.h
Shader.h
Texture.h)
Texture.h
Window.h)
+7 -2
View File
@@ -6,7 +6,7 @@
#include "RenderPass.h"
#include "Pipeline.h"
#include "Descriptor.h"
#include "RenderTarget.h"
#include "Window.h"
#include <vulkan/vulkan_core.h>
using namespace Seele;
@@ -58,7 +58,8 @@ void Command::end()
void Command::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer)
{
assert(state == State::Begin);
boundRenderPass = renderPass;
boundFramebuffer = framebuffer;
VkRenderPassBeginInfo beginInfo = {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.pNext = nullptr,
@@ -74,6 +75,8 @@ void Command::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer)
void Command::endRenderPass()
{
boundRenderPass = nullptr;
boundFramebuffer = nullptr;
vkCmdEndRenderPass(handle);
state = State::Begin;
}
@@ -148,6 +151,7 @@ void Command::checkFence()
for(auto& descriptor : boundDescriptors)
{
descriptor->unbind();
//std::cout << "Unbinding descriptor " << descriptor.cast<DescriptorSet>()->getHandle() << " to cmd " << handle << std::endl;
}
boundDescriptors.clear();
graphics->getDestructionManager()->notifyCmdComplete(this);
@@ -282,6 +286,7 @@ void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorS
assert(descriptorSet->writeDescriptors.size() == 0);
descriptorSet->bind();
//std::cout << "Binding descriptor " << descriptorSet->getHandle() << " to cmd " << handle << std::endl;
boundDescriptors.add(descriptorSet.getHandle());
sets[descriptorSet->getSetIndex()] = descriptorSet->getHandle();
}
+1 -1
View File
@@ -6,7 +6,7 @@
#include "PipelineCache.h"
#include "Command.h"
#include "Descriptor.h"
#include "RenderTarget.h"
#include "Window.h"
#include "RenderPass.h"
#include "Framebuffer.h"
#include "Shader.h"
+4 -5
View File
@@ -23,8 +23,7 @@ void Queue::submitCommandBuffer(PCommand command, uint32 numSignalSemaphores, Vk
std::unique_lock lock(queueLock);
assert(command->state == Command::State::End);
PFence fence = command->fence;
assert(!fence->isSignaled());
assert(!(command->fence->isSignaled()));
VkCommandBuffer cmdHandle = command->handle;
@@ -49,15 +48,15 @@ void Queue::submitCommandBuffer(PCommand command, uint32 numSignalSemaphores, Vk
.pSignalSemaphores = signalSemaphores,
};
VK_CHECK(vkQueueSubmit(queue, 1, &submitInfo, fence->getHandle()));
VK_CHECK(vkQueueSubmit(queue, 1, &submitInfo, command->fence->getHandle()));
command->state = Command::State::Submit;
command->waitFlags.clear();
command->waitSemaphores.clear();
if (Gfx::waitIdleOnSubmit)
{
fence->wait(200 * 1000ull);
command->fence->wait(200 * 1000ull);
}
command->checkFence();
command->checkFence();
}
+9 -7
View File
@@ -121,7 +121,15 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::ORenderTargetLayout _layout, Gfx
};
VK_CHECK(vkCreateRenderPass(graphics->getDevice(), &info, nullptr, &renderPass));
}
RenderPass::~RenderPass()
{
vkDestroyRenderPass(graphics->getDevice(), renderPass, nullptr);
}
uint32 RenderPass::getFramebufferHash()
{
FramebufferDescription description;
std::memset(&description, 0, sizeof(FramebufferDescription));
for (auto& inputAttachment : layout->inputAttachments)
@@ -139,11 +147,5 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::ORenderTargetLayout _layout, Gfx
PTexture2D tex = layout->depthAttachment->getTexture().cast<Texture2D>();
description.depthAttachment = tex->getView();
}
framebufferHash = CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32());
return CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32());
}
RenderPass::~RenderPass()
{
vkDestroyRenderPass(graphics->getDevice(), renderPass, nullptr);
}
+1 -4
View File
@@ -11,10 +11,7 @@ class RenderPass : public Gfx::RenderPass
public:
RenderPass(PGraphics graphics, Gfx::ORenderTargetLayout layout, Gfx::PViewport viewport);
virtual ~RenderPass();
constexpr uint32 getFramebufferHash() const
{
return framebufferHash;
}
uint32 getFramebufferHash();
constexpr VkRenderPass getHandle() const
{
return renderPass;
-412
View File
@@ -1,412 +0,0 @@
#include "RenderTarget.h"
#include "Resources.h"
#include "Graphics.h"
#include "Enums.h"
#include "Command.h"
#include <GLFW/glfw3.h>
using namespace Seele;
using namespace Seele::Vulkan;
double currentFrameDelta = 0;
double Gfx::getCurrentFrameDelta()
{
return currentFrameDelta;
}
void glfwKeyCallback(GLFWwindow* handle, int key, int, int action, int modifier)
{
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->keyCallback((KeyCode)key, (InputAction)action, (KeyModifier)modifier);
}
void glfwMouseMoveCallback(GLFWwindow* handle, double xpos, double ypos)
{
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->mouseMoveCallback(xpos, ypos);
}
void glfwMouseButtonCallback(GLFWwindow* handle, int button, int action, int modifier)
{
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->mouseButtonCallback((MouseButton)button, (InputAction)action, (KeyModifier)modifier);
}
void glfwScrollCallback(GLFWwindow* handle, double xoffset, double yoffset)
{
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->scrollCallback(xoffset, yoffset);
}
void glfwFileCallback(GLFWwindow* handle, int count, const char** paths)
{
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->fileCallback(count, paths);
}
void glfwCloseCallback(GLFWwindow* handle)
{
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->closeCallback();
}
Window::Window(PGraphics graphics, const WindowCreateInfo &createInfo)
: Gfx::Window(createInfo)
, graphics(graphics)
, instance(graphics->getInstance())
, swapchain(VK_NULL_HANDLE)
, numSamples(createInfo.numSamples)
{
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWwindow *handle = glfwCreateWindow(createInfo.width, createInfo.height, createInfo.title, createInfo.bFullscreen ? glfwGetPrimaryMonitor() : nullptr, nullptr);
windowHandle = handle;
glfwSetWindowUserPointer(handle, this);
glfwGetWindowSize(handle, &windowState.width, &windowState.height);
glfwSetKeyCallback(handle, &glfwKeyCallback);
glfwSetCursorPosCallback(handle, &glfwMouseMoveCallback);
glfwSetMouseButtonCallback(handle, &glfwMouseButtonCallback);
glfwSetScrollCallback(handle, &glfwScrollCallback);
glfwSetDropCallback(handle, &glfwFileCallback);
glfwSetWindowCloseCallback(handle, &glfwCloseCallback);
glfwCreateWindowSurface(instance, handle, nullptr, &surface);
uint32_t numQueueFamilies = 0;
vkGetPhysicalDeviceQueueFamilyProperties(graphics->getPhysicalDevice(), &numQueueFamilies, nullptr);
Array<VkQueueFamilyProperties> queueProperties(numQueueFamilies);
vkGetPhysicalDeviceQueueFamilyProperties(graphics->getPhysicalDevice(), &numQueueFamilies, queueProperties.data());
bool viableDevice = false;
for (uint32 i = 0; i < numQueueFamilies; ++i)
{
VkBool32 supportsPresent;
vkGetPhysicalDeviceSurfaceSupportKHR(graphics->getPhysicalDevice(), i, surface, &supportsPresent);
if (supportsPresent)
{
viableDevice = true;
break;
}
}
if (!viableDevice)
{
std::cerr << "Device not suitable for presenting to surface " << surface << ", use a different one" << std::endl;
}
recreateSwapchain(windowState);
}
Window::~Window()
{
vkDestroySwapchainKHR(graphics->getDevice(), swapchain, nullptr);
vkDestroySurfaceKHR(instance, surface, nullptr);
glfwDestroyWindow(static_cast<GLFWwindow *>(windowHandle));
}
void Window::beginFrame()
{
glfwPollEvents();
advanceBackBuffer();
}
void Window::endFrame()
{
present();
}
void Window::onWindowCloseEvent()
{
}
Gfx::PTexture2D Window::getBackBuffer()
{
return PTexture2D(backBufferImages[currentImageIndex]);
}
void Window::setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback)
{
keyCallback = callback;
}
void Window::setMouseMoveCallback(std::function<void(double, double)> callback)
{
mouseMoveCallback = callback;
}
void Window::setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback)
{
mouseButtonCallback = callback;
}
void Window::setScrollCallback(std::function<void(double, double)> callback)
{
scrollCallback = callback;
}
void Window::setFileCallback(std::function<void(int, const char**)> callback)
{
fileCallback = callback;
}
void Window::setCloseCallback(std::function<void()> callback)
{
closeCallback = callback;
}
void Window::advanceBackBuffer()
{
VkResult res = VK_ERROR_OUT_OF_DATE_KHR;
uint32 imageIndex = 0;
const int32 prevSemaphoreIndex = semaphoreIndex;
semaphoreIndex = (semaphoreIndex + 1) % Gfx::numFramesBuffered;
while (res != VK_SUCCESS)
{
res = vkAcquireNextImageKHR(
graphics->getDevice(),
swapchain,
UINT64_MAX,
imageAcquired[semaphoreIndex]->getHandle(),
VK_NULL_HANDLE,
&imageIndex);
if (res == VK_ERROR_OUT_OF_DATE_KHR)
{
semaphoreIndex = prevSemaphoreIndex;
}
if (res == VK_ERROR_SURFACE_LOST_KHR)
{
semaphoreIndex = prevSemaphoreIndex;
}
}
imageAcquiredSemaphore = imageAcquired[semaphoreIndex];
currentImageIndex = imageIndex;
backBufferImages[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkClearColorValue clearColor = {0.0f, 0.0f, 0.0f, 0.0f};
PCommand command = graphics->getGraphicsCommands()->getCommands();
VkImageSubresourceRange range = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
};
vkCmdClearColorImage(
command->getHandle(),
backBufferHandles[currentImageIndex],
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
&clearColor,
1,
&range);
backBufferImages[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
graphics->getGraphicsCommands()->getCommands()->waitForSemaphore(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, imageAcquiredSemaphore);
graphics->getGraphicsCommands()->submitCommands();
}
void Window::recreateSwapchain(const WindowCreateInfo &windowInfo)
{
destroySwapchain();
windowState = windowInfo;
uint32_t numFormats;
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(graphics->getPhysicalDevice(), surface, &numFormats, nullptr));
Array<VkSurfaceFormatKHR> formats(numFormats);
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(graphics->getPhysicalDevice(), surface, &numFormats, formats.data()));
uint32_t numPresentModes;
VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(graphics->getPhysicalDevice(), surface, &numPresentModes, nullptr));
Array<VkPresentModeKHR> modes(numPresentModes);
VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(graphics->getPhysicalDevice(), surface, &numPresentModes, modes.data()));
chooseSurfaceFormat(formats, windowInfo.pixelFormat);
choosePresentMode(modes);
createSwapchain();
}
static uint32_t currentFrameIndex = 0;
void Window::present()
{
backBufferImages[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_PRESENT_SRC_KHR);
graphics->getGraphicsCommands()->submitCommands(renderFinished[currentImageIndex]);
VkSemaphore renderFinishedHandle = renderFinished[currentImageIndex]->getHandle();
VkPresentInfoKHR info = {
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
.pNext = nullptr,
.waitSemaphoreCount = 1,
.pWaitSemaphores = &renderFinishedHandle,
.swapchainCount = 1,
.pSwapchains = &swapchain,
.pImageIndices = (uint32*)&currentImageIndex,
.pResults = 0,
};
VkResult presentResult = VK_ERROR_OUT_OF_DATE_KHR;
// Trial and error
while (presentResult != VK_SUCCESS)
{
presentResult = vkQueuePresentKHR(graphics->getGraphicsCommands()->getQueue()->getHandle(), &info);
}
currentFrameIndex = (currentFrameIndex + 1) % Gfx::numFramesBuffered;
static double lastFrameTime = 0.f;
double currentTime = glfwGetTime();
double currentDelta = currentTime - lastFrameTime;
currentFrameDelta = currentDelta;
lastFrameTime = currentTime;
}
void Window::createSwapchain()
{
VkSurfaceCapabilitiesKHR surfProperties;
VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(graphics->getPhysicalDevice(), surface, &surfProperties));
uint32 desiredNumBuffers = Gfx::numFramesBuffered;
if (desiredNumBuffers < surfProperties.minImageCount)
{
throw new std::logic_error("Trying to buffer less than the minimal number of frames");
}
if (desiredNumBuffers > surfProperties.maxImageCount)
{
throw new std::logic_error("Trying to buffer more than the maximum number of frames");
}
VkSwapchainCreateInfoKHR swapchainInfo = {
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
.pNext = nullptr,
.flags = 0,
.surface = surface,
.minImageCount = desiredNumBuffers,
.imageFormat = surfaceFormat.format,
.imageColorSpace = surfaceFormat.colorSpace,
.imageExtent = {
.width = getWidth(),
.height = getHeight(),
},
.imageArrayLayers = 1,
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
.presentMode = presentMode,
.clipped = VK_TRUE,
};
VK_CHECK(vkCreateSwapchainKHR(graphics->getDevice(), &swapchainInfo, nullptr, &swapchain));
uint32 numSwapchainImages;
VK_CHECK(vkGetSwapchainImagesKHR(graphics->getDevice(), swapchain, &numSwapchainImages, nullptr));
Array<VkImage> swapchainImages(numSwapchainImages);
VK_CHECK(vkGetSwapchainImagesKHR(graphics->getDevice(), swapchain, &numSwapchainImages, swapchainImages.data()));
TextureCreateInfo backBufferCreateInfo = {
.sourceData = {
.owner = Gfx::QueueType::GRAPHICS,
},
.format = cast(surfaceFormat.format),
.width = getWidth(),
.height = getHeight(),
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
};
for (uint32 i = 0; i < numSwapchainImages; ++i)
{
imageAcquired[i] = new Semaphore(graphics);
renderFinished[i] = new Semaphore(graphics);
backBufferImages[i] = new Texture2D(graphics, backBufferCreateInfo, swapchainImages[i]);
backBufferHandles[i] = swapchainImages[i];
VkClearColorValue clearColor;
std::memset(&clearColor, 0, sizeof(VkClearColorValue));
backBufferImages[i]->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkImageSubresourceRange range = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
};
PCommand command = graphics->getGraphicsCommands()->getCommands();
vkCmdClearColorImage(command->getHandle(), backBufferHandles[i], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
backBufferImages[i]->changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
}
graphics->getGraphicsCommands()->submitCommands();
currentImageIndex = -1;
}
void Window::destroySwapchain()
{
if (swapchain != VK_NULL_HANDLE)
{
vkDestroySwapchainKHR(graphics->getDevice(), swapchain, nullptr);
}
for (uint32 i = 0; i < Gfx::numFramesBuffered; ++i)
{
imageAcquired[i] = nullptr;
}
}
void Window::chooseSurfaceFormat(const Array<VkSurfaceFormatKHR> &available, Gfx::SeFormat preferred)
{
VkFormat preferredFormat = cast(preferred);
for (auto availabeFormat : available)
{
if (availabeFormat.format == preferredFormat)
{
surfaceFormat = availabeFormat;
return;
}
}
if (available.size() == 1 && available[0].format == VK_FORMAT_UNDEFINED)
{
surfaceFormat = {VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR};
return;
}
for (const auto &availableFormat : available)
{
if (availableFormat.format == VK_FORMAT_B8G8R8A8_UNORM && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
{
surfaceFormat = availableFormat;
return;
}
}
surfaceFormat = available[0];
}
void Window::choosePresentMode(const Array<VkPresentModeKHR> &modes)
{
for (auto mode : modes)
{
if (mode == VK_PRESENT_MODE_MAILBOX_KHR)
{
presentMode = mode;
return;
}
}
presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
}
Viewport::Viewport(PGraphics graphics, PWindow owner, const ViewportCreateInfo &viewportInfo)
: Gfx::Viewport(owner, viewportInfo), graphics(graphics)
{
handle.width = static_cast<float>(sizeX);
handle.height = static_cast<float>(sizeY);
handle.x = static_cast<float>(offsetX);
handle.y = static_cast<float>(offsetY) + handle.height;
handle.height = -handle.height;
handle.minDepth = 0.f;
handle.maxDepth = 1.f;
}
Viewport::~Viewport()
{
}
void Viewport::resize(uint32 newX, uint32 newY)
{
sizeX = newX;
sizeY = newY;
handle.width = static_cast<float>(sizeX);
handle.y = static_cast<float>(sizeY + offsetX);
handle.height = -static_cast<float>(sizeY);
}
void Viewport::move(uint32 newOffsetX, uint32 newOffsetY)
{
offsetX = newOffsetX;
offsetY = newOffsetY;
handle.x = static_cast<float>(offsetX);
handle.y = static_cast<float>(offsetY + sizeY);
}
+6
View File
@@ -197,7 +197,9 @@ void TextureBase::changeLayout(Gfx::SeImageLayout newLayout)
.image = image,
.subresourceRange = {
.aspectMask = aspect,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = layerCount,
},
};
@@ -328,6 +330,10 @@ void TextureBase::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStag
.image = image,
.subresourceRange = {
.aspectMask = aspect,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
},
};
PCommand command = graphics->getQueueCommands(currentOwner)->getCommands();
+304
View File
@@ -0,0 +1,304 @@
#include "Window.h"
#include "Resources.h"
#include "Graphics.h"
#include "Enums.h"
#include "Command.h"
#include <GLFW/glfw3.h>
using namespace Seele;
using namespace Seele::Vulkan;
double currentFrameDelta = 0;
double Gfx::getCurrentFrameDelta()
{
return currentFrameDelta;
}
void glfwKeyCallback(GLFWwindow* handle, int key, int, int action, int modifier)
{
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->keyCallback((KeyCode)key, (InputAction)action, (KeyModifier)modifier);
}
void glfwMouseMoveCallback(GLFWwindow* handle, double xpos, double ypos)
{
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->mouseMoveCallback(xpos, ypos);
}
void glfwMouseButtonCallback(GLFWwindow* handle, int button, int action, int modifier)
{
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->mouseButtonCallback((MouseButton)button, (InputAction)action, (KeyModifier)modifier);
}
void glfwScrollCallback(GLFWwindow* handle, double xoffset, double yoffset)
{
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->scrollCallback(xoffset, yoffset);
}
void glfwFileCallback(GLFWwindow* handle, int count, const char** paths)
{
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->fileCallback(count, paths);
}
void glfwCloseCallback(GLFWwindow* handle)
{
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->closeCallback();
}
Window::Window(PGraphics graphics, const WindowCreateInfo &createInfo)
: graphics(graphics)
, preferences(createInfo)
, instance(graphics->getInstance())
, swapchain(VK_NULL_HANDLE)
, numSamples(createInfo.numSamples)
{
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWwindow *handle = glfwCreateWindow(createInfo.width, createInfo.height, createInfo.title, nullptr, nullptr);
windowHandle = handle;
glfwSetWindowUserPointer(handle, this);
glfwSetKeyCallback(handle, &glfwKeyCallback);
glfwSetCursorPosCallback(handle, &glfwMouseMoveCallback);
glfwSetMouseButtonCallback(handle, &glfwMouseButtonCallback);
glfwSetScrollCallback(handle, &glfwScrollCallback);
glfwSetDropCallback(handle, &glfwFileCallback);
glfwSetWindowCloseCallback(handle, &glfwCloseCallback);
glfwCreateWindowSurface(instance, handle, nullptr, &surface);
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(graphics->getPhysicalDevice(), surface, &capabilities);
uint32 numFormats;
vkGetPhysicalDeviceSurfaceFormatsKHR(graphics->getPhysicalDevice(), surface, &numFormats, nullptr);
supportedFormats.resize(numFormats);
vkGetPhysicalDeviceSurfaceFormatsKHR(graphics->getPhysicalDevice(), surface, &numFormats, supportedFormats.data());
uint32 numPresentModes;
vkGetPhysicalDeviceSurfacePresentModesKHR(graphics->getPhysicalDevice(), surface, &numPresentModes, nullptr);
supportedPresentModes.resize(numFormats);
vkGetPhysicalDeviceSurfacePresentModesKHR(graphics->getPhysicalDevice(), surface, &numPresentModes, supportedPresentModes.data());
chooseSwapSurfaceFormat();
framebufferFormat = cast(format.format);
chooseSwapPresentMode();
chooseSwapExtent();
framebufferWidth = extent.width;
framebufferHeight = extent.height;
sampleFlags = createInfo.numSamples;
createSwapChain();
}
Window::~Window()
{
vkDestroySwapchainKHR(graphics->getDevice(), swapchain, nullptr);
vkDestroySurfaceKHR(instance, surface, nullptr);
glfwDestroyWindow(static_cast<GLFWwindow *>(windowHandle));
}
void Window::beginFrame()
{
glfwPollEvents();
vkAcquireNextImageKHR(graphics->getDevice(), swapchain, std::numeric_limits<uint64>::max(), imageAvailableSemaphores[currentSemaphoreIndex]->getHandle(), VK_NULL_HANDLE, &currentImageIndex);
swapChainTextures[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
graphics->getGraphicsCommands()->getCommands()->waitForSemaphore(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, imageAvailableSemaphores[currentSemaphoreIndex]);
}
void Window::endFrame()
{
swapChainTextures[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_PRESENT_SRC_KHR);
graphics->getGraphicsCommands()->submitCommands(renderingDoneSemaphores[currentSemaphoreIndex]);
VkSemaphore renderDoneHandle = renderingDoneSemaphores[currentSemaphoreIndex]->getHandle();
VkPresentInfoKHR presentInfo = {
.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
.pNext = nullptr,
.waitSemaphoreCount = 1,
.pWaitSemaphores = &renderDoneHandle,
.swapchainCount = 1,
.pSwapchains = &swapchain,
.pImageIndices = &currentImageIndex,
.pResults = nullptr,
};
VkResult r = vkQueuePresentKHR(graphics->getGraphicsCommands()->getQueue()->getHandle(), &presentInfo);
if(r == VK_SUCCESS)
{ }
else if (r == VK_ERROR_OUT_OF_DATE_KHR || r == VK_SUBOPTIMAL_KHR)
{
createSwapChain();
}
else
{
VK_CHECK(r);
}
currentSemaphoreIndex = (currentSemaphoreIndex + 1) % Gfx::numFramesBuffered;
}
void Window::onWindowCloseEvent()
{
}
Gfx::PTexture2D Window::getBackBuffer()
{
return PTexture2D(swapChainTextures[currentImageIndex]);
}
void Window::setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback)
{
keyCallback = callback;
}
void Window::setMouseMoveCallback(std::function<void(double, double)> callback)
{
mouseMoveCallback = callback;
}
void Window::setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback)
{
mouseButtonCallback = callback;
}
void Window::setScrollCallback(std::function<void(double, double)> callback)
{
scrollCallback = callback;
}
void Window::setFileCallback(std::function<void(int, const char**)> callback)
{
fileCallback = callback;
}
void Window::setCloseCallback(std::function<void()> callback)
{
closeCallback = callback;
}
void Window::chooseSwapSurfaceFormat()
{
for (const auto& supportedFormat : supportedFormats)
{
if (supportedFormat.format == cast(preferences.preferredFormat))
{
format = supportedFormat;
return;
}
}
for (const auto& supportedFormat : supportedFormats)
{
if (supportedFormat.format == VK_FORMAT_R8G8B8A8_SRGB && supportedFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
{
format = supportedFormat;
return;
}
}
format = supportedFormats[0];
}
void Window::chooseSwapPresentMode()
{
for (const auto& supportedPresentMode : supportedPresentModes)
{
if (supportedPresentMode == VK_PRESENT_MODE_MAILBOX_KHR)
{
presentMode = supportedPresentMode;
return;
}
}
presentMode = VK_PRESENT_MODE_FIFO_KHR;
}
void Window::chooseSwapExtent()
{
if (capabilities.currentExtent.width != std::numeric_limits<uint32>::max()) {
extent = capabilities.currentExtent;
return;
}
int width, height;
glfwGetFramebufferSize(static_cast<GLFWwindow*>(windowHandle), &width, &height);
extent = {
static_cast<uint32>(width),
static_cast<uint32>(height),
};
extent.width = std::clamp(extent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
extent.height = std::clamp(extent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
}
void Window::createSwapChain()
{
uint32 imageCount = Gfx::numFramesBuffered;
VkSwapchainCreateInfoKHR createInfo = {
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
.pNext = nullptr,
.surface = surface,
.minImageCount = Gfx::numFramesBuffered,
.imageFormat = format.format,
.imageColorSpace = format.colorSpace,
.imageExtent = extent,
.imageArrayLayers = 1,
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
.preTransform = capabilities.currentTransform,
.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
.presentMode = presentMode,
.clipped = VK_TRUE,
.oldSwapchain = swapchain,
};
VK_CHECK(vkCreateSwapchainKHR(graphics->getDevice(), &createInfo, nullptr, &swapchain));
uint32 numImages;
vkGetSwapchainImagesKHR(graphics->getDevice(), swapchain, &numImages, swapChainImages.data());
assert(numImages == Gfx::numFramesBuffered);
for (uint32 i = 0; i < numImages; ++i)
{
swapChainTextures[i] = new Texture2D(graphics, TextureCreateInfo{
.format = cast(format.format),
.width = extent.width,
.height = extent.height,
.depth = 1,
.mipLevels = 1,
.layers = 1,
.elements = 1,
.samples = 1,
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
}, swapChainImages[i]);
imageAvailableSemaphores[i] = new Semaphore(graphics);
renderingDoneSemaphores[i] = new Semaphore(graphics);
}
}
Viewport::Viewport(PGraphics graphics, PWindow owner, const ViewportCreateInfo &viewportInfo)
: Gfx::Viewport(owner, viewportInfo), graphics(graphics)
{
handle.width = static_cast<float>(sizeX);
handle.height = static_cast<float>(sizeY);
handle.x = static_cast<float>(offsetX);
handle.y = static_cast<float>(offsetY) + handle.height;
handle.height = -handle.height;
handle.minDepth = 0.f;
handle.maxDepth = 1.f;
}
Viewport::~Viewport()
{
}
void Viewport::resize(uint32 newX, uint32 newY)
{
sizeX = newX;
sizeY = newY;
handle.width = static_cast<float>(sizeX);
handle.y = static_cast<float>(sizeY + offsetX);
handle.height = -static_cast<float>(sizeY);
}
void Viewport::move(uint32 newOffsetX, uint32 newOffsetY)
{
offsetX = newOffsetX;
offsetY = newOffsetY;
handle.x = static_cast<float>(offsetX);
handle.y = static_cast<float>(offsetY + sizeY);
}
@@ -24,11 +24,6 @@ public:
virtual void setFileCallback(std::function<void(int, const char**)> callback) override;
virtual void setCloseCallback(std::function<void()> callback);
VkFormat getPixelFormat() const
{
return cast(windowState.pixelFormat);
}
std::function<void(KeyCode, InputAction, KeyModifier)> keyCallback;
std::function<void(double, double)> mouseMoveCallback;
std::function<void(MouseButton, InputAction, KeyModifier)> mouseButtonCallback;
@@ -36,32 +31,30 @@ public:
std::function<void(int, const char**)> fileCallback;
std::function<void()> closeCallback;
protected:
void advanceBackBuffer();
void recreateSwapchain(const WindowCreateInfo &createInfo);
void present();
void destroySwapchain();
void createSwapchain();
void chooseSurfaceFormat(const Array<VkSurfaceFormatKHR> &available, Gfx::SeFormat preferred);
void choosePresentMode(const Array<VkPresentModeKHR> &modes);
OTexture2D backBufferImages[Gfx::numFramesBuffered];
VkImage backBufferHandles[Gfx::numFramesBuffered];
OSemaphore renderFinished[Gfx::numFramesBuffered];
OSemaphore imageAcquired[Gfx::numFramesBuffered];
PSemaphore imageAcquiredSemaphore;
void chooseSwapSurfaceFormat();
void chooseSwapPresentMode();
void chooseSwapExtent();
void createSwapChain();
PGraphics graphics;
WindowCreateInfo preferences;
VkInstance instance;
VkSwapchainKHR swapchain;
VkSampleCountFlags numSamples;
VkPresentModeKHR presentMode;
VkSurfaceKHR surface;
VkSurfaceFormatKHR surfaceFormat;
VkSurfaceCapabilitiesKHR capabilities;
Array<VkSurfaceFormatKHR> supportedFormats;
Array<VkPresentModeKHR> supportedPresentModes;
// the values used for the current swapchain
VkSurfaceFormatKHR format;
VkPresentModeKHR presentMode;
VkExtent2D extent;
void *windowHandle;
int32 currentImageIndex;
int32 acquiredImageIndex;
int32 preAcquiredImageIndex;
int32 semaphoreIndex;
StaticArray<VkImage, Gfx::numFramesBuffered> swapChainImages;
StaticArray<OTexture2D, Gfx::numFramesBuffered> swapChainTextures;
StaticArray<OSemaphore, Gfx::numFramesBuffered> imageAvailableSemaphores;
StaticArray<OSemaphore, Gfx::numFramesBuffered> renderingDoneSemaphores;
uint32 currentImageIndex = 0;
uint32 currentSemaphoreIndex = 0;
};
DEFINE_REF(Window)
+39
View File
@@ -0,0 +1,39 @@
#include "Window.h"
using namespace Seele;
using namespace Seele::Gfx;
Window::Window()
{
}
Window::~Window()
{
}
Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo)
: sizeX(std::min(owner->getFramebufferWidth(), viewportInfo.dimensions.size.x))
, sizeY(std::min(owner->getFramebufferHeight(), viewportInfo.dimensions.size.y))
, offsetX(viewportInfo.dimensions.offset.x)
, offsetY(viewportInfo.dimensions.offset.y)
, fieldOfView(viewportInfo.fieldOfView)
, owner(owner)
{
}
Viewport::~Viewport()
{
}
Matrix4 Viewport::getProjectionMatrix() const
{
if (fieldOfView > 0.0f)
{
return glm::perspective(fieldOfView, sizeX / static_cast<float>(sizeY), 0.1f, 1000.0f);
}
else
{
return glm::ortho(0.0f, (float)sizeX, (float)sizeY, 0.0f);
}
}
+73
View File
@@ -0,0 +1,73 @@
#pragma once
#include "Initializer.h"
#include "Texture.h"
namespace Seele
{
namespace Gfx
{
class Window
{
public:
Window();
virtual ~Window();
virtual void beginFrame() = 0;
virtual void endFrame() = 0;
virtual void onWindowCloseEvent() = 0;
virtual PTexture2D getBackBuffer() = 0;
virtual void setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback) = 0;
virtual void setMouseMoveCallback(std::function<void(double, double)> callback) = 0;
virtual void setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback) = 0;
virtual void setScrollCallback(std::function<void(double, double)> callback) = 0;
virtual void setFileCallback(std::function<void(int, const char**)> callback) = 0;
virtual void setCloseCallback(std::function<void()> callback) = 0;
constexpr SeFormat getSwapchainFormat() const
{
return framebufferFormat;
}
constexpr SeSampleCountFlags getNumSamples() const
{
return sampleFlags;
}
constexpr uint32 getFramebufferWidth() const
{
return framebufferWidth;
}
constexpr uint32 getFramebufferHeight() const
{
return framebufferHeight;
}
protected:
SeFormat framebufferFormat;
SeSampleCountFlags sampleFlags;
uint32 framebufferWidth;
uint32 framebufferHeight;
};
DEFINE_REF(Window)
class Viewport
{
public:
Viewport(PWindow owner, const ViewportCreateInfo& createInfo);
virtual ~Viewport();
virtual void resize(uint32 newX, uint32 newY) = 0;
virtual void move(uint32 newOffsetX, uint32 newOffsetY) = 0;
constexpr PWindow getOwner() const { return owner; }
constexpr uint32 getWidth() const { return sizeX; }
constexpr uint32 getHeight() const { return sizeY; }
constexpr uint32 getOffsetX() const { return offsetX; }
constexpr uint32 getOffsetY() const { return offsetY; }
Matrix4 getProjectionMatrix() const;
protected:
uint32 sizeX;
uint32 sizeY;
uint32 offsetX;
uint32 offsetY;
float fieldOfView;
PWindow owner;
};
DEFINE_REF(Viewport)
}
}
+1
View File
@@ -33,6 +33,7 @@ void Window::render()
view->render();
}
gfxHandle->endFrame();
std::cout << "Render" << std::endl;
}
}