implementing renderpass and vieport

This commit is contained in:
Dynamitos
2020-04-12 15:47:19 +02:00
parent 3ba8f2c2a0
commit 576747c369
54 changed files with 6234 additions and 4202 deletions
-2
View File
@@ -14,8 +14,6 @@ target_sources(SeeleEngine
SceneView.cpp
WindowManager.h
WindowManager.cpp
Window.h
Window.cpp
GraphicsResources.h
GraphicsResources.cpp
GraphicsEnums.h)
-1
View File
@@ -9,5 +9,4 @@ Graphics::Graphics()
Graphics::~Graphics()
{
}
+29 -19
View File
@@ -3,22 +3,32 @@
#include "GraphicsResources.h"
#include "Containers/Array.h"
namespace Seele {
namespace Gfx
{
class Window;
class Graphics
{
public:
Graphics();
~Graphics();
virtual void init(GraphicsInitializer initializer) = 0;
virtual void beginFrame(void* windowHandle) = 0;
virtual void endFrame(void* windowHandle) = 0;
virtual void* createWindow(const WindowCreateInfo& createInfo) = 0;
protected:
friend class Window;
};
DEFINE_REF(Graphics);
}
}
namespace Seele
{
namespace Gfx
{
class Graphics
{
public:
Graphics();
virtual ~Graphics();
virtual void init(GraphicsInitializer initializer) = 0;
virtual PWindow createWindow(const WindowCreateInfo &createInfo) = 0;
virtual PViewport createViewport(PWindow owner, const ViewportCreateInfo &createInfo) = 0;
virtual PRenderPass createRenderPass(PRenderTargetLayout layout) = 0;
virtual void beginRenderPass(PRenderPass renderPass) = 0;
virtual void endRenderPass() = 0;
virtual PTexture2D createTexture2D(const TextureCreateInfo &createInfo) = 0;
virtual PUniformBuffer createUniformBuffer(const BulkResourceData &bulkData) = 0;
virtual PStructuredBuffer createStructuredBuffer(const BulkResourceData &bulkData) = 0;
virtual PVertexBuffer createVertexBuffer(const BulkResourceData &bulkData) = 0;
virtual PIndexBuffer createIndexBuffer(const BulkResourceData &bulkData) = 0;
protected:
friend class Window;
};
DEFINE_REF(Graphics);
} // namespace Gfx
} // namespace Seele
File diff suppressed because it is too large Load Diff
+39 -25
View File
@@ -1,5 +1,6 @@
#include "GraphicsResources.h"
using namespace Seele;
using namespace Seele::Gfx;
void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorType type, uint32 arrayCount)
@@ -30,8 +31,8 @@ void PipelineLayout::addDescriptorLayout(uint32 setIndex, PDescriptorLayout layo
}
if (descriptorSetLayouts[setIndex] != nullptr)
{
auto& thisBindings = descriptorSetLayouts[setIndex]->descriptorBindings;
auto& otherBindings = layout->descriptorBindings;
auto &thisBindings = descriptorSetLayouts[setIndex]->descriptorBindings;
auto &otherBindings = layout->descriptorBindings;
thisBindings.resize(otherBindings.size());
for (size_t i = 0; i < otherBindings.size(); ++i)
{
@@ -48,44 +49,57 @@ void PipelineLayout::addDescriptorLayout(uint32 setIndex, PDescriptorLayout layo
}
}
void PipelineLayout::addPushConstants(const SePushConstantRange& pushConstant)
void PipelineLayout::addPushConstants(const SePushConstantRange &pushConstant)
{
pushConstants.add(pushConstant);
}
UniformBuffer::UniformBuffer()
{
}
UniformBuffer::~UniformBuffer()
{
}
RenderTargetLayout::RenderTargetLayout()
: inputAttachments()
, colorAttachments()
, depthAttachment()
: inputAttachments(), colorAttachments(), depthAttachment()
{
}
RenderTargetLayout::RenderTargetLayout(PTexture2D depthAttachment)
: inputAttachments()
, colorAttachments()
, depthAttachment(depthAttachment)
RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment depthAttachment)
: inputAttachments(), colorAttachments(), depthAttachment(depthAttachment)
{
}
RenderTargetLayout::RenderTargetLayout(PTexture2D colorAttachment, PTexture2D depthAttachment)
: inputAttachments()
, depthAttachment(depthAttachment)
RenderTargetLayout::RenderTargetLayout(PRenderTargetAttachment colorAttachment, PRenderTargetAttachment depthAttachment)
: inputAttachments(), depthAttachment(depthAttachment)
{
colorAttachments.add(colorAttachment);
}
RenderTargetLayout::RenderTargetLayout(Array<PTexture2D> colorAttachments, PTexture2D depthAttachmet)
: inputAttachments()
, colorAttachments(colorAttachments)
, depthAttachment(depthAttachment)
RenderTargetLayout::RenderTargetLayout(Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachmet)
: inputAttachments(), colorAttachments(colorAttachments), depthAttachment(depthAttachment)
{
}
RenderTargetLayout::RenderTargetLayout(Array<PTexture2D> inputAttachments, Array<PTexture2D> colorAttachments, PTexture2D depthAttachment)
: inputAttachments(inputAttachments)
, colorAttachments(colorAttachments)
, depthAttachment(depthAttachment)
RenderTargetLayout::RenderTargetLayout(Array<PRenderTargetAttachment> inputAttachments, Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachment)
: inputAttachments(inputAttachments), colorAttachments(colorAttachments), depthAttachment(depthAttachment)
{
}
Window::Window(const WindowCreateInfo &createInfo)
: sizeX(createInfo.width), sizeY(createInfo.height), bFullscreen(createInfo.bFullscreen), title(createInfo.title), pixelFormat(createInfo.pixelFormat)
{
}
Window::~Window()
{
}
Viewport::Viewport(PWindow owner, const ViewportCreateInfo &viewportInfo)
: sizeX(viewportInfo.sizeX), sizeY(viewportInfo.sizeY), offsetX(viewportInfo.offsetX), offsetY(viewportInfo.offsetY), owner(owner)
{
}
Viewport::~Viewport()
{
}
+361 -230
View File
@@ -9,235 +9,366 @@
namespace Seele
{
struct GraphicsInitializer
namespace Gfx
{
enum class QueueType
{
GRAPHICS = 1,
COMPUTE = 2,
TRANSFER = 3,
DEDICATED_TRANSFER = 4
};
} // namespace Gfx
struct GraphicsInitializer
{
const char *windowLayoutFile;
const char *applicationName;
const char *engineName;
void *windowHandle;
/**
* layers defines the enabled Vulkan layers used in the instance,
* if ENABLE_VALIDATION is defined, standard validation is already enabled
* not yet implemented
*/
Array<const char *> layers;
Array<const char *> instanceExtensions;
Array<const char *> deviceExtensions;
GraphicsInitializer()
: applicationName("SeeleEngine"), engineName("SeeleEngine"), layers{"VK_LAYER_LUNARG_standard_validation"}, instanceExtensions{}, deviceExtensions{"VK_KHR_swapchain"}, windowHandle(nullptr)
{
const char* windowLayoutFile;
const char* applicationName;
const char* engineName;
void* windowHandle;
/**
* layers defines the enabled Vulkan layers used in the instance,
* if ENABLE_VALIDATION is defined, standard validation is already enabled
* not yet implemented
*/
Array<const char*> layers;
Array<const char*> instanceExtensions;
Array<const char*> deviceExtensions;
GraphicsInitializer()
: applicationName("SeeleEngine")
, engineName("SeeleEngine")
, layers{ "VK_LAYER_LUNARG_standard_validation" }
, instanceExtensions{}
, deviceExtensions{ "VK_KHR_swapchain" }
, windowHandle(nullptr)
{}
GraphicsInitializer(const GraphicsInitializer& other)
: applicationName(other.applicationName)
, engineName(other.engineName)
, layers(other.layers)
, instanceExtensions(other.instanceExtensions)
, deviceExtensions(other.deviceExtensions)
{
}
};
struct WindowCreateInfo
{
int32 width;
int32 height;
const char* title;
bool bFullscreen;
};
namespace Gfx
{
struct SePushConstantRange {
SeShaderStageFlags stageFlags;
uint32_t offset;
uint32_t size;
};
class RenderCommandBase
{
};
DEFINE_REF(RenderCommandBase);
class SamplerState
{
public:
virtual ~SamplerState()
{
}
};
DEFINE_REF(SamplerState);
class DescriptorBinding
{
public:
DescriptorBinding()
: binding(0)
, descriptorType(SE_DESCRIPTOR_TYPE_MAX_ENUM)
, descriptorCount(-1)
, shaderStages(SE_SHADER_STAGE_ALL)
{}
DescriptorBinding(const DescriptorBinding& other)
: binding(other.binding)
, descriptorType(other.descriptorType)
, descriptorCount(other.descriptorCount)
, shaderStages(other.shaderStages)
{}
void operator=(const DescriptorBinding& other)
{
binding = other.binding;
descriptorType = other.descriptorType;
descriptorCount = other.descriptorCount;
shaderStages = other.shaderStages;
}
uint32_t binding;
SeDescriptorType descriptorType;
uint32_t descriptorCount;
SeShaderStageFlags shaderStages;
};
DEFINE_REF(DescriptorBinding);
DECLARE_REF(DescriptorSet);
class DescriptorAllocator
{
public:
DescriptorAllocator() {}
~DescriptorAllocator() {}
virtual void allocateDescriptorSet(PDescriptorSet& descriptorSet) = 0;
};
DEFINE_REF(DescriptorAllocator);
DECLARE_REF(UniformBuffer);
DECLARE_REF(StructuredBuffer);
DECLARE_REF(Texture);
class DescriptorSet
{
public:
virtual ~DescriptorSet() {}
virtual void writeChanges() = 0;
virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0;
virtual void updateBuffer(uint32 binding, PStructuredBuffer structuredBuffer) = 0;
virtual void updateSampler(uint32 binding, PSamplerState samplerState) = 0;
virtual void updateTexture(uint32 binding, PTexture texture, PSamplerState samplerState = nullptr) = 0;
virtual bool operator<(PDescriptorSet other) = 0;
};
DEFINE_REF(DescriptorSet);
class DescriptorLayout
{
public:
DescriptorLayout() {}
virtual ~DescriptorLayout() {}
void operator=(const DescriptorLayout& other)
{
descriptorBindings.resize(other.descriptorBindings.size());
std::memcpy(descriptorBindings.data(), other.descriptorBindings.data(), sizeof(DescriptorLayout) * descriptorBindings.size());
}
virtual void create() = 0;
virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1);
virtual PDescriptorSet allocatedDescriptorSet();
const Array<DescriptorBinding>& getBindings() const { return descriptorBindings; }
protected:
Array<DescriptorBinding> descriptorBindings;
PDescriptorAllocator allocator;
friend class PipelineLayout;
friend class DescriptorAllocator;
};
DEFINE_REF(DescriptorLayout);
class PipelineLayout
{
public:
PipelineLayout() {}
virtual ~PipelineLayout() {}
virtual void create() = 0;
void addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout);
void addPushConstants(const SePushConstantRange& pushConstants);
virtual uint32 getHash() const = 0;
protected:
Array<PDescriptorLayout> descriptorSetLayouts;
Array<SePushConstantRange> pushConstants;
};
DEFINE_REF(PipelineLayout);
class VertexDeclaration
{
};
DEFINE_REF(VertexDeclaration);
class GraphicsPipeline
{
public:
virtual ~GraphicsPipeline()
{
}
};
DEFINE_REF(GraphicsPipeline);
class UniformBuffer
{
public:
virtual ~UniformBuffer()
{
}
};
DEFINE_REF(UniformBuffer);
class Viewport
{
};
DEFINE_REF(Viewport);
class VertexBuffer
{
};
DEFINE_REF(VertexBuffer);
class IndexBuffer
{
};
DEFINE_REF(IndexBuffer);
class StructuredBuffer
{
public:
virtual ~StructuredBuffer()
{
}
};
DEFINE_REF(StructuredBuffer);
class Texture
{
};
DEFINE_REF(Texture);
class Texture2D : public Texture
{
public:
virtual ~Texture2D()
{
}
};
DEFINE_REF(Texture2D);
class RenderTargetLayout
{
public:
RenderTargetLayout();
RenderTargetLayout(PTexture2D depthAttachment);
RenderTargetLayout(PTexture2D colorAttachment, PTexture2D depthAttachment);
RenderTargetLayout(Array<PTexture2D> colorAttachments, PTexture2D depthAttachmet);
RenderTargetLayout(Array<PTexture2D> inputAttachments, Array<PTexture2D> colorAttachments, PTexture2D depthAttachment);
Array<PTexture2D> inputAttachments;
Array<PTexture2D> colorAttachments;
PTexture2D depthAttachment;
};
DEFINE_REF(RenderTargetLayout);
class RenderPass
{
};
DEFINE_REF(RenderPass);
}
}
GraphicsInitializer(const GraphicsInitializer &other)
: applicationName(other.applicationName), engineName(other.engineName), layers(other.layers), instanceExtensions(other.instanceExtensions), deviceExtensions(other.deviceExtensions)
{
}
};
struct WindowCreateInfo
{
int32 width;
int32 height;
const char *title;
bool bFullscreen;
Gfx::SeFormat pixelFormat;
void *windowHandle;
};
struct ViewportCreateInfo
{
uint32 sizeX;
uint32 sizeY;
uint32 offsetX;
uint32 offsetY;
bool bFullscreen;
bool bVsync;
};
struct TextureCreateInfo
{
uint32 width;
uint32 height;
uint32 depth;
bool bArray;
uint32 arrayLayers;
uint32 mipLevels;
uint32 samples;
Gfx::SeFormat format;
Gfx::SeImageUsageFlagBits usage;
Gfx::QueueType queueType;
TextureCreateInfo()
: width(1), height(1), depth(1), bArray(false), arrayLayers(1), mipLevels(1), samples(1), format(Gfx::SE_FORMAT_R32G32B32A32_SFLOAT), usage(Gfx::SE_IMAGE_USAGE_SAMPLED_BIT)
{
}
};
//doesnt own the data, only proxy it
struct BulkResourceData
{
uint32 size;
uint8 *data;
Gfx::QueueType owner;
};
namespace Gfx
{
struct SePushConstantRange
{
SeShaderStageFlags stageFlags;
uint32_t offset;
uint32_t size;
};
class RenderCommandBase
{
public:
virtual ~RenderCommandBase()
{
}
};
DEFINE_REF(RenderCommandBase);
class SamplerState
{
public:
virtual ~SamplerState()
{
}
};
DEFINE_REF(SamplerState);
class DescriptorBinding
{
public:
DescriptorBinding()
: binding(0), descriptorType(SE_DESCRIPTOR_TYPE_MAX_ENUM), descriptorCount(0x7fff), shaderStages(SE_SHADER_STAGE_ALL)
{
}
DescriptorBinding(const DescriptorBinding &other)
: binding(other.binding), descriptorType(other.descriptorType), descriptorCount(other.descriptorCount), shaderStages(other.shaderStages)
{
}
void operator=(const DescriptorBinding &other)
{
binding = other.binding;
descriptorType = other.descriptorType;
descriptorCount = other.descriptorCount;
shaderStages = other.shaderStages;
}
uint32_t binding;
SeDescriptorType descriptorType;
uint32_t descriptorCount;
SeShaderStageFlags shaderStages;
};
DEFINE_REF(DescriptorBinding);
DECLARE_REF(DescriptorSet);
class DescriptorAllocator
{
public:
DescriptorAllocator() {}
virtual ~DescriptorAllocator() {}
virtual void allocateDescriptorSet(PDescriptorSet &descriptorSet) = 0;
};
DEFINE_REF(DescriptorAllocator);
DECLARE_REF(UniformBuffer);
DECLARE_REF(StructuredBuffer);
DECLARE_REF(Texture);
class DescriptorSet
{
public:
virtual ~DescriptorSet() {}
virtual void writeChanges() = 0;
virtual void updateBuffer(uint32 binding, PUniformBuffer uniformBuffer) = 0;
virtual void updateBuffer(uint32 binding, PStructuredBuffer structuredBuffer) = 0;
virtual void updateSampler(uint32 binding, PSamplerState samplerState) = 0;
virtual void updateTexture(uint32 binding, PTexture texture, PSamplerState samplerState = nullptr) = 0;
virtual bool operator<(PDescriptorSet other) = 0;
};
DEFINE_REF(DescriptorSet);
class DescriptorLayout
{
public:
DescriptorLayout() {}
virtual ~DescriptorLayout() {}
void operator=(const DescriptorLayout &other)
{
descriptorBindings.resize(other.descriptorBindings.size());
std::memcpy(descriptorBindings.data(), other.descriptorBindings.data(), sizeof(DescriptorLayout) * descriptorBindings.size());
}
virtual void create() = 0;
virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1);
virtual PDescriptorSet allocatedDescriptorSet();
const Array<DescriptorBinding> &getBindings() const { return descriptorBindings; }
protected:
Array<DescriptorBinding> descriptorBindings;
PDescriptorAllocator allocator;
friend class PipelineLayout;
friend class DescriptorAllocator;
};
DEFINE_REF(DescriptorLayout);
class PipelineLayout
{
public:
PipelineLayout() {}
virtual ~PipelineLayout() {}
virtual void create() = 0;
void addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout);
void addPushConstants(const SePushConstantRange &pushConstants);
virtual uint32 getHash() const = 0;
protected:
Array<PDescriptorLayout> descriptorSetLayouts;
Array<SePushConstantRange> pushConstants;
};
DEFINE_REF(PipelineLayout);
class VertexDeclaration
{
public:
virtual ~VertexDeclaration()
{
}
};
DEFINE_REF(VertexDeclaration);
class GraphicsPipeline
{
public:
virtual ~GraphicsPipeline()
{
}
};
DEFINE_REF(GraphicsPipeline);
class UniformBuffer
{
public:
UniformBuffer();
virtual ~UniformBuffer();
};
DEFINE_REF(UniformBuffer);
class VertexBuffer
{
public:
virtual ~VertexBuffer()
{
}
};
DEFINE_REF(VertexBuffer);
class IndexBuffer
{
public:
virtual ~IndexBuffer()
{
}
};
DEFINE_REF(IndexBuffer);
class StructuredBuffer
{
public:
virtual ~StructuredBuffer()
{
}
};
DEFINE_REF(StructuredBuffer);
class Texture
{
public:
virtual ~Texture()
{
}
};
DEFINE_REF(Texture);
class Texture2D : public Texture
{
public:
virtual ~Texture2D()
{
}
};
DEFINE_REF(Texture2D);
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;
protected:
uint32 sizeX;
uint32 sizeY;
bool bFullscreen;
const char *title;
SeFormat pixelFormat;
};
DEFINE_REF(Window);
class Viewport
{
public:
Viewport(PWindow owner, const ViewportCreateInfo &createInfo);
virtual ~Viewport();
protected:
uint32 sizeX;
uint32 sizeY;
uint32 offsetX;
uint32 offsetY;
PWindow owner;
};
DEFINE_REF(Viewport);
class RenderTargetAttachment
{
public:
RenderTargetAttachment(PTexture2D texture,
SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD,
SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE,
SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE,
SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE)
: texture(texture), loadOp(loadOp), storeOp(storeOp), stencilLoadOp(stencilLoadOp), stencilStoreOp(stencilStoreOp)
{
}
virtual ~RenderTargetAttachment()
{
}
virtual PTexture2D getTexture()
{
return texture;
}
inline SeAttachmentLoadOp getLoadOp() const { return loadOp; }
inline SeAttachmentStoreOp getStoreOp() const { return storeOp; }
inline SeAttachmentLoadOp getStencilLoadOp() const { return stencilLoadOp; }
inline SeAttachmentStoreOp getStencilStoreOp() const { return stencilStoreOp; }
protected:
PTexture2D texture;
SeAttachmentLoadOp loadOp;
SeAttachmentStoreOp storeOp;
SeAttachmentLoadOp stencilLoadOp;
SeAttachmentStoreOp stencilStoreOp;
};
DEFINE_REF(RenderTargetAttachment);
class SwapchainAttachment : public RenderTargetAttachment
{
public:
SwapchainAttachment(PWindow owner,
SeAttachmentLoadOp loadOp = SE_ATTACHMENT_LOAD_OP_LOAD,
SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE,
SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE,
SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE)
: RenderTargetAttachment(owner->getBackBuffer(), loadOp, storeOp, stencilLoadOp, stencilStoreOp), owner(owner)
{
}
virtual PTexture2D getTexture() override
{
return owner->getBackBuffer();
}
private:
PWindow owner;
};
DEFINE_REF(SwapchainAttachment);
class RenderTargetLayout
{
public:
RenderTargetLayout();
RenderTargetLayout(PRenderTargetAttachment depthAttachment);
RenderTargetLayout(PRenderTargetAttachment colorAttachment, PRenderTargetAttachment depthAttachment);
RenderTargetLayout(Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachmet);
RenderTargetLayout(Array<PRenderTargetAttachment> inputAttachments, Array<PRenderTargetAttachment> colorAttachments, PRenderTargetAttachment depthAttachment);
Array<PRenderTargetAttachment> inputAttachments;
Array<PRenderTargetAttachment> colorAttachments;
PRenderTargetAttachment depthAttachment;
};
DEFINE_REF(RenderTargetLayout);
class RenderPass
{
public:
virtual ~RenderPass()
{
}
};
DEFINE_REF(RenderPass);
DEFINE_REF(RenderPass);
} // namespace Gfx
} // namespace Seele
+1 -1
View File
@@ -21,7 +21,7 @@ void Seele::RenderCore::init()
void Seele::RenderCore::renderLoop()
{
while(windowManager->isActive())
while (windowManager->isActive())
{
windowManager->beginFrame();
windowManager->endFrame();
+13 -12
View File
@@ -2,15 +2,16 @@
#include "WindowManager.h"
namespace Seele
{
class RenderCore
{
public:
RenderCore();
~RenderCore();
void init();
void renderLoop();
void shutdown();
private:
PWindowManager windowManager;
};
}
class RenderCore
{
public:
RenderCore();
~RenderCore();
void init();
void renderLoop();
void shutdown();
private:
PWindowManager windowManager;
};
} // namespace Seele
+18 -17
View File
@@ -2,20 +2,21 @@
#include "Graphics.h"
namespace Seele
{
//A renderpath is a general Renderer for a view.
class RenderPath
{
public:
RenderPath(Gfx::PGraphics graphics);
virtual ~RenderPath();
virtual void applyArea(Rect area) = 0;
virtual void init() = 0;
virtual void beginFrame() = 0;
virtual void render() = 0;
virtual void endFrame() = 0;
protected:
Gfx::PGraphics graphics;
Rect area;
};
DEFINE_REF(RenderPath);
}
//A renderpath is a general Renderer for a view.
class RenderPath
{
public:
RenderPath(Gfx::PGraphics graphics);
virtual ~RenderPath();
virtual void applyArea(Rect area) = 0;
virtual void init() = 0;
virtual void beginFrame() = 0;
virtual void render() = 0;
virtual void endFrame() = 0;
protected:
Gfx::PGraphics graphics;
Rect area;
};
DEFINE_REF(RenderPath);
} // namespace Seele
+2 -1
View File
@@ -9,8 +9,9 @@ Seele::SceneRenderPath::~SceneRenderPath()
{
}
void Seele::SceneRenderPath::applyArea(Rect area)
void Seele::SceneRenderPath::applyArea(Rect newArea)
{
area = newArea;
}
void Seele::SceneRenderPath::init()
+12 -12
View File
@@ -3,15 +3,15 @@
namespace Seele
{
class SceneRenderPath : public RenderPath
{
public:
SceneRenderPath(Gfx::PGraphics graphics);
virtual ~SceneRenderPath();
virtual void applyArea(Rect area) override;
virtual void init() override;
virtual void beginFrame() override;
virtual void render() override;
virtual void endFrame() override;
};
}
class SceneRenderPath : public RenderPath
{
public:
SceneRenderPath(Gfx::PGraphics graphics);
virtual ~SceneRenderPath();
virtual void applyArea(Rect area) override;
virtual void init() override;
virtual void beginFrame() override;
virtual void render() override;
virtual void endFrame() override;
};
} // namespace Seele
+7 -7
View File
@@ -2,10 +2,10 @@
#include "View.h"
namespace Seele
{
class SceneView : public View
{
public:
SceneView(Gfx::PGraphics graphics);
~SceneView();
};
}
class SceneView : public View
{
public:
SceneView(Gfx::PGraphics graphics);
~SceneView();
};
} // namespace Seele
+16 -15
View File
@@ -2,19 +2,20 @@
#include "RenderPath.h"
namespace Seele
{
// A view is a part of the window, which can be anything from a viewport to an editor
class View
{
public:
View(Gfx::PGraphics graphics);
virtual ~View();
void beginFrame();
void endFrame();
void applyArea(Rect area);
protected:
Gfx::PGraphics graphics;
PRenderPath renderer;
};
// A view is a part of the window, which can be anything from a viewport to an editor
class View
{
public:
View(Gfx::PGraphics graphics);
virtual ~View();
void beginFrame();
void endFrame();
void applyArea(Rect area);
DEFINE_REF(View)
}
protected:
Gfx::PGraphics graphics;
PRenderPath renderer;
};
DEFINE_REF(View)
} // namespace Seele
+2 -1
View File
@@ -20,4 +20,5 @@ target_sources(SeeleEngine
VulkanRenderPass.cpp
VulkanTexture.cpp
VulkanQueue.h
VulkanQueue.cpp)
VulkanQueue.cpp
VulkanViewport.cpp)
+230 -24
View File
@@ -5,7 +5,7 @@
using namespace Seele::Vulkan;
SubAllocation::SubAllocation(Allocation* owner, uint32 allocatedOffset, uint32 size, uint32 alignedOffset, uint32 allocatedSize)
SubAllocation::SubAllocation(Allocation* owner, VkDeviceSize allocatedOffset, VkDeviceSize size, VkDeviceSize alignedOffset, VkDeviceSize allocatedSize)
: owner(owner)
, size(size)
, allocatedOffset(allocatedOffset)
@@ -14,11 +14,43 @@ SubAllocation::SubAllocation(Allocation* owner, uint32 allocatedOffset, uint32 s
{
}
Allocation::Allocation(PGraphics graphics, Allocator* allocator, uint32 size, uint32 memoryTypeIndex, VkMemoryPropertyFlags properties, bool isDedicated)
SubAllocation::~SubAllocation()
{
owner->markFree(this);
}
VkDeviceMemory SubAllocation::getHandle() const
{
return owner->getHandle();
}
bool SubAllocation::isReadable() const
{
return owner->isReadable();
}
void* SubAllocation::getMappedPointer()
{
return (uint8*)owner->getMappedPointer() + alignedOffset;
}
void SubAllocation::flushMemory()
{
owner->flushMemory();
}
void SubAllocation::invalidateMemory()
{
owner->invalidateMemory();
}
Allocation::Allocation(PGraphics graphics, Allocator* allocator, VkDeviceSize size, uint8 memoryTypeIndex,
VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo* dedicatedInfo)
: device(graphics->getDevice())
, allocator(allocator)
, bytesAllocated(0)
, bytesUsed(0)
, readable(properties & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
, properties(properties)
, memoryTypeIndex(memoryTypeIndex)
{
@@ -26,38 +58,52 @@ Allocation::Allocation(PGraphics graphics, Allocator* allocator, uint32 size, ui
init::MemoryAllocateInfo();
allocInfo.allocationSize = size;
allocInfo.memoryTypeIndex = memoryTypeIndex;
isDedicated = dedicatedInfo != nullptr;
allocInfo.pNext = dedicatedInfo;
VK_CHECK(vkAllocateMemory(device, &allocInfo, nullptr, &allocatedMemory));
bytesAllocated = size;
PSubAllocation freeRange = new SubAllocation(this, 0, size, 0, size);
freeRanges.add(freeRange);
freeRanges[0] = freeRange;
canMap = (properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
isMapped = false;
}
PSubAllocation Allocation::getSuballocation(uint32 requestedSize, uint32 alignment)
Allocation::~Allocation()
{
allocator->free(this);
}
PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDeviceSize alignment)
{
if (isDedicated)
{
if (activeAllocations.size() == 0)
if (activeAllocations.empty())
{
assert(requestedSize == bytesAllocated);
activeAllocations.add(freeRanges.back());
PSubAllocation suballoc = freeRanges[0];
activeAllocations[0] = suballoc.getHandle();
freeRanges.clear();
bytesUsed += requestedSize;
return suballoc;
}
else
{
return nullptr;
}
}
for (int i = 0; i < freeRanges.size(); ++i)
for (uint32 i = 0; i < freeRanges.size(); ++i)
{
PSubAllocation freeAllocation = freeRanges[i];
uint32 allocatedOffset = freeAllocation->allocatedOffset;
uint32 alignedOffset = align(allocatedOffset, alignment);
uint32 alignmentAdjustment = alignedOffset - allocatedOffset;
uint32 size = alignmentAdjustment + requestedSize;
VkDeviceSize allocatedOffset = freeAllocation->allocatedOffset;
VkDeviceSize alignedOffset = align(allocatedOffset, alignment);
VkDeviceSize alignmentAdjustment = alignedOffset - allocatedOffset;
VkDeviceSize size = alignmentAdjustment + requestedSize;
if (freeAllocation->size == size)
{
freeRanges.remove(i);
activeAllocations.add(freeAllocation);
freeRanges.erase(allocatedOffset);
activeAllocations[allocatedOffset] = freeAllocation.getHandle();
bytesUsed += size;
return freeAllocation;
}
else if (size < freeAllocation->allocatedSize)
@@ -67,19 +113,61 @@ PSubAllocation Allocation::getSuballocation(uint32 requestedSize, uint32 alignme
freeAllocation->allocatedOffset += allocatedOffset;
freeAllocation->alignedOffset += allocatedOffset;
PSubAllocation subAlloc = new SubAllocation(this, allocatedOffset, size, alignedOffset, size);
activeAllocations.add(subAlloc);
activeAllocations[allocatedOffset] = subAlloc.getHandle();
freeRanges.erase(allocatedOffset);
freeRanges[freeAllocation->allocatedOffset] = freeAllocation;
bytesUsed += size;
return subAlloc;
}
}
return nullptr;
}
void Allocation::markFree(SubAllocation* allocation)
{
VkDeviceSize lowerBound = allocation->allocatedOffset;
VkDeviceSize upperBound = allocation->allocatedOffset + allocation->allocatedSize;
PSubAllocation allocHandle;
for(auto freeRange : freeRanges)
{
PSubAllocation freeAlloc = freeRange.value;
if(freeAlloc->allocatedOffset + freeAlloc->allocatedSize + 1 == lowerBound)
{
freeAlloc->allocatedSize += allocation->allocatedSize;
allocHandle = freeAlloc;
break;
}
}
auto foundAlloc = freeRanges.find(upperBound + 1);
if(foundAlloc != freeRanges.end())
{
if(allocHandle == nullptr)
{
allocHandle->allocatedSize += foundAlloc->value->allocatedSize;
freeRanges.erase(foundAlloc->key);
}
else
{
allocHandle = foundAlloc->value;
allocHandle->allocatedOffset -= allocation->allocatedSize;
allocHandle->alignedOffset -= allocation->allocatedSize;
}
}
if(allocHandle == nullptr)
{
allocHandle = new SubAllocation(this, allocation->alignedOffset, allocation->size, allocation->alignedOffset, allocation->allocatedSize);
freeRanges[allocation->allocatedOffset] = allocHandle;
}
activeAllocations.erase(allocation->allocatedOffset);
bytesUsed -= allocation->allocatedSize;
}
Allocator::Allocator(PGraphics graphics)
: graphics(graphics)
{
vkGetPhysicalDeviceMemoryProperties(graphics->getPhysicalDevice(), &memProperties);
heaps.resize(memProperties.memoryHeapCount);
for (size_t i = 0; i < memProperties.memoryHeapCount; i++)
for (size_t i = 0; i < memProperties.memoryHeapCount; ++i)
{
VkMemoryHeap memoryHeap = memProperties.memoryHeaps[i];
HeapInfo& heapInfo = heaps[i];
@@ -89,25 +177,68 @@ Allocator::Allocator(PGraphics graphics)
Allocator::~Allocator()
{
for(auto heap : heaps)
{
for(auto alloc : heap.allocations)
{
assert(alloc->activeAllocations.empty());
assert(alloc->freeRanges.size() == 1);
}
heap.allocations.clear();
}
graphics = nullptr;
}
PSubAllocation Allocator::allocate(uint64 size, const VkMemoryRequirements2& memRequirements2, VkMemoryPropertyFlags properties)
PSubAllocation Allocator::allocate(const VkMemoryRequirements2& memRequirements2, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo* dedicatedInfo)
{
// no suitable allocations found, allocate new block
const VkMemoryRequirements& requirements = memRequirements2.memoryRequirements;
uint32 memoryTypeIndex;
uint8 memoryTypeIndex;
VK_CHECK(findMemoryType(requirements.memoryTypeBits, properties, &memoryTypeIndex));
bool isDedicated = memRequirements2.pNext != nullptr;
PAllocation newAllocation = new Allocation(graphics, this, MemoryBlockSize, memoryTypeIndex, properties, isDedicated);
uint32 heapIndex = memProperties.memoryTypes[memoryTypeIndex].heapIndex;
if(memRequirements2.pNext != nullptr)
{
VkMemoryDedicatedRequirements* dedicatedReq = (VkMemoryDedicatedRequirements*)memRequirements2.pNext;
if(dedicatedReq->prefersDedicatedAllocation)
{
PAllocation newAllocation = new Allocation(graphics, this, requirements.size, memoryTypeIndex, properties, dedicatedInfo);
heaps[heapIndex].allocations.add(newAllocation);
return newAllocation->getSuballocation(requirements.size, requirements.alignment);
}
}
for(auto alloc : heaps[heapIndex].allocations)
{
PSubAllocation suballoc = alloc->getSuballocation(requirements.size, requirements.alignment);
if(suballoc != nullptr)
{
return suballoc;
}
}
// no suitable allocations found, allocate new block
PAllocation newAllocation = new Allocation(graphics, this, (requirements.size > MemoryBlockSize) ? requirements.size : MemoryBlockSize, memoryTypeIndex, properties, nullptr);
heaps[heapIndex].allocations.add(newAllocation);
return newAllocation->getSuballocation(size, requirements.alignment);
return newAllocation->getSuballocation(requirements.size, requirements.alignment);
}
VkResult Allocator::findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties, uint32* typeIndex)
void Allocator::free(Allocation* allocation)
{
for (int memoryIndex = 0; memoryIndex < memProperties.memoryTypeCount && typeBits; ++memoryIndex)
for(auto heap : heaps)
{
for(uint32 i = 0; i < heap.allocations.size(); ++i)
{
if(heap.allocations[i] == allocation)
{
heap.allocations.remove(i, false);
return;
}
}
}
}
VkResult Allocator::findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties, uint8* typeIndex)
{
for (uint8 memoryIndex = 0; memoryIndex < memProperties.memoryTypeCount && typeBits; ++memoryIndex)
{
if ((typeBits & 1) == 1)
{
@@ -121,4 +252,79 @@ VkResult Allocator::findMemoryType(uint32 typeBits, VkMemoryPropertyFlags proper
}
return VK_ERROR_FORMAT_NOT_SUPPORTED;
}
StagingBuffer::StagingBuffer()
{
}
StagingBuffer::~StagingBuffer()
{
}
StagingManager::StagingManager(PGraphics graphics, PAllocator allocator)
: graphics(graphics)
, allocator(allocator)
{
}
StagingManager::~StagingManager()
{
}
void StagingManager::clearPending()
{
}
PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageFlags usage, bool bCPURead)
{
for(auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it)
{
auto freeBuffer = *it;
if(freeBuffer->allocation->getSize() == size && freeBuffer->allocation->isReadable() == bCPURead)
{
activeBuffers.add(freeBuffer.getHandle());
freeBuffers.remove(it, false);
return freeBuffer;
}
}
PStagingBuffer stagingBuffer = new StagingBuffer();
VkBufferCreateInfo stagingBufferCreateInfo = init::BufferCreateInfo(usage, size);
VkDevice vulkanDevice = graphics->getDevice();
VK_CHECK(vkCreateBuffer(vulkanDevice, &stagingBufferCreateInfo, nullptr, &stagingBuffer->buffer));
VkMemoryDedicatedRequirements dedicatedReqs;
dedicatedReqs.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
dedicatedReqs.pNext = nullptr;
VkMemoryRequirements2 memReqs;
memReqs.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
memReqs.pNext = &dedicatedReqs;
VkBufferMemoryRequirementsInfo2 bufferQuery;
bufferQuery.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2;
bufferQuery.pNext = nullptr;
bufferQuery.buffer = stagingBuffer->buffer;
vkGetBufferMemoryRequirements2(vulkanDevice, &bufferQuery, &memReqs);
memReqs.memoryRequirements.alignment =
(16 > memReqs.memoryRequirements.alignment) ?
16 : memReqs.memoryRequirements.alignment;
stagingBuffer->allocation = allocator->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | (bCPURead ? VK_MEMORY_PROPERTY_HOST_CACHED_BIT : VK_MEMORY_PROPERTY_HOST_COHERENT_BIT), stagingBuffer->buffer);
stagingBuffer->bReadable = bCPURead;
vkBindBufferMemory(graphics->getDevice(), stagingBuffer->buffer, stagingBuffer->getMemoryHandle(), stagingBuffer->getOffset());
activeBuffers.add(stagingBuffer.getHandle());
return stagingBuffer;
}
void StagingManager::releaseStagingBuffer(PStagingBuffer buffer)
{
freeBuffers.add(buffer);
activeBuffers.remove(activeBuffers.find(buffer.getHandle()));
}
+206 -64
View File
@@ -6,69 +6,211 @@
namespace Seele
{
namespace Vulkan
namespace Vulkan
{
DECLARE_REF(Graphics);
class Allocation;
class Allocator;
class SubAllocation
{
public:
SubAllocation(Allocation *owner, VkDeviceSize allocatedOffset, VkDeviceSize size, VkDeviceSize alignedOffset, VkDeviceSize allocatedSize);
~SubAllocation();
VkDeviceMemory getHandle() const;
inline VkDeviceSize getSize() const
{
DECLARE_REF(Graphics);
class Allocation;
class Allocator;
class SubAllocation
{
public:
SubAllocation(Allocation* owner, uint32 allocatedOffset, uint32 size, uint32 alignedOffset, uint32 allocatedSize);
private:
Allocation* owner;
uint32 allocatedOffset;
uint32 size;
uint32 alignedOffset;
uint32 allocatedSize;
friend class Allocation;
friend class Allocator;
};
DEFINE_REF(SubAllocation);
class Allocation
{
public:
Allocation(PGraphics graphics, Allocator* allocator, uint32 size, uint32 memoryTypeIndex, VkMemoryPropertyFlags properties, bool isDedicated);
PSubAllocation getSuballocation(uint32 size, uint32 alignment);
private:
Allocator* allocator;
VkDevice device;
VkDeviceMemory allocatedMemory;
VkDeviceSize bytesAllocated;
VkDeviceSize bytesUsed;
VkMemoryPropertyFlags properties;
Array<PSubAllocation> activeAllocations;
Array<PSubAllocation> freeRanges;
void* mappedPointer;
uint8 isDedicated : 1;
uint8 canMap : 1;
uint8 memoryTypeIndex;
friend class Allocator;
};
DEFINE_REF(Allocation);
class Allocator
{
public:
Allocator(PGraphics graphics);
~Allocator();
PSubAllocation allocate(uint64 size, const VkMemoryRequirements2& requirements, VkMemoryPropertyFlags props);
private:
enum
{
MemoryBlockSize = 64 * 1024 * 1024 // 64MB
};
struct HeapInfo
{
uint32 maxSize = 0;
Array<PAllocation> allocations;
};
Array<HeapInfo> heaps;
VkResult findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties, uint32* typeIndex);
PGraphics graphics;
VkPhysicalDeviceMemoryProperties memProperties;
};
DEFINE_REF(Allocator);
return size;
}
}
inline VkDeviceSize getOffset() const
{
return alignedOffset;
}
inline bool isReadable() const;
void *getMappedPointer();
void flushMemory();
void invalidateMemory();
private:
Allocation *owner;
VkDeviceSize allocatedOffset;
VkDeviceSize size;
VkDeviceSize alignedOffset;
VkDeviceSize allocatedSize;
friend class Allocation;
friend class Allocator;
};
DEFINE_REF(SubAllocation);
class Allocation
{
public:
Allocation(PGraphics graphics, Allocator *allocator, VkDeviceSize size, uint8 memoryTypeIndex,
VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo = nullptr);
~Allocation();
PSubAllocation getSuballocation(VkDeviceSize size, VkDeviceSize alignment);
void markFree(SubAllocation *alloc);
inline VkDeviceMemory getHandle() const
{
return allocatedMemory;
}
inline void *getMappedPointer()
{
if (!canMap)
{
return nullptr;
}
if (!isMapped)
{
vkMapMemory(device, allocatedMemory, 0, bytesAllocated, 0, &mappedPointer);
isMapped = true;
}
return mappedPointer;
}
inline bool isReadable() const
{
return readable;
}
void flushMemory()
{
VkMappedMemoryRange range;
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
range.pNext = 0;
range.memory = allocatedMemory;
range.size = bytesAllocated;
range.offset = 0;
vkFlushMappedMemoryRanges(device, 1, &range);
}
void invalidateMemory()
{
VkMappedMemoryRange range;
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
range.pNext = 0;
range.memory = allocatedMemory;
range.size = bytesAllocated;
vkInvalidateMappedMemoryRanges(device, 1, &range);
}
private:
Allocator *allocator;
VkDevice device;
VkDeviceMemory allocatedMemory;
VkDeviceSize bytesAllocated;
VkDeviceSize bytesUsed;
VkMemoryPropertyFlags properties;
Map<VkDeviceSize, SubAllocation *> activeAllocations;
Map<VkDeviceSize, PSubAllocation> freeRanges;
void *mappedPointer;
uint8 memoryTypeIndex;
uint8 isDedicated : 1;
uint8 canMap : 1;
uint8 isMapped : 1;
uint8 readable : 1;
friend class Allocator;
};
DEFINE_REF(Allocation);
class Allocator
{
public:
Allocator(PGraphics graphics);
~Allocator();
PSubAllocation allocate(const VkMemoryRequirements2 &requirements, VkMemoryPropertyFlags props,
VkMemoryDedicatedAllocateInfo *dedicatedInfo = nullptr);
inline PSubAllocation allocate(const VkMemoryRequirements2 &requirements, VkMemoryPropertyFlags props,
VkBuffer buffer)
{
VkMemoryDedicatedAllocateInfo allocInfo;
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
allocInfo.pNext = nullptr;
allocInfo.buffer = buffer;
allocInfo.image = VK_NULL_HANDLE;
return allocate(requirements, props, &allocInfo);
}
inline PSubAllocation allocate(const VkMemoryRequirements2 &requirements, VkMemoryPropertyFlags props,
VkImage image)
{
VkMemoryDedicatedAllocateInfo allocInfo;
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
allocInfo.pNext = nullptr;
allocInfo.buffer = VK_NULL_HANDLE;
allocInfo.image = image;
return allocate(requirements, props, &allocInfo);
}
void free(Allocation *allocation);
private:
enum
{
MemoryBlockSize = 64 * 1024 * 1024 // 64MB
};
struct HeapInfo
{
VkDeviceSize maxSize = 0;
Array<PAllocation> allocations;
};
Array<HeapInfo> heaps;
VkResult findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties, uint8 *typeIndex);
PGraphics graphics;
VkPhysicalDeviceMemoryProperties memProperties;
};
DEFINE_REF(Allocator);
class StagingBuffer
{
public:
StagingBuffer();
~StagingBuffer();
void *getMappedPointer()
{
return allocation->getMappedPointer();
}
void flushMappedMemory()
{
allocation->flushMemory();
}
void invalidateMemory()
{
allocation->invalidateMemory();
}
VkBuffer getHandle() const
{
return buffer;
}
VkDeviceMemory getMemoryHandle() const
{
return allocation->getHandle();
}
VkDeviceSize getOffset() const
{
return allocation->getOffset();
}
private:
PSubAllocation allocation;
VkBuffer buffer;
uint8 bReadable;
friend class StagingManager;
};
DEFINE_REF(StagingBuffer);
class StagingManager
{
public:
StagingManager(PGraphics graphics, PAllocator allocator);
~StagingManager();
PStagingBuffer allocateStagingBuffer(uint32 size, VkBufferUsageFlags usageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, bool bCPURead = false);
void releaseStagingBuffer(PStagingBuffer buffer);
void clearPending();
private:
PGraphics graphics;
PAllocator allocator;
Array<PStagingBuffer> freeBuffers;
Array<StagingBuffer *> activeBuffers;
};
DEFINE_REF(StagingManager);
} // namespace Vulkan
} // namespace Seele
+311 -10
View File
@@ -1,28 +1,329 @@
#include "VulkanGraphicsResources.h"
#include "VulkanInitializer.h"
#include "VulkanGraphics.h"
#include "VulkanCommandBuffer.h"
#include "VulkanAllocator.h"
using namespace Seele;
using namespace Seele::Vulkan;
QueueOwnedResource::QueueOwnedResource(PGraphics graphics, QueueType startQueueType)
: graphics(graphics)
, currentOwner(startQueueType)
struct PendingBuffer
{
}
PStagingBuffer stagingBuffer;
Gfx::QueueType prevQueue;
bool bWriteOnly;
};
QueueOwnedResource::~QueueOwnedResource()
{
}
static Map<Buffer *, PendingBuffer> pendingBuffers;
Buffer::Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, QueueType queueType)
: QueueOwnedResource(graphics, queueType)
Buffer::Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType)
: QueueOwnedResource(graphics, queueType), currentBuffer(0), size(size)
{
if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ||
usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT ||
usage & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT ||
usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)
{
numBuffers = 1;
}
else
{
numBuffers = Gfx::numFramesBuffered;
}
usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
VkBufferCreateInfo info =
init::BufferCreateInfo(
usage,
size);
VkBufferMemoryRequirementsInfo2 bufferReqInfo;
bufferReqInfo.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2;
bufferReqInfo.pNext = nullptr;
VkMemoryDedicatedRequirements dedicatedRequirements;
dedicatedRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
dedicatedRequirements.pNext = nullptr;
VkMemoryRequirements2 memRequirements;
memRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
memRequirements.pNext = &dedicatedRequirements;
for (uint32 i = 0; i < numBuffers; ++i)
{
vkCreateBuffer(graphics->getDevice(), &info, nullptr, &buffers[i].buffer);
bufferReqInfo.buffer = buffers[i].buffer;
vkGetBufferMemoryRequirements2(graphics->getDevice(), &bufferReqInfo, &memRequirements);
buffers[i].allocation = graphics->getAllocator()->allocate(memRequirements, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, buffers[i].buffer);
vkBindBufferMemory(graphics->getDevice(), buffers[i].buffer, buffers[i].allocation->getHandle(), buffers[i].allocation->getOffset());
}
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
}
Buffer::~Buffer()
{
for (uint32 i = 0; i < numBuffers; ++i)
{
vkDestroyBuffer(graphics->getDevice(), buffers[i].buffer, nullptr);
buffers[i].allocation = nullptr;
}
}
void Buffer::executeOwnershipBarrier(QueueType newOwner)
void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
VkBufferMemoryBarrier barrier =
init::BufferMemoryBarrier();
PCommandBufferManager sourceManager = getCommands();
PCommandBufferManager dstManager = nullptr;
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
QueueFamilyMapping mapping = graphics->getFamilyMapping();
barrier.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(currentOwner);
barrier.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner);
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
if (currentOwner == Gfx::QueueType::TRANSFER || currentOwner == Gfx::QueueType::DEDICATED_TRANSFER)
{
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
}
else if (currentOwner == Gfx::QueueType::COMPUTE)
{
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
}
else if (currentOwner == Gfx::QueueType::GRAPHICS)
{
barrier.srcAccessMask = getSourceAccessMask();
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
}
if (newOwner == Gfx::QueueType::TRANSFER)
{
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstManager = graphics->getTransferCommands();
}
else if (newOwner == Gfx::QueueType::DEDICATED_TRANSFER)
{
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstManager = graphics->getDedicatedTransferCommands();
}
else if (newOwner == Gfx::QueueType::COMPUTE)
{
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
dstManager = graphics->getComputeCommands();
}
else if (newOwner == Gfx::QueueType::GRAPHICS)
{
barrier.dstAccessMask = getDestAccessMask();
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
dstManager = graphics->getGraphicsCommands();
}
VkCommandBuffer srcCommand = sourceManager->getCommands()->getHandle();
VkCommandBuffer dstCommand = dstManager->getCommands()->getHandle();
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
for (uint32_t i = 0; i < numBuffers; ++i)
{
dynamicBarriers[i] = barrier;
dynamicBarriers[i].buffer = buffers[i].buffer;
dynamicBarriers[i].offset = 0;
dynamicBarriers[i].size = buffers[i].allocation->getSize();
}
vkCmdPipelineBarrier(srcCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
vkCmdPipelineBarrier(dstCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
sourceManager->submitCommands();
cachedCmdBufferManager = dstManager;
}
void *Buffer::lock(bool bWriteOnly)
{
void *data = nullptr;
/*if (bVolatile)
{
if (lockMode == RLM_ReadOnly)
{
assert(0);
}
else
{
throw new std::logic_error("TODO implement volatile buffers");
//device->getRHIDevice()->getTemp
}
}*/
//assert(bStatic || bDynamic || bUAV);
PendingBuffer pending;
pending.bWriteOnly = bWriteOnly;
pending.prevQueue = currentOwner;
if (bWriteOnly)
{
transferOwnership(Gfx::QueueType::DEDICATED_TRANSFER);
PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
data = stagingBuffer->getMappedPointer();
pending.stagingBuffer = stagingBuffer;
}
else
{
PCmdBuffer current = getCommands()->getCommands();
getCommands()->submitCommands();
getCommands()->waitForCommands(current);
transferOwnership(Gfx::QueueType::DEDICATED_TRANSFER);
VkCommandBuffer handle = getCommands()->getCommands()->getHandle();
VkBufferMemoryBarrier barrier =
init::BufferMemoryBarrier();
barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
barrier.buffer = buffers[currentBuffer].buffer;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.offset = 0;
barrier.size = size;
vkCmdPipelineBarrier(handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr);
PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true);
VkBufferCopy regions;
regions.size = size;
regions.srcOffset = 0;
regions.dstOffset = 0;
vkCmdCopyBuffer(handle, buffers[currentBuffer].buffer, stagingBuffer->getHandle(), 1, &regions);
getCommands()->submitCommands();
vkQueueWaitIdle(getCommands()->getQueue()->getHandle());
stagingBuffer->flushMappedMemory();
pending.stagingBuffer = stagingBuffer;
data = stagingBuffer->getMappedPointer();
}
pendingBuffers[this] = pending;
assert(data);
return data;
}
void Buffer::unlock()
{
auto found = pendingBuffers.find(this);
if (found != pendingBuffers.end())
{
PendingBuffer pending = found->value;
pending.stagingBuffer->flushMappedMemory();
pendingBuffers.erase(this);
if (pending.bWriteOnly)
{
PStagingBuffer stagingBuffer = pending.stagingBuffer;
PCmdBuffer cmdBuffer = getCommands()->getCommands();
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
VkBufferCopy region;
std::memset(&region, 0, sizeof(VkBufferCopy));
region.size = size;
vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, &region);
graphics->getStagingManager()->releaseStagingBuffer(stagingBuffer);
}
transferOwnership(pending.prevQueue);
}
}
UniformBuffer::UniformBuffer(PGraphics graphics, const BulkResourceData &resourceData)
: Buffer(graphics, resourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, resourceData.owner)
{
if (resourceData.data != nullptr)
{
void *data = lock();
std::memcpy(data, resourceData.data, resourceData.size);
unlock();
}
}
UniformBuffer::~UniformBuffer()
{
}
VkAccessFlags UniformBuffer::getSourceAccessMask()
{
return VK_ACCESS_MEMORY_WRITE_BIT;
}
VkAccessFlags UniformBuffer::getDestAccessMask()
{
return VK_ACCESS_UNIFORM_READ_BIT;
}
StructuredBuffer::StructuredBuffer(PGraphics graphics, const BulkResourceData &resourceData)
: Buffer(graphics, resourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, resourceData.owner)
{
if (resourceData.data != nullptr)
{
void *data = lock();
std::memcpy(data, resourceData.data, resourceData.size);
unlock();
}
}
StructuredBuffer::~StructuredBuffer()
{
}
VkAccessFlags StructuredBuffer::getSourceAccessMask()
{
return VK_ACCESS_MEMORY_WRITE_BIT;
}
VkAccessFlags StructuredBuffer::getDestAccessMask()
{
return VK_ACCESS_MEMORY_READ_BIT;
}
VertexBuffer::VertexBuffer(PGraphics graphics, const BulkResourceData &resourceData)
: Buffer(graphics, resourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, resourceData.owner)
{
if (resourceData.data != nullptr)
{
void *data = lock();
std::memcpy(data, resourceData.data, resourceData.size);
unlock();
}
}
VertexBuffer::~VertexBuffer()
{
}
VkAccessFlags VertexBuffer::getSourceAccessMask()
{
return VK_ACCESS_MEMORY_WRITE_BIT;
}
VkAccessFlags VertexBuffer::getDestAccessMask()
{
return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
}
IndexBuffer::IndexBuffer(PGraphics graphics, const BulkResourceData &resourceData)
: Buffer(graphics, resourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, resourceData.owner)
{
if (resourceData.data != nullptr)
{
void *data = lock();
std::memcpy(data, resourceData.data, resourceData.size);
unlock();
}
}
IndexBuffer::~IndexBuffer()
{
}
VkAccessFlags IndexBuffer::getSourceAccessMask()
{
return VK_ACCESS_MEMORY_WRITE_BIT;
}
VkAccessFlags IndexBuffer::getDestAccessMask()
{
return VK_ACCESS_INDEX_READ_BIT;
}
@@ -9,34 +9,34 @@ using namespace Seele;
using namespace Seele::Vulkan;
CmdBufferBase::CmdBufferBase(PGraphics graphics, VkCommandPool cmdPool)
: graphics(graphics)
, owner(cmdPool)
: graphics(graphics), owner(cmdPool)
{
}
CmdBufferBase::~CmdBufferBase()
{
graphics = nullptr;
}
CmdBuffer::CmdBuffer(PGraphics graphics, VkCommandPool cmdPool)
: CmdBufferBase(graphics, cmdPool)
, renderPass(nullptr)
, framebuffer(nullptr)
, subpassIndex(0)
: CmdBufferBase(graphics, cmdPool), renderPass(nullptr), framebuffer(nullptr), subpassIndex(0)
{
VkCommandBufferAllocateInfo allocInfo =
init::CommandBufferAllocateInfo(cmdPool,
VK_COMMAND_BUFFER_LEVEL_PRIMARY,
1);
VK_COMMAND_BUFFER_LEVEL_PRIMARY,
1);
VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle))
fence = new Fence(graphics);
state = State::ReadyBegin;
}
CmdBuffer::~CmdBuffer()
{
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
renderPass = nullptr;
framebuffer = nullptr;
waitSemaphores.clear();
}
void CmdBuffer::begin()
@@ -54,8 +54,11 @@ void CmdBuffer::end()
state = State::Ended;
}
void CmdBuffer::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer)
void CmdBuffer::beginRenderPass(PRenderPass newRenderPass, PFramebuffer newFramebuffer)
{
renderPass = newRenderPass;
framebuffer = newFramebuffer;
VkRenderPassBeginInfo beginInfo =
init::RenderPassBeginInfo();
beginInfo.clearValueCount = renderPass->getClearValueCount();
@@ -64,11 +67,49 @@ void CmdBuffer::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer
beginInfo.renderPass = renderPass->getHandle();
beginInfo.framebuffer = framebuffer->getHandle();
vkCmdBeginRenderPass(handle, &beginInfo, renderPass->getSubpassContents());
state = State::RenderPassActive;
}
void CmdBuffer::endRenderPass()
{
vkCmdEndRenderPass(handle);
state = State::InsideBegin;
}
void CmdBuffer::executeCommands(Array<PSecondaryCmdBuffer> commands)
{
assert(state == State::RenderPassActive);
Array<VkCommandBuffer> cmdBuffers(commands.size());
for (uint32 i = 0; i < commands.size(); ++i)
{
cmdBuffers[i] = commands[i]->getHandle();
}
vkCmdExecuteCommands(handle, cmdBuffers.size(), cmdBuffers.data());
}
void CmdBuffer::addWaitSemaphore(VkPipelineStageFlags flags, PSemaphore semaphore)
{
waitSemaphores.add(semaphore);
waitFlags.add(flags);
}
void CmdBuffer::refreshFence()
{
if (state == State::Submitted)
{
if (fence->isSignaled())
{
state = State::ReadyBegin;
vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
fence->reset();
}
}
else
{
assert(!fence->isSignaled());
}
}
SecondaryCmdBuffer::SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool)
@@ -76,8 +117,8 @@ SecondaryCmdBuffer::SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool
{
VkCommandBufferAllocateInfo allocInfo =
init::CommandBufferAllocateInfo(cmdPool,
VK_COMMAND_BUFFER_LEVEL_SECONDARY,
1);
VK_COMMAND_BUFFER_LEVEL_SECONDARY,
1);
VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle));
}
@@ -105,8 +146,7 @@ void SecondaryCmdBuffer::end()
}
CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue)
: graphics(graphics)
, queue(queue)
: graphics(graphics), queue(queue)
{
VkCommandPoolCreateInfo info =
init::CommandPoolCreateInfo();
@@ -117,11 +157,14 @@ CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue)
activeCmdBuffer = new CmdBuffer(graphics, commandPool);
activeCmdBuffer->begin();
allocatedBuffers.add(activeCmdBuffer);
}
CommandBufferManager::~CommandBufferManager()
{
vkDestroyCommandPool(graphics->getDevice(), commandPool, nullptr);
graphics = nullptr;
queue = nullptr;
}
PCmdBuffer CommandBufferManager::getCommands()
@@ -136,16 +179,15 @@ PSecondaryCmdBuffer CommandBufferManager::createSecondaryCmdBuffer()
void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
{
if(activeCmdBuffer->state == CmdBuffer::State::InsideBegin
|| activeCmdBuffer->state == CmdBuffer::State::RenderPassActive)
if (activeCmdBuffer->state == CmdBuffer::State::InsideBegin || activeCmdBuffer->state == CmdBuffer::State::RenderPassActive)
{
if(!activeCmdBuffer->state == CmdBuffer::State::RenderPassActive)
if (activeCmdBuffer->state == CmdBuffer::State::RenderPassActive)
{
std::cout << "End of renderpass forced" << std::endl;
activeCmdBuffer->endRenderPass();
}
activeCmdBuffer->end();
if(signalSemaphore != nullptr)
if (signalSemaphore != nullptr)
{
queue->submitCommandBuffer(activeCmdBuffer, signalSemaphore->getHandle());
}
@@ -154,11 +196,11 @@ void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
queue->submitCommandBuffer(activeCmdBuffer);
}
}
for(int32_t i = 0; i < allocatedBuffers.size(); ++i)
for (uint32 i = 0; i < allocatedBuffers.size(); ++i)
{
PCmdBuffer cmdBuffer = allocatedBuffers[i];
cmdBuffer->refreshFences();
if(cmdBuffer->state == CmdBuffer::State::ReadyBegin)
cmdBuffer->refreshFence();
if (cmdBuffer->state == CmdBuffer::State::ReadyBegin)
{
activeCmdBuffer = cmdBuffer;
activeCmdBuffer->begin();
@@ -173,3 +215,9 @@ void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
allocatedBuffers.add(activeCmdBuffer);
activeCmdBuffer->begin();
}
void CommandBufferManager::waitForCommands(PCmdBuffer cmdBuffer, uint32 timeout)
{
cmdBuffer->fence->wait(timeout);
cmdBuffer->refreshFence();
}
@@ -4,88 +4,100 @@
namespace Seele
{
namespace Vulkan
namespace Vulkan
{
DECLARE_REF(RenderPass);
DECLARE_REF(Framebuffer);
class CmdBufferBase : public Gfx::RenderCommandBase
{
public:
CmdBufferBase(PGraphics graphics, VkCommandPool cmdPool);
virtual ~CmdBufferBase();
inline VkCommandBuffer getHandle()
{
DECLARE_REF(RenderPass);
DECLARE_REF(Framebuffer);
class CmdBufferBase : public Gfx::RenderCommandBase
{
public:
CmdBufferBase(PGraphics graphics, VkCommandPool cmdPool);
virtual ~CmdBufferBase();
inline VkCommandBuffer getHandle()
{
return handle;
}
void reset();
VkViewport currentViewport;
VkRect2D currentScissor;
protected:
PGraphics graphics;
VkCommandBuffer handle;
VkCommandPool owner;
};
DEFINE_REF(CmdBufferBase);
DECLARE_REF(SecondaryCmdBuffer);
class CmdBuffer : public CmdBufferBase
{
public:
CmdBuffer(PGraphics graphics, VkCommandPool cmdPool);
virtual ~CmdBuffer();
void begin();
void end();
void beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer);
void endRenderPass();
void executeCommands(Array<PSecondaryCmdBuffer> secondaryCommands);
void addWaitSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore);
enum State
{
ReadyBegin,
InsideBegin,
RenderPassActive,
Ended,
Submitted,
};
private:
PRenderPass renderPass;
PFramebuffer framebuffer;
uint32 subpassIndex;
State state;
friend class SecondaryCmdBuffer;
friend class CommandBufferManager;
};
DEFINE_REF(CmdBuffer);
class SecondaryCmdBuffer : public CmdBufferBase
{
public:
SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool);
virtual ~SecondaryCmdBuffer();
void begin(PCmdBuffer parent);
void end();
private:
};
DEFINE_REF(SecondaryCmdBuffer);
class CommandBufferManager
{
public:
CommandBufferManager(PGraphics graphics, PQueue queue);
virtual ~CommandBufferManager();
PCmdBuffer getCommands();
PSecondaryCmdBuffer createSecondaryCmdBuffer();
void submitCommands(PSemaphore signalSemaphore = nullptr);
void waitForCommands(PCmdBuffer cmdBuffer, float timeToWait = 1.0f);
private:
PGraphics graphics;
VkCommandPool commandPool;
PQueue queue;
uint32 queueFamilyIndex;
PCmdBuffer activeCmdBuffer;
Array<PCmdBuffer> allocatedBuffers;
};
DEFINE_REF(CommandBufferManager);
return handle;
}
}
void reset();
VkViewport currentViewport;
VkRect2D currentScissor;
protected:
PGraphics graphics;
VkCommandBuffer handle;
VkCommandPool owner;
};
DEFINE_REF(CmdBufferBase);
DECLARE_REF(SecondaryCmdBuffer);
class CmdBuffer : public CmdBufferBase
{
public:
CmdBuffer(PGraphics graphics, VkCommandPool cmdPool);
virtual ~CmdBuffer();
void begin();
void end();
void beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer);
void endRenderPass();
void executeCommands(Array<PSecondaryCmdBuffer> secondaryCommands);
void addWaitSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore);
void refreshFence();
enum State
{
ReadyBegin,
InsideBegin,
RenderPassActive,
Ended,
Submitted,
};
private:
PRenderPass renderPass;
PFramebuffer framebuffer;
PFence fence;
uint32 subpassIndex;
State state;
Array<PSemaphore> waitSemaphores;
Array<VkPipelineStageFlags> waitFlags;
friend class SecondaryCmdBuffer;
friend class CommandBufferManager;
friend class Queue;
};
DEFINE_REF(CmdBuffer);
class SecondaryCmdBuffer : public CmdBufferBase
{
public:
SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool);
virtual ~SecondaryCmdBuffer();
void begin(PCmdBuffer parent);
void end();
private:
};
DEFINE_REF(SecondaryCmdBuffer);
class CommandBufferManager
{
public:
CommandBufferManager(PGraphics graphics, PQueue queue);
virtual ~CommandBufferManager();
inline PQueue getQueue() const
{
return queue;
}
PCmdBuffer getCommands();
PSecondaryCmdBuffer createSecondaryCmdBuffer();
void submitCommands(PSemaphore signalSemaphore = nullptr);
void waitForCommands(PCmdBuffer cmdBuffer, uint32 timeToWait = 1000000u);
private:
PGraphics graphics;
VkCommandPool commandPool;
PQueue queue;
uint32 queueFamilyIndex;
PCmdBuffer activeCmdBuffer;
Array<PCmdBuffer> allocatedBuffers;
};
DEFINE_REF(CommandBufferManager);
} // namespace Vulkan
} // namespace Seele
@@ -2,6 +2,7 @@
#include "VulkanGraphicsEnums.h"
#include "VulkanGraphics.h"
#include "VulkanInitializer.h"
#include "VulkanDescriptorSets.h"
using namespace Seele;
using namespace Seele::Vulkan;
@@ -23,8 +24,8 @@ void DescriptorLayout::create()
bindings.resize(descriptorBindings.size());
for (size_t i = 0; i < descriptorBindings.size(); ++i)
{
VkDescriptorSetLayoutBinding& binding = bindings[i];
const Gfx::DescriptorBinding& rhiBinding = descriptorBindings[i];
VkDescriptorSetLayoutBinding &binding = bindings[i];
const Gfx::DescriptorBinding &rhiBinding = descriptorBindings[i];
binding.binding = rhiBinding.binding;
binding.descriptorCount = rhiBinding.descriptorCount;
binding.descriptorType = cast(rhiBinding.descriptorType);
@@ -78,8 +79,8 @@ DescriptorSet::~DescriptorSet()
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer)
{
PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>();
// VkDescriptorBufferInfo bufferInfo = init::DescriptorBufferInfo(vulkanBuffer->getHandle(), vulkanBuffer->getOffset(), vulkanBuffer->getSize());
// bufferInfos.add(bufferInfo);
// VkDescriptorBufferInfo bufferInfo = init::DescriptorBufferInfo(vulkanBuffer->getHandle(), vulkanBuffer->getOffset(), vulkanBuffer->getSize());
// bufferInfos.add(bufferInfo);
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, binding, &bufferInfos.back());
writeDescriptors.add(writeDescriptor);
@@ -88,8 +89,8 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBu
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer)
{
PStructuredBuffer vulkanBuffer = uniformBuffer.cast<StructuredBuffer>();
// VkDescriptorBufferInfo bufferInfo = init::DescriptorBufferInfo(vulkanBuffer->getHandle(), vulkanBuffer->getOffset(), vulkanBuffer->getSize());
// bufferInfos.add(bufferInfo);
// VkDescriptorBufferInfo bufferInfo = init::DescriptorBufferInfo(vulkanBuffer->getHandle(), vulkanBuffer->getOffset(), vulkanBuffer->getSize());
// bufferInfos.add(bufferInfo);
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, binding, &bufferInfos.back());
writeDescriptors.add(writeDescriptor);
@@ -111,23 +112,23 @@ void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSamplerState samplerSt
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState samplerState)
{
// VulkanTextureBase* vulkanTexture = VulkanTextureBase::cast(texture);
PTextureHandle vulkanTexture = TextureBase::cast(texture);
//It is assumed that the image is in the correct layout
// VkDescriptorImageInfo imageInfo =
// init::DescriptorImageInfo(
// VK_NULL_HANDLE,
// vulkanTexture->defaultView.view,
// graphics->getRHIDevice().findLayout(vulkanTexture->surface.image));
VkDescriptorImageInfo imageInfo =
init::DescriptorImageInfo(
VK_NULL_HANDLE,
vulkanTexture->getView(),
vulkanTexture->getLayout());
if (samplerState != nullptr)
{
// PVulkanSamplerState vulkanSampler = samplerState.cast<VulkanSamplerState>();
// imageInfo.sampler = vulkanSampler->sampler;
PSamplerState vulkanSampler = samplerState.cast<SamplerState>();
imageInfo.sampler = vulkanSampler->sampler;
}
// imageInfos.add(imageInfo);
imageInfos.add(imageInfo);
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, samplerState != nullptr ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, binding, &imageInfos.back());
// if (vulkanTexture->surface.usageFlags & TexCreate_UAV)
if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT)
{
// writeDescriptor.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
writeDescriptor.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
}
writeDescriptors.add(writeDescriptor);
}
@@ -149,20 +150,19 @@ void DescriptorSet::writeChanges()
}
}
DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout& layout)
: layout(layout)
, graphics(graphics)
DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout &layout)
: layout(layout), graphics(graphics)
{
uint32 perTypeSizes[VK_DESCRIPTOR_TYPE_END_RANGE];
std::memset(perTypeSizes, 0, sizeof(perTypeSizes));
for (int i = 0; i < layout.getBindings().size(); ++i)
for (uint32 i = 0; i < layout.getBindings().size(); ++i)
{
auto& binding = layout.getBindings()[i];
auto &binding = layout.getBindings()[i];
int typeIndex = binding.descriptorType;
perTypeSizes[typeIndex] += 256;
}
Array<VkDescriptorPoolSize> poolSizes;
for (int i = 0; i < VK_DESCRIPTOR_TYPE_END_RANGE; ++i)
for (uint32 i = 0; i < VK_DESCRIPTOR_TYPE_END_RANGE; ++i)
{
if (perTypeSizes[i] > 0)
{
@@ -179,9 +179,10 @@ DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout& l
DescriptorAllocator::~DescriptorAllocator()
{
vkDestroyDescriptorPool(graphics->getDevice(), poolHandle, nullptr);
graphics = nullptr;
}
void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet& descriptorSet)
void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet)
{
descriptorSet = new DescriptorSet(graphics, this);
PDescriptorSet vulkanSet = descriptorSet.cast<DescriptorSet>();
@@ -0,0 +1,106 @@
#include "VulkanGraphicsResources.h"
namespace Seele
{
namespace Vulkan
{
DECLARE_REF(Graphics);
class DescriptorLayout : public Gfx::DescriptorLayout
{
public:
DescriptorLayout(PGraphics graphics)
: graphics(graphics), layoutHandle(VK_NULL_HANDLE)
{
}
virtual ~DescriptorLayout();
virtual void create();
inline VkDescriptorSetLayout getHandle() const
{
return layoutHandle;
}
private:
PGraphics graphics;
Array<VkDescriptorSetLayoutBinding> bindings;
VkDescriptorSetLayout layoutHandle;
friend class PipelineStateCacheManager;
};
DEFINE_REF(DescriptorLayout);
class PipelineLayout : public Gfx::PipelineLayout
{
public:
PipelineLayout(PGraphics graphics)
: graphics(graphics), layoutHash(0), layoutHandle(VK_NULL_HANDLE)
{
}
virtual ~PipelineLayout();
virtual void create();
inline VkPipelineLayout getHandle() const
{
return layoutHandle;
}
virtual uint32 getHash() const
{
return layoutHash;
}
private:
Array<VkDescriptorSetLayout> vulkanDescriptorLayouts;
uint32 layoutHash;
VkPipelineLayout layoutHandle;
PGraphics graphics;
friend class PipelineStateCacheManager;
};
DEFINE_REF(PipelineLayout);
class DescriptorSet : public Gfx::DescriptorSet
{
public:
DescriptorSet(PGraphics graphics, PDescriptorAllocator owner)
: graphics(graphics), owner(owner), setHandle(VK_NULL_HANDLE)
{
}
virtual ~DescriptorSet();
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer);
virtual void updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer);
virtual void updateSampler(uint32_t binding, Gfx::PSamplerState samplerState);
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState sampler = nullptr);
virtual bool operator<(Gfx::PDescriptorSet other);
inline VkDescriptorSet getHandle() const
{
return setHandle;
}
private:
virtual void writeChanges();
Array<VkDescriptorImageInfo> imageInfos;
Array<VkDescriptorBufferInfo> bufferInfos;
Array<VkWriteDescriptorSet> writeDescriptors;
VkDescriptorSet setHandle;
PDescriptorAllocator owner;
PGraphics graphics;
friend class DescriptorAllocator;
};
DEFINE_REF(DescriptorSet);
class DescriptorAllocator : public Gfx::DescriptorAllocator
{
public:
DescriptorAllocator(PGraphics graphics, DescriptorLayout &layout);
virtual ~DescriptorAllocator();
virtual void allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet);
inline VkDescriptorPool getHandle()
{
return poolHandle;
}
private:
PGraphics graphics;
int maxSets = 512;
VkDescriptorPool poolHandle;
DescriptorLayout &layout;
};
DEFINE_REF(DescriptorAllocator);
} // namespace Vulkan
} // namespace Seele
@@ -12,23 +12,27 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::PRende
, layout(renderTargetLayout)
, renderPass(renderPass)
{
FramebufferDescription description;
std::memset(&description, 0, sizeof(FramebufferDescription));
Array<VkImageView> attachments;
for(auto inputAttachment : layout->inputAttachments)
for (auto inputAttachment : layout->inputAttachments)
{
PTexture2D vkInputAttachment = inputAttachment.cast<Texture2D>();
PTexture2D vkInputAttachment = inputAttachment->getTexture().cast<Texture2D>();
attachments.add(vkInputAttachment->getView());
description.inputAttachments[description.numInputAttachments++] = vkInputAttachment->getView();
}
for(auto colorAttachment : layout->colorAttachments)
for (auto colorAttachment : layout->colorAttachments)
{
PTexture2D vkColorAttachment = colorAttachment.cast<Texture2D>();
PTexture2D vkColorAttachment = colorAttachment->getTexture().cast<Texture2D>();
attachments.add(vkColorAttachment->getView());
description.colorAttachments[description.numColorAttachments++] = vkColorAttachment->getView();
}
if(layout->depthAttachment != nullptr)
if (layout->depthAttachment != nullptr)
{
PTexture2D vkDepthAttachment = layout->depthAttachment.cast<Texture2D>();
PTexture2D vkDepthAttachment = layout->depthAttachment->getTexture().cast<Texture2D>();
attachments.add(vkDepthAttachment->getView());
description.depthAttachment = vkDepthAttachment->getView();
}
VkFramebufferCreateInfo createInfo =
init::FramebufferCreateInfo(
renderPass->getHandle(),
@@ -36,9 +40,10 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::PRende
attachments.data(),
renderPass->getRenderArea().extent.width,
renderPass->getRenderArea().extent.height,
1
);
1);
VK_CHECK(vkCreateFramebuffer(graphics->getDevice(), &createInfo, nullptr, &handle));
hash = memCrc32(&description, sizeof(FramebufferDescription));
}
Framebuffer::~Framebuffer()
+32 -19
View File
@@ -3,24 +3,37 @@
namespace Seele
{
namespace Vulkan
namespace Vulkan
{
DECLARE_REF(RenderPass);
struct FramebufferDescription
{
VkImageView inputAttachments[16];
VkImageView colorAttachments[16];
VkImageView depthAttachment;
uint32 numInputAttachments;
uint32 numColorAttachments;
};
class Framebuffer
{
public:
Framebuffer(PGraphics graphics, PRenderPass renderpass, Gfx::PRenderTargetLayout renderTargetLayout);
virtual ~Framebuffer();
inline VkFramebuffer getHandle() const
{
DECLARE_REF(RenderPass);
class Framebuffer
{
public:
Framebuffer(PGraphics graphics, PRenderPass renderpass, Gfx::PRenderTargetLayout renderTargetLayout);
virtual ~Framebuffer();
inline VkFramebuffer getHandle() const
{
return handle;
}
private:
PGraphics graphics;
VkFramebuffer handle;
Gfx::PRenderTargetLayout layout;
PRenderPass renderPass;
};
DEFINE_REF(Framebuffer);
return handle;
}
}
inline uint32 getHash() const
{
return hash;
}
private:
uint32 hash;
PGraphics graphics;
VkFramebuffer handle;
Gfx::PRenderTargetLayout layout;
PRenderPass renderPass;
};
DEFINE_REF(Framebuffer);
} // namespace Vulkan
} // namespace Seele
+121 -29
View File
@@ -1,26 +1,33 @@
#include "Containers/Array.h"
#include "VulkanGraphics.h"
#include "VulkanAllocator.h"
#include "VulkanQueue.h"
#include "Containers/Array.h"
#include "VulkanInitializer.h"
#include "VulkanCommandBuffer.h"
#include <GLFW/glfw3.h>
#include "VulkanRenderPass.h"
#include "VulkanFramebuffer.h"
#include "Graphics/GraphicsResources.h"
#include <glfw/glfw3.h>
using namespace Seele::Vulkan;
Graphics::Graphics()
: callback(VK_NULL_HANDLE), handle(VK_NULL_HANDLE), instance(VK_NULL_HANDLE), physicalDevice(VK_NULL_HANDLE)
{
glfwInit();
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
}
Graphics::~Graphics()
{
allocator = nullptr;
stagingManager = nullptr;
graphicsCommands = nullptr;
computeCommands = nullptr;
transferCommands = nullptr;
dedicatedTransferCommands = nullptr;
viewports.clear();
vkDestroyDevice(handle, nullptr);
DestroyDebugReportCallbackEXT(instance, nullptr, callback);
vkDestroyInstance(instance, nullptr);
glfwTerminate();
}
void Graphics::init(GraphicsInitializer initInfo)
@@ -30,27 +37,86 @@ void Graphics::init(GraphicsInitializer initInfo)
pickPhysicalDevice();
createDevice(initInfo);
allocator = new Allocator(this);
stagingManager = new StagingManager(this, allocator);
graphicsCommands = new CommandBufferManager(this, graphicsQueue);
computeCommands = new CommandBufferManager(this, computeQueue);
transferCommands = new CommandBufferManager(this, transferQueue);
dedicatedTransferCommands = new CommandBufferManager(this, dedicatedTransferQueue);
}
void Graphics::beginFrame(void *windowHandle)
Gfx::PWindow Graphics::createWindow(const WindowCreateInfo &createInfo)
{
GLFWwindow *window = static_cast<GLFWwindow *>(windowHandle);
glfwPollEvents();
PWindow result = new Window(this, createInfo);
return result;
}
void Graphics::endFrame(void *windowHandle)
Gfx::PViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreateInfo &viewportInfo)
{
GLFWwindow *window = static_cast<GLFWwindow *>(windowHandle);
PViewport result = new Viewport(this, owner, viewportInfo);
viewports.add(result);
return result;
}
Gfx::PRenderPass Graphics::createRenderPass(Gfx::PRenderTargetLayout layout)
{
PRenderPass result = new RenderPass(this, layout);
return result;
}
void Graphics::beginRenderPass(Gfx::PRenderPass renderPass)
{
PRenderPass rp = renderPass.cast<RenderPass>();
uint32 framebufferHash = rp->getFramebufferHash();
PFramebuffer framebuffer;
auto found = allocatedFramebuffers.find(framebufferHash);
if(found == allocatedFramebuffers.end())
{
framebuffer = new Framebuffer(this, rp, rp->getLayout());
}
else
{
framebuffer = found->value;
}
graphicsCommands->getCommands()->beginRenderPass(rp, framebuffer);
}
void *Graphics::createWindow(const WindowCreateInfo &createInfo)
void Graphics::endRenderPass()
{
GLFWwindow *window = glfwCreateWindow(createInfo.width, createInfo.height, createInfo.title, createInfo.bFullscreen ? glfwGetPrimaryMonitor() : nullptr, nullptr);
return window;
graphicsCommands->getCommands()->endRenderPass();
}
Gfx::PTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo)
{
PTexture2D result = new Texture2D(this, createInfo.width, createInfo.height, createInfo.bArray,
createInfo.bArray, createInfo.arrayLayers, createInfo.format,
createInfo.samples, createInfo.usage, createInfo.queueType);
return result;
}
Gfx::PUniformBuffer Graphics::createUniformBuffer(const BulkResourceData &bulkData)
{
PUniformBuffer uniformBuffer = new UniformBuffer(this, bulkData);
return uniformBuffer;
}
Gfx::PStructuredBuffer Graphics::createStructuredBuffer(const BulkResourceData &bulkData)
{
PStructuredBuffer structuredBuffer = new StructuredBuffer(this, bulkData);
return structuredBuffer;
}
Gfx::PVertexBuffer Graphics::createVertexBuffer(const BulkResourceData &bulkData)
{
PVertexBuffer vertexBuffer = new VertexBuffer(this, bulkData);
return vertexBuffer;
}
Gfx::PIndexBuffer Graphics::createIndexBuffer(const BulkResourceData &bulkData)
{
PIndexBuffer indexBuffer = new IndexBuffer(this, bulkData);
return indexBuffer;
}
VkInstance Graphics::getInstance() const
{
return instance;
}
VkDevice Graphics::getDevice() const
@@ -84,6 +150,11 @@ PAllocator Graphics::getAllocator()
return allocator;
}
PStagingManager Graphics::getStagingManager()
{
return stagingManager;
}
Array<const char *> Graphics::getRequiredExtensions()
{
Array<const char *> extensions;
@@ -143,13 +214,13 @@ void Graphics::pickPhysicalDevice()
vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr);
Array<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data());
VkPhysicalDevice bestDevice;
VkPhysicalDevice bestDevice = VK_NULL_HANDLE;
uint32 deviceRating = 0;
for (auto physicalDevice : physicalDevices)
for (auto dev : physicalDevices)
{
uint32 currentRating = 0;
vkGetPhysicalDeviceProperties(physicalDevice, &props);
vkGetPhysicalDeviceFeatures(physicalDevice, &features);
vkGetPhysicalDeviceProperties(dev, &props);
vkGetPhysicalDeviceFeatures(dev, &features);
if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
{
currentRating += 100;
@@ -161,10 +232,12 @@ void Graphics::pickPhysicalDevice()
if (currentRating > deviceRating)
{
deviceRating = currentRating;
bestDevice = physicalDevice;
bestDevice = dev;
}
}
this->physicalDevice = bestDevice;
physicalDevice = bestDevice;
vkGetPhysicalDeviceProperties(physicalDevice, &props);
vkGetPhysicalDeviceFeatures(physicalDevice, &features);
}
void Graphics::createDevice(GraphicsInitializer initializer)
@@ -180,11 +253,12 @@ void Graphics::createDevice(GraphicsInitializer initializer)
int32_t dedicatedTransferQueueFamilyIndex = -1;
int32_t computeQueueFamilyIndex = -1;
int32_t asyncComputeFamilyIndex = -1;
for (int32_t familyIndex = 0; familyIndex < queueProperties.size(); ++familyIndex)
uint32 numPriorities = 0;
for (uint32 familyIndex = 0; familyIndex < queueProperties.size(); ++familyIndex)
{
uint32 numQueuesForFamily = 0;
VkQueueFamilyProperties currProps = queueProperties[familyIndex];
bool bSparse = currProps.queueFlags & VK_QUEUE_SPARSE_BINDING_BIT;
// bool bSparse = currProps.queueFlags & VK_QUEUE_SPARSE_BINDING_BIT;
currProps.queueFlags = currProps.queueFlags ^ VK_QUEUE_SPARSE_BINDING_BIT;
if ((currProps.queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT)
{
@@ -204,7 +278,7 @@ void Graphics::createDevice(GraphicsInitializer initializer)
{
if (asyncComputeFamilyIndex == -1)
{
if (familyIndex == graphicsQueueFamilyIndex)
if (familyIndex == (uint32)graphicsQueueFamilyIndex)
{
if (currProps.queueCount > 1)
{
@@ -232,13 +306,27 @@ void Graphics::createDevice(GraphicsInitializer initializer)
numQueuesForFamily++;
}
}
if(numQueuesForFamily > 0)
if (numQueuesForFamily > 0)
{
VkDeviceQueueCreateInfo info =
init::DeviceQueueCreateInfo(familyIndex, numQueuesForFamily);
numPriorities += numQueuesForFamily;
queueInfos.add(info);
}
}
Array<float> queuePriorities;
queuePriorities.resize(numPriorities);
float *currentPriority = queuePriorities.data();
for (uint32 index = 0; index < queueInfos.size(); ++index)
{
VkDeviceQueueCreateInfo &currQueue = queueInfos[index];
currQueue.pQueuePriorities = currentPriority;
for (int32_t queueIndex = 0; queueIndex < (int32_t)currQueue.queueCount; ++queueIndex)
{
*currentPriority++ = 1.0f;
}
}
VkDeviceCreateInfo deviceInfo = init::DeviceCreateInfo(
queueInfos.data(),
(uint32)queueInfos.size(),
@@ -250,28 +338,32 @@ void Graphics::createDevice(GraphicsInitializer initializer)
VK_CHECK(vkCreateDevice(physicalDevice, &deviceInfo, nullptr, &handle));
graphicsQueue = new Queue(this, QueueType::GRAPHICS, graphicsQueueFamilyIndex, 0);
graphicsQueue = new Queue(this, Gfx::QueueType::GRAPHICS, graphicsQueueFamilyIndex, 0);
if (Gfx::useAsyncCompute && asyncComputeFamilyIndex != -1)
{
if (asyncComputeFamilyIndex == graphicsQueueFamilyIndex)
{
// Same family as graphics, but different queue
computeQueue = new Queue(this, QueueType::COMPUTE, asyncComputeFamilyIndex, 1);
computeQueue = new Queue(this, Gfx::QueueType::COMPUTE, asyncComputeFamilyIndex, 1);
}
else
{
// Different family
computeQueue = new Queue(this, QueueType::COMPUTE, asyncComputeFamilyIndex, 0);
computeQueue = new Queue(this, Gfx::QueueType::COMPUTE, asyncComputeFamilyIndex, 0);
}
}
else
{
computeQueue = new Queue(this, QueueType::COMPUTE, computeQueueFamilyIndex, 0);
computeQueue = new Queue(this, Gfx::QueueType::COMPUTE, computeQueueFamilyIndex, 0);
}
transferQueue = new Queue(this, QueueType::TRANSFER, transferQueueFamilyIndex, 0);
transferQueue = new Queue(this, Gfx::QueueType::TRANSFER, transferQueueFamilyIndex, 0);
if (dedicatedTransferQueueFamilyIndex != -1)
{
dedicatedTransferQueue = new Queue(this, QueueType::DEDICATED_TRANSFER, dedicatedTransferQueueFamilyIndex, 0);
dedicatedTransferQueue = new Queue(this, Gfx::QueueType::DEDICATED_TRANSFER, dedicatedTransferQueueFamilyIndex, 0);
}
else
{
dedicatedTransferQueue = transferQueue;
}
queueMapping.graphicsFamily = graphicsQueue->getFamilyIndex();
queueMapping.computeFamily = computeQueue->getFamilyIndex();
+76 -55
View File
@@ -1,62 +1,83 @@
#pragma once
#include "Graphics/Graphics.h"
#include "VulkanGraphicsResources.h"
#include "Graphics/Graphics.h"
namespace Seele
{
namespace Vulkan
namespace Vulkan
{
DECLARE_REF(Allocator);
DECLARE_REF(StagingManager);
DECLARE_REF(CommandBufferManager);
DECLARE_REF(Queue);
DECLARE_REF(Framebuffer);
class Graphics : public Gfx::Graphics
{
public:
Graphics();
virtual ~Graphics();
VkInstance getInstance() const;
VkDevice getDevice() const;
VkPhysicalDevice getPhysicalDevice() const;
PCommandBufferManager getGraphicsCommands();
PCommandBufferManager getComputeCommands();
PCommandBufferManager getTransferCommands();
PCommandBufferManager getDedicatedTransferCommands();
const QueueFamilyMapping getFamilyMapping() const
{
DECLARE_REF(Allocator);
DECLARE_REF(CommandBufferManager);
DECLARE_REF(Queue);
class Graphics : public Gfx::Graphics
{
public:
Graphics();
virtual ~Graphics();
VkDevice getDevice() const;
VkPhysicalDevice getPhysicalDevice() const;
PCommandBufferManager getGraphicsCommands();
PCommandBufferManager getComputeCommands();
PCommandBufferManager getTransferCommands();
PCommandBufferManager getDedicatedTransferCommands();
PAllocator getAllocator();
// Inherited via Graphics
virtual void init(GraphicsInitializer initializer) override;
virtual void beginFrame(void* windowHandle) override;
virtual void endFrame(void* windowHandle) override;
virtual void* createWindow(const WindowCreateInfo& createInfo) override;
protected:
Array<const char*> getRequiredExtensions();
void initInstance(GraphicsInitializer initInfo);
void setupDebugCallback();
void pickPhysicalDevice();
void createDevice(GraphicsInitializer initInfo);
VkDevice handle;
VkPhysicalDevice physicalDevice;
VkInstance instance;
PQueue graphicsQueue;
PQueue computeQueue;
PQueue transferQueue;
PQueue dedicatedTransferQueue;
QueueFamilyMapping queueMapping;
PCommandBufferManager graphicsCommands;
PCommandBufferManager computeCommands;
PCommandBufferManager transferCommands;
PCommandBufferManager dedicatedTransferCommands;
VkPhysicalDeviceProperties props;
VkPhysicalDeviceFeatures features;
VkDebugReportCallbackEXT callback;
Array<PViewport> viewports;
PAllocator allocator;
friend class Window;
};
DEFINE_REF(Graphics);
return queueMapping;
}
}
PAllocator getAllocator();
PStagingManager getStagingManager();
// Inherited via Graphics
virtual void init(GraphicsInitializer initializer) override;
virtual Gfx::PWindow createWindow(const WindowCreateInfo &createInfo) override;
virtual Gfx::PViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo &createInfo) override;
virtual Gfx::PRenderPass createRenderPass(Gfx::PRenderTargetLayout layout) override;
virtual void beginRenderPass(Gfx::PRenderPass renderPass) override;
virtual void endRenderPass() override;
virtual Gfx::PTexture2D createTexture2D(const TextureCreateInfo &createInfo) override;
virtual Gfx::PUniformBuffer createUniformBuffer(const BulkResourceData &bulkData) override;
virtual Gfx::PStructuredBuffer createStructuredBuffer(const BulkResourceData &bulkData) override;
virtual Gfx::PVertexBuffer createVertexBuffer(const BulkResourceData &bulkData) override;
virtual Gfx::PIndexBuffer createIndexBuffer(const BulkResourceData &bulkData) override;
protected:
Array<const char *> getRequiredExtensions();
void initInstance(GraphicsInitializer initInfo);
void setupDebugCallback();
void pickPhysicalDevice();
void createDevice(GraphicsInitializer initInfo);
VkDevice handle;
VkPhysicalDevice physicalDevice;
VkInstance instance;
PQueue graphicsQueue;
PQueue computeQueue;
PQueue transferQueue;
PQueue dedicatedTransferQueue;
QueueFamilyMapping queueMapping;
PCommandBufferManager graphicsCommands;
PCommandBufferManager computeCommands;
PCommandBufferManager transferCommands;
PCommandBufferManager dedicatedTransferCommands;
VkPhysicalDeviceProperties props;
VkPhysicalDeviceFeatures features;
VkDebugReportCallbackEXT callback;
Array<PViewport> viewports;
Map<uint32, PFramebuffer> allocatedFramebuffers;
PAllocator allocator;
PStagingManager stagingManager;
friend class Window;
};
DEFINE_REF(Graphics);
} // namespace Vulkan
} // namespace Seele
@@ -3,7 +3,7 @@
using namespace Seele::Vulkan;
using namespace Seele::Gfx;
VkDescriptorType Seele::Vulkan::cast(const Seele::Gfx::SeDescriptorType& descriptorType)
VkDescriptorType Seele::Vulkan::cast(const Seele::Gfx::SeDescriptorType &descriptorType)
{
switch (descriptorType)
{
@@ -41,7 +41,7 @@ VkDescriptorType Seele::Vulkan::cast(const Seele::Gfx::SeDescriptorType& descrip
return VK_DESCRIPTOR_TYPE_MAX_ENUM;
}
Seele::Gfx::SeDescriptorType Seele::Vulkan::cast(const VkDescriptorType& descriptorType)
Seele::Gfx::SeDescriptorType Seele::Vulkan::cast(const VkDescriptorType &descriptorType)
{
switch (descriptorType)
{
@@ -80,7 +80,7 @@ Seele::Gfx::SeDescriptorType Seele::Vulkan::cast(const VkDescriptorType& descrip
return SE_DESCRIPTOR_TYPE_MAX_ENUM;
}
VkShaderStageFlagBits Seele::Vulkan::cast(const Seele::Gfx::SeShaderStageFlagBits& stage)
VkShaderStageFlagBits Seele::Vulkan::cast(const Seele::Gfx::SeShaderStageFlagBits &stage)
{
switch (stage)
{
@@ -125,7 +125,7 @@ VkShaderStageFlagBits Seele::Vulkan::cast(const Seele::Gfx::SeShaderStageFlagBit
return VK_SHADER_STAGE_ALL;
}
Seele::Gfx::SeShaderStageFlagBits Seele::Vulkan::cast(const VkShaderStageFlagBits& stage)
Seele::Gfx::SeShaderStageFlagBits Seele::Vulkan::cast(const VkShaderStageFlagBits &stage)
{
switch (stage)
{
@@ -162,14 +162,14 @@ Seele::Gfx::SeShaderStageFlagBits Seele::Vulkan::cast(const VkShaderStageFlagBit
return SE_SHADER_STAGE_TASK_BIT_NV;
case VK_SHADER_STAGE_MESH_BIT_NV:
return SE_SHADER_STAGE_MESH_BIT_NV;
#endif
#endif
default:
break;
}
return SE_SHADER_STAGE_ALL;
}
VkFormat Seele::Vulkan::cast(const Seele::Gfx::SeFormat& format)
VkFormat Seele::Vulkan::cast(const Seele::Gfx::SeFormat &format)
{
switch (format)
{
@@ -631,7 +631,7 @@ VkFormat Seele::Vulkan::cast(const Seele::Gfx::SeFormat& format)
return VK_FORMAT_MAX_ENUM;
}
}
Seele::Gfx::SeFormat Seele::Vulkan::cast(const VkFormat& format)
Seele::Gfx::SeFormat Seele::Vulkan::cast(const VkFormat &format)
{
switch (format)
{
@@ -1092,4 +1092,56 @@ Seele::Gfx::SeFormat Seele::Vulkan::cast(const VkFormat& format)
default:
return SE_FORMAT_MAX_ENUM;
}
}
}
VkAttachmentStoreOp Seele::Vulkan::cast(const Gfx::SeAttachmentStoreOp &storeOp)
{
switch (storeOp)
{
case SE_ATTACHMENT_STORE_OP_STORE:
return VK_ATTACHMENT_STORE_OP_STORE;
case SE_ATTACHMENT_STORE_OP_DONT_CARE:
return VK_ATTACHMENT_STORE_OP_DONT_CARE;
default:
return VK_ATTACHMENT_STORE_OP_MAX_ENUM;
}
}
Gfx::SeAttachmentStoreOp Seele::Vulkan::cast(const VkAttachmentStoreOp &storeOp)
{
switch (storeOp)
{
case VK_ATTACHMENT_STORE_OP_STORE:
return SE_ATTACHMENT_STORE_OP_STORE;
case VK_ATTACHMENT_STORE_OP_DONT_CARE:
return SE_ATTACHMENT_STORE_OP_DONT_CARE;
default:
return SE_ATTACHMENT_STORE_OP_MAX_ENUM;
}
}
VkAttachmentLoadOp Seele::Vulkan::cast(const Gfx::SeAttachmentLoadOp &loadOp)
{
switch (loadOp)
{
case SE_ATTACHMENT_LOAD_OP_LOAD:
return VK_ATTACHMENT_LOAD_OP_LOAD;
case SE_ATTACHMENT_LOAD_OP_CLEAR:
return VK_ATTACHMENT_LOAD_OP_CLEAR;
case SE_ATTACHMENT_LOAD_OP_DONT_CARE:
return VK_ATTACHMENT_LOAD_OP_DONT_CARE;
default:
return VK_ATTACHMENT_LOAD_OP_MAX_ENUM;
}
}
Gfx::SeAttachmentLoadOp Seele::Vulkan::cast(const VkAttachmentLoadOp &loadOp)
{
switch (loadOp)
{
case VK_ATTACHMENT_LOAD_OP_LOAD:
return SE_ATTACHMENT_LOAD_OP_LOAD;
case VK_ATTACHMENT_LOAD_OP_CLEAR:
return SE_ATTACHMENT_LOAD_OP_CLEAR;
case VK_ATTACHMENT_LOAD_OP_DONT_CARE:
return SE_ATTACHMENT_LOAD_OP_DONT_CARE;
default:
return SE_ATTACHMENT_LOAD_OP_MAX_ENUM;
}
}
@@ -2,25 +2,29 @@
#include "Graphics/GraphicsEnums.h"
#include <vulkan/vulkan.h>
#define VK_CHECK(f) \
{ \
VkResult res = (f); \
if (res != VK_SUCCESS) \
{ \
std::cout << "Fatal : VkResult is \"" << res << "\" in " << __FILE__ << " at line " << __LINE__ << std::endl; \
assert(res == VK_SUCCESS); \
} \
}
#define VK_CHECK(f) \
{ \
VkResult res = (f); \
if (res != VK_SUCCESS) \
{ \
std::cout << "Fatal : VkResult is \"" << res << "\" in " << __FILE__ << " at line " << __LINE__ << std::endl; \
assert(res == VK_SUCCESS); \
} \
}
namespace Seele
{
namespace Vulkan
{
VkDescriptorType cast(const Gfx::SeDescriptorType& descriptorType);
Gfx::SeDescriptorType cast(const VkDescriptorType& descriptorType);
VkShaderStageFlagBits cast(const Gfx::SeShaderStageFlagBits& stage);
Gfx::SeShaderStageFlagBits cast(const VkShaderStageFlagBits& stage);
VkFormat cast(const Gfx::SeFormat& format);
Gfx::SeFormat cast(const VkFormat& format);
}
}
namespace Vulkan
{
VkDescriptorType cast(const Gfx::SeDescriptorType &descriptorType);
Gfx::SeDescriptorType cast(const VkDescriptorType &descriptorType);
VkShaderStageFlagBits cast(const Gfx::SeShaderStageFlagBits &stage);
Gfx::SeShaderStageFlagBits cast(const VkShaderStageFlagBits &stage);
VkFormat cast(const Gfx::SeFormat &format);
Gfx::SeFormat cast(const VkFormat &format);
VkAttachmentStoreOp cast(const Gfx::SeAttachmentStoreOp &storeOp);
Gfx::SeAttachmentStoreOp cast(const VkAttachmentStoreOp &storeOp);
VkAttachmentLoadOp cast(const Gfx::SeAttachmentLoadOp &loadOp);
Gfx::SeAttachmentLoadOp cast(const VkAttachmentLoadOp &loadOp);
} // namespace Vulkan
} // namespace Seele
@@ -2,10 +2,52 @@
#include "VulkanInitializer.h"
#include "VulkanGraphics.h"
#include "VulkanGraphicsEnums.h"
#include "VulkanCommandBuffer.h"
using namespace Seele;
using namespace Seele::Vulkan;
QueueOwnedResource::QueueOwnedResource(PGraphics graphics, Gfx::QueueType startQueueType)
: graphics(graphics), currentOwner(startQueueType)
{
}
QueueOwnedResource::~QueueOwnedResource()
{
cachedCmdBufferManager = nullptr;
graphics = nullptr;
}
void QueueOwnedResource::transferOwnership(Gfx::QueueType newOwner)
{
if (graphics->getFamilyMapping().needsTransfer(currentOwner, newOwner))
{
executeOwnershipBarrier(newOwner);
currentOwner = newOwner;
}
}
PCommandBufferManager QueueOwnedResource::getCommands()
{
if (cachedCmdBufferManager != nullptr)
{
assert(cachedCmdBufferManager->getQueue()->getFamilyIndex() == graphics->getFamilyMapping().getQueueTypeFamilyIndex(currentOwner));
return cachedCmdBufferManager;
}
switch (currentOwner)
{
case Gfx::QueueType::GRAPHICS:
return graphics->getGraphicsCommands();
case Gfx::QueueType::COMPUTE:
return graphics->getComputeCommands();
case Gfx::QueueType::TRANSFER:
return graphics->getTransferCommands();
case Gfx::QueueType::DEDICATED_TRANSFER:
return graphics->getDedicatedTransferCommands();
}
return nullptr;
}
Semaphore::Semaphore(PGraphics graphics)
: graphics(graphics)
{
@@ -16,5 +58,65 @@ Semaphore::Semaphore(PGraphics graphics)
Semaphore::~Semaphore()
{
graphics = nullptr;
vkDestroySemaphore(graphics->getDevice(), handle, nullptr);
}
}
Fence::Fence(PGraphics graphics)
: graphics(graphics), signaled(false)
{
VkFenceCreateInfo info =
init::FenceCreateInfo(0);
VK_CHECK(vkCreateFence(graphics->getDevice(), &info, nullptr, &fence));
}
Fence::~Fence()
{
vkDestroyFence(graphics->getDevice(), fence, nullptr);
}
bool Fence::isSignaled()
{
if (signaled)
{
return true;
}
VkResult res = vkGetFenceStatus(graphics->getDevice(), fence);
switch (res)
{
case VK_SUCCESS:
signaled = true;
return true;
case VK_NOT_READY:
break;
default:
break;
}
return false;
}
void Fence::reset()
{
if (signaled)
{
vkResetFences(graphics->getDevice(), 1, &fence);
signaled = false;
}
}
void Fence::wait(uint32 timeout)
{
VkFence fences[] = {fence};
VkResult r = vkWaitForFences(graphics->getDevice(), 1, fences, true, timeout * 1000ull);
switch (r)
{
case VK_SUCCESS:
signaled = true;
break;
case VK_TIMEOUT:
break;
default:
VK_CHECK(r);
break;
}
}
@@ -10,6 +10,7 @@ namespace Vulkan
DECLARE_REF(DescriptorAllocator);
DECLARE_REF(CommandBufferManager);
DECLARE_REF(Graphics);
DECLARE_REF(SubAllocation);
class Semaphore
{
public:
@@ -19,116 +20,32 @@ public:
{
return handle;
}
private:
VkSemaphore handle;
PGraphics graphics;
};
DEFINE_REF(Semaphore);
class DescriptorLayout : public Gfx::DescriptorLayout
class Fence
{
public:
DescriptorLayout(PGraphics graphics)
: graphics(graphics), layoutHandle(VK_NULL_HANDLE)
Fence(PGraphics graphics);
~Fence();
bool isSignaled();
void reset();
inline VkFence getHandle() const
{
return fence;
}
virtual ~DescriptorLayout();
virtual void create();
inline VkDescriptorSetLayout getHandle() const
{
return layoutHandle;
}
void wait(uint32 timeout);
private:
bool signaled;
VkFence fence;
PGraphics graphics;
Array<VkDescriptorSetLayoutBinding> bindings;
VkDescriptorSetLayout layoutHandle;
friend class PipelineStateCacheManager;
};
DEFINE_REF(DescriptorLayout);
class PipelineLayout : public Gfx::PipelineLayout
{
public:
PipelineLayout(PGraphics graphics)
: graphics(graphics), layoutHash(0), layoutHandle(VK_NULL_HANDLE)
{
}
virtual ~PipelineLayout();
virtual void create();
inline VkPipelineLayout getHandle() const
{
return layoutHandle;
}
virtual uint32 getHash() const
{
return layoutHash;
}
private:
Array<VkDescriptorSetLayout> vulkanDescriptorLayouts;
uint32 layoutHash;
VkPipelineLayout layoutHandle;
PGraphics graphics;
friend class PipelineStateCacheManager;
};
DEFINE_REF(PipelineLayout);
class DescriptorSet : public Gfx::DescriptorSet
{
public:
DescriptorSet(PGraphics graphics, PDescriptorAllocator owner)
: graphics(graphics), owner(owner), setHandle(VK_NULL_HANDLE)
{
}
virtual ~DescriptorSet();
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer);
virtual void updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer);
virtual void updateSampler(uint32_t binding, Gfx::PSamplerState samplerState);
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState sampler = nullptr);
virtual bool operator<(Gfx::PDescriptorSet other);
inline VkDescriptorSet getHandle() const
{
return setHandle;
}
private:
virtual void writeChanges();
Array<VkDescriptorImageInfo> imageInfos;
Array<VkDescriptorBufferInfo> bufferInfos;
Array<VkWriteDescriptorSet> writeDescriptors;
VkDescriptorSet setHandle;
PDescriptorAllocator owner;
PGraphics graphics;
friend class DescriptorAllocator;
};
DEFINE_REF(DescriptorSet);
class DescriptorAllocator : public Gfx::DescriptorAllocator
{
public:
DescriptorAllocator(PGraphics graphics, DescriptorLayout &layout);
~DescriptorAllocator();
virtual void allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet);
inline VkDescriptorPool getHandle()
{
return poolHandle;
}
private:
PGraphics graphics;
int maxSets = 512;
VkDescriptorPool poolHandle;
DescriptorLayout &layout;
};
DEFINE_REF(DescriptorAllocator);
enum class QueueType
{
GRAPHICS = 1,
COMPUTE = 2,
TRANSFER = 3,
DEDICATED_TRANSFER = 4
};
DEFINE_REF(Fence);
struct QueueFamilyMapping
{
@@ -136,23 +53,23 @@ struct QueueFamilyMapping
uint32 computeFamily;
uint32 transferFamily;
uint32 dedicatedTransferFamily;
uint32 getQueueTypeFamilyIndex(QueueType type)
uint32 getQueueTypeFamilyIndex(Gfx::QueueType type) const
{
switch (type)
{
case QueueType::GRAPHICS:
case Gfx::QueueType::GRAPHICS:
return graphicsFamily;
case QueueType::COMPUTE:
case Gfx::QueueType::COMPUTE:
return computeFamily;
case QueueType::TRANSFER:
case Gfx::QueueType::TRANSFER:
return transferFamily;
case QueueType::DEDICATED_TRANSFER:
case Gfx::QueueType::DEDICATED_TRANSFER:
return dedicatedTransferFamily;
default:
return VK_QUEUE_FAMILY_IGNORED;
}
}
bool needsTransfer(QueueType src, QueueType dst)
bool needsTransfer(Gfx::QueueType src, Gfx::QueueType dst) const
{
uint32 srcIndex = getQueueTypeFamilyIndex(src);
uint32 dstIndex = getQueueTypeFamilyIndex(dst);
@@ -162,71 +79,179 @@ struct QueueFamilyMapping
class QueueOwnedResource
{
public:
QueueOwnedResource(PGraphics graphics, QueueType startQueueType);
~QueueOwnedResource();
QueueOwnedResource(PGraphics graphics, Gfx::QueueType startQueueType);
virtual ~QueueOwnedResource();
PCommandBufferManager getCommands();
//Preliminary checks to see if the barrier should be executed at all
void transferOwnership(QueueType newOwner);
void transferOwnership(Gfx::QueueType newOwner);
protected:
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
QueueType currentOwner;
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) = 0;
Gfx::QueueType currentOwner;
PGraphics graphics;
CommandBufferManager *cachedCmdBufferManager;
PCommandBufferManager cachedCmdBufferManager;
};
DEFINE_REF(QueueOwnedResource);
class Buffer : public QueueOwnedResource
{
public:
Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, QueueType queueType = QueueType::GRAPHICS);
Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType);
virtual ~Buffer();
VkBuffer getHandle() const
{
return buffers[currentBuffer].buffer;
}
void advanceBuffer()
{
currentBuffer = (currentBuffer + 1) % numBuffers;
}
void *lock(bool bWriteOnly = true);
void unlock();
protected:
struct BufferAllocation
{
VkBuffer buffer;
PSubAllocation allocation;
};
BufferAllocation buffers[Gfx::numFramesBuffered];
uint32 numBuffers;
uint32 currentBuffer;
uint32 size;
private:
virtual VkAccessFlags getSourceAccessMask() = 0;
virtual VkAccessFlags getDestAccessMask() = 0;
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner);
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
};
DEFINE_REF(Buffer);
class UniformBuffer : public Buffer, public Gfx::UniformBuffer
{
public:
UniformBuffer(PGraphics graphics, const BulkResourceData &resourceData);
virtual ~UniformBuffer();
protected:
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
};
DEFINE_REF(UniformBuffer);
class StructuredBuffer : public Buffer, public Gfx::StructuredBuffer
{
public:
StructuredBuffer(PGraphics graphics, const BulkResourceData &resourceData);
virtual ~StructuredBuffer();
protected:
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
};
DEFINE_REF(StructuredBuffer);
class TextureBase
class VertexBuffer : public Buffer, public Gfx::VertexBuffer
{
public:
TextureBase(PGraphics graphics, VkImageViewType viewType, uint32 sizeX, uint32 sizeY, uint32 sizeZ,
bool bArray, uint32 arraySize, uint32 mipLevels, Gfx::SeFormat format,
uint32 samples, Gfx::SeImageUsageFlags usage);
virtual ~TextureBase();
VertexBuffer(PGraphics graphics, const BulkResourceData &resourceData);
virtual ~VertexBuffer();
protected:
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
};
DEFINE_REF(VertexBuffer);
class IndexBuffer : public Buffer, public Gfx::IndexBuffer
{
public:
IndexBuffer(PGraphics graphics, const BulkResourceData &resourceData);
virtual ~IndexBuffer();
protected:
virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask();
};
DEFINE_REF(IndexBuffer);
class TextureHandle : public QueueOwnedResource
{
public:
TextureHandle(PGraphics graphics, VkImageViewType viewType, uint32 sizeX, uint32 sizeY, uint32 sizeZ,
bool bArray, uint32 arraySize, uint32 mipLevels, Gfx::SeFormat format,
uint32 samples, Gfx::SeImageUsageFlags usage, Gfx::QueueType owner = Gfx::QueueType::GRAPHICS, VkImage existingImage = VK_NULL_HANDLE);
virtual ~TextureHandle();
inline VkImageView getView() const
{
return defaultView;
}
inline VkImageLayout getLayout() const
{
return layout;
}
inline VkImageAspectFlags getAspect() const
{
return aspect;
}
inline VkImageUsageFlags getUsage() const
{
return usage;
}
inline Gfx::SeFormat getFormat() const
{
return format;
}
inline bool isDepthStencil() const
{
return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
}
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
private:
PGraphics graphics;
PSubAllocation allocation;
uint32 sizeX;
uint32 sizeY;
uint32 sizeZ;
uint32 arrayCount;
uint32 mipLevels;
uint32 samples;
Gfx::SeFormat format;
Gfx::SeImageUsageFlags usage;
VkImage image;
VkImageView defaultView;
VkImageAspectFlags aspect;
VkImageLayout layout;
friend class TextureBase;
friend class Texture2D;
};
DEFINE_REF(TextureHandle);
DECLARE_REF(TextureBase);
class TextureBase
{
public:
static PTextureHandle cast(Gfx::PTexture texture)
{
PTextureBase base = texture.cast<TextureBase>();
return base->textureHandle;
}
void changeLayout(VkImageLayout newLayout);
protected:
PTextureHandle textureHandle;
};
DEFINE_REF(TextureBase);
class Texture2D : public Gfx::Texture2D
class Texture2D : public TextureBase, public Gfx::Texture2D
{
public:
Texture2D(PGraphics graphics, uint32 sizeX, uint32 sizeY,
bool bArray, uint32 arraySize, uint32 mipLevels,
Gfx::SeFormat format, uint32 samples, Gfx::SeImageUsageFlags usage);
Texture2D(PGraphics graphics, uint32 sizeX, uint32 sizeY,
bool bArray, uint32 arraySize, uint32 mipLevels, Gfx::SeFormat format,
uint32 samples, Gfx::SeImageUsageFlags usage, Gfx::QueueType owner = Gfx::QueueType::GRAPHICS, VkImage existingImage = VK_NULL_HANDLE);
virtual ~Texture2D();
inline uint32 getSizeX() const
{
@@ -248,8 +273,12 @@ public:
{
return textureHandle->defaultView;
}
inline bool isDepthStencil() const
{
return textureHandle->isDepthStencil();
}
private:
PTextureBase textureHandle;
};
DEFINE_REF(Texture2D);
@@ -260,16 +289,54 @@ public:
};
DEFINE_REF(SamplerState);
class Window : public Gfx::Window
{
public:
Window(PGraphics graphics, const WindowCreateInfo &createInfo);
virtual ~Window();
virtual void beginFrame() override;
virtual void endFrame() override;
virtual Gfx::PTexture2D getBackBuffer() override;
virtual void onWindowCloseEvent() override;
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);
PTexture2D backBufferImages[Gfx::numFramesBuffered];
PSemaphore renderFinished[Gfx::numFramesBuffered];
PSemaphore imageAcquired[Gfx::numFramesBuffered];
PSemaphore imageAcquiredSemaphore;
PGraphics graphics;
VkFormat pixelFormat;
VkPresentModeKHR presentMode;
VkSwapchainKHR swapchain;
VkSurfaceKHR surface;
VkSurfaceFormatKHR surfaceFormat;
void *windowHandle;
int32 currentImageIndex;
int32 acquiredImageIndex;
int32 preAcquiredImageIndex;
int32 semaphoreIndex;
VkInstance instance;
};
DEFINE_REF(Window);
class Viewport : public Gfx::Viewport
{
public:
Viewport(PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo);
virtual ~Viewport();
protected:
private:
uint32 sizeX;
uint32 sizeY;
uint32 offsetX;
uint32 offsetY;
VkSwapchainKHR swapchain;
void *windowHandle;
PGraphics graphics;
friend class Graphics;
};
DECLARE_REF(Viewport);
} // namespace Vulkan
@@ -3,7 +3,7 @@
using namespace Seele::Vulkan;
VkApplicationInfo init::ApplicationInfo(const char* appName, uint32_t appVersion, const char* engineName, uint32_t engineVersion, uint32_t apiVersion)
VkApplicationInfo init::ApplicationInfo(const char *appName, uint32_t appVersion, const char *engineName, uint32_t engineVersion, uint32_t apiVersion)
{
VkApplicationInfo info = {};
info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
@@ -11,10 +11,11 @@ VkApplicationInfo init::ApplicationInfo(const char* appName, uint32_t appVersion
info.applicationVersion = appVersion;
info.pEngineName = engineName;
info.engineVersion = engineVersion;
info.apiVersion = apiVersion;
return info;
}
VkInstanceCreateInfo init::InstanceCreateInfo(VkApplicationInfo* appInfo, const Array<const char*>& extensions, const Array<const char*>& layers)
VkInstanceCreateInfo init::InstanceCreateInfo(VkApplicationInfo *appInfo, const Array<const char *> &extensions, const Array<const char *> &layers)
{
VkInstanceCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
@@ -41,7 +42,7 @@ VkDeviceQueueCreateInfo init::DeviceQueueCreateInfo(int queueFamilyIndex, int qu
return DeviceQueueCreateInfo(queueFamilyIndex, queueCount, &priority);
}
VkDeviceQueueCreateInfo init::DeviceQueueCreateInfo(int queueFamilyIndex, int queueCount, float* queuePriority)
VkDeviceQueueCreateInfo init::DeviceQueueCreateInfo(int queueFamilyIndex, int queueCount, float *queuePriority)
{
VkDeviceQueueCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
@@ -51,7 +52,7 @@ VkDeviceQueueCreateInfo init::DeviceQueueCreateInfo(int queueFamilyIndex, int qu
return createInfo;
}
VkDeviceCreateInfo init::DeviceCreateInfo(VkDeviceQueueCreateInfo* queueInfos, uint32_t queueCount, VkPhysicalDeviceFeatures* features)
VkDeviceCreateInfo init::DeviceCreateInfo(VkDeviceQueueCreateInfo *queueInfos, uint32_t queueCount, VkPhysicalDeviceFeatures *features)
{
return DeviceCreateInfo(queueInfos, queueCount, features, nullptr, 0, nullptr, 0);
}
@@ -93,7 +94,7 @@ VkSwapchainCreateInfoKHR init::SwapchainCreateInfo(VkSurfaceKHR surface, uint32_
return createInfo;
}
VkFramebufferCreateInfo init::FramebufferCreateInfo(VkRenderPass renderPass, uint32_t attachmentCount, VkImageView* attachments, uint32_t width, uint32_t height, uint32_t layers)
VkFramebufferCreateInfo init::FramebufferCreateInfo(VkRenderPass renderPass, uint32_t attachmentCount, VkImageView *attachments, uint32_t width, uint32_t height, uint32_t layers)
{
VkFramebufferCreateInfo frameBufferCreateInfo = {};
frameBufferCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
@@ -121,16 +122,26 @@ VkAttachmentDescription init::AttachmentDescription(VkFormat format, VkSampleCou
return desc;
}
VkSubpassDescription init::SubpassDescription(VkPipelineBindPoint bindPoint, uint32_t colorAttachmentCount, VkAttachmentReference* colorReference, uint32_t depthAttachmentCount, VkAttachmentReference* depthReference, uint32_t inputAttachmentCount, VkAttachmentReference* inputReference, uint32_t resolveAttachmentCount, VkAttachmentReference* resolveReference, uint32_t preserveAttachmentCount, VkAttachmentReference* preserveReference)
VkSubpassDescription init::SubpassDescription(VkPipelineBindPoint bindPoint,
uint32_t colorAttachmentCount, VkAttachmentReference *colorReference,
VkAttachmentReference *depthReference,
uint32_t inputAttachmentCount, VkAttachmentReference *inputReference,
VkAttachmentReference *resolveReference, uint32_t preserveAttachmentCount, uint32_t *preserveReference)
{
VkSubpassDescription desc = {};
desc.pipelineBindPoint = bindPoint;
desc.colorAttachmentCount = colorAttachmentCount;
desc.pColorAttachments = colorReference;
desc.inputAttachmentCount = inputAttachmentCount;
desc.pInputAttachments = inputReference;
desc.pResolveAttachments = resolveReference;
desc.preserveAttachmentCount = preserveAttachmentCount;
desc.pPreserveAttachments = preserveReference;
desc.pDepthStencilAttachment = depthReference;
return desc;
}
VkRenderPassCreateInfo init::RenderPassCreateInfo(uint32_t attachmentCount, const VkAttachmentDescription* attachments, uint32_t subpassCount, const VkSubpassDescription* subpasses, uint32_t dependencyCount, const VkSubpassDependency* subpassDependencies)
VkRenderPassCreateInfo init::RenderPassCreateInfo(uint32_t attachmentCount, const VkAttachmentDescription *attachments, uint32_t subpassCount, const VkSubpassDescription *subpasses, uint32_t dependencyCount, const VkSubpassDependency *subpassDependencies)
{
VkRenderPassCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
@@ -143,7 +154,7 @@ VkRenderPassCreateInfo init::RenderPassCreateInfo(uint32_t attachmentCount, cons
return info;
}
VkDeviceCreateInfo init::DeviceCreateInfo(VkDeviceQueueCreateInfo* queueInfos, uint32_t queueCount, VkPhysicalDeviceFeatures* features, const char* const* deviceExtensions, uint32_t deviceExtensionCount, const char* const* layers, uint32_t layerCount)
VkDeviceCreateInfo init::DeviceCreateInfo(VkDeviceQueueCreateInfo *queueInfos, uint32_t queueCount, VkPhysicalDeviceFeatures *features, const char *const *deviceExtensions, uint32_t deviceExtensionCount, const char *const *layers, uint32_t layerCount)
{
VkDeviceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
@@ -160,6 +171,8 @@ VkDeviceCreateInfo init::DeviceCreateInfo(VkDeviceQueueCreateInfo* queueInfos, u
createInfo.ppEnabledLayerNames = layers;
#else
createInfo.enabledLayerCount = 0;
layerCount = 0;
layers = nullptr;
#endif // ENABLE_VALIDATION
return createInfo;
@@ -230,33 +243,40 @@ VkImageMemoryBarrier init::ImageMemoryBarrier(VkImage image, VkImageLayout oldLa
barrier.srcQueueFamilyIndex = srcQueue;
barrier.dstQueueFamilyIndex = dstQueue;
barrier.image = image;
if (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
if (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
{
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
}
else {
else
{
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
}
barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.levelCount = 1;
barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.layerCount = 1;
if (oldLayout == VK_IMAGE_LAYOUT_PREINITIALIZED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) {
if (oldLayout == VK_IMAGE_LAYOUT_PREINITIALIZED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
{
barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
}
else if (oldLayout == VK_IMAGE_LAYOUT_PREINITIALIZED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
else if (oldLayout == VK_IMAGE_LAYOUT_PREINITIALIZED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
{
barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
}
else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
{
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
}
else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
{
barrier.srcAccessMask = 0;
barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
}
else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
else if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
{
barrier.srcAccessMask = 0;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
}
@@ -422,7 +442,7 @@ VkBufferCreateInfo init::BufferCreateInfo(
VkDescriptorPoolCreateInfo init::DescriptorPoolCreateInfo(
uint32_t poolSizeCount,
VkDescriptorPoolSize* pPoolSizes,
VkDescriptorPoolSize *pPoolSizes,
uint32_t maxSets)
{
VkDescriptorPoolCreateInfo descriptorPoolInfo = {};
@@ -459,7 +479,7 @@ VkDescriptorSetLayoutBinding init::DescriptorSetLayoutBinding(
}
VkDescriptorSetLayoutCreateInfo init::DescriptorSetLayoutCreateInfo(
const VkDescriptorSetLayoutBinding* pBindings,
const VkDescriptorSetLayoutBinding *pBindings,
uint32_t bindingCount)
{
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {};
@@ -471,7 +491,7 @@ VkDescriptorSetLayoutCreateInfo init::DescriptorSetLayoutCreateInfo(
}
VkPipelineLayoutCreateInfo init::PipelineLayoutCreateInfo(
const VkDescriptorSetLayout* pSetLayouts,
const VkDescriptorSetLayout *pSetLayouts,
uint32_t setLayoutCount)
{
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {};
@@ -484,7 +504,7 @@ VkPipelineLayoutCreateInfo init::PipelineLayoutCreateInfo(
VkDescriptorSetAllocateInfo init::DescriptorSetAllocateInfo(
VkDescriptorPool descriptorPool,
const VkDescriptorSetLayout* pSetLayouts,
const VkDescriptorSetLayout *pSetLayouts,
uint32_t descriptorSetCount)
{
VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {};
@@ -522,7 +542,7 @@ VkWriteDescriptorSet init::WriteDescriptorSet(
VkDescriptorSet dstSet,
VkDescriptorType type,
uint32_t binding,
VkDescriptorBufferInfo* bufferInfo)
VkDescriptorBufferInfo *bufferInfo)
{
VkWriteDescriptorSet writeDescriptorSet = {};
writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
@@ -540,7 +560,7 @@ VkWriteDescriptorSet init::WriteDescriptorSet(
VkDescriptorSet dstSet,
VkDescriptorType type,
uint32_t binding,
VkDescriptorImageInfo* bufferInfo)
VkDescriptorImageInfo *bufferInfo)
{
VkWriteDescriptorSet writeDescriptorSet = {};
writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
@@ -630,7 +650,7 @@ VkPipelineColorBlendAttachmentState init::PipelineColorBlendAttachmentState(
VkPipelineColorBlendStateCreateInfo init::PipelineColorBlendStateCreateInfo(
uint32_t attachmentCount,
const VkPipelineColorBlendAttachmentState* pAttachments)
const VkPipelineColorBlendAttachmentState *pAttachments)
{
VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo = {};
pipelineColorBlendStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
@@ -674,17 +694,19 @@ VkPipelineMultisampleStateCreateInfo init::PipelineMultisampleStateCreateInfo(
{
VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo = {};
pipelineMultisampleStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
pipelineMultisampleStateCreateInfo.flags = flags;
pipelineMultisampleStateCreateInfo.rasterizationSamples = rasterizationSamples;
return pipelineMultisampleStateCreateInfo;
}
VkPipelineDynamicStateCreateInfo init::PipelineDynamicStateCreateInfo(
const VkDynamicState* pDynamicStates,
const VkDynamicState *pDynamicStates,
uint32_t dynamicStateCount,
VkPipelineDynamicStateCreateFlags flags)
{
VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {};
pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
pipelineDynamicStateCreateInfo.flags = flags;
pipelineDynamicStateCreateInfo.pDynamicStates = pDynamicStates;
pipelineDynamicStateCreateInfo.dynamicStateCount = dynamicStateCount;
return pipelineDynamicStateCreateInfo;
@@ -733,7 +755,7 @@ VkPushConstantRange init::PushConstantRange(
return pushConstantRange;
}
VkPipelineShaderStageCreateInfo init::PipelineShaderStageCreateInfo(VkShaderStageFlagBits stage, VkShaderModule module, const char* entryName)
VkPipelineShaderStageCreateInfo init::PipelineShaderStageCreateInfo(VkShaderStageFlagBits stage, VkShaderModule module, const char *entryName)
{
VkPipelineShaderStageCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
@@ -743,25 +765,31 @@ VkPipelineShaderStageCreateInfo init::PipelineShaderStageCreateInfo(VkShaderStag
return info;
}
VkBool32 Seele::Vulkan::debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char* layerPrefix, const char* msg, void* userDataManager) {
#pragma warning(disable : 4100)
VkBool32 Seele::Vulkan::debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char *layerPrefix, const char *msg, void *userDataManager)
{
std::cerr << layerPrefix << ": " << msg << std::endl;
return VK_FALSE;
}
VkResult Seele::Vulkan::CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback) {
#pragma warning(default : 4100)
VkResult Seele::Vulkan::CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback)
{
auto func = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");
if (func != nullptr) {
if (func != nullptr)
{
return func(instance, pCreateInfo, pAllocator, pCallback);
}
else {
else
{
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
}
void Seele::Vulkan::DestroyDebugReportCallbackEXT(VkInstance instance, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT pCallback)
void Seele::Vulkan::DestroyDebugReportCallbackEXT(VkInstance instance, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT pCallback)
{
auto func = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT");
if (func != nullptr) {
if (func != nullptr)
{
func(instance, pCallback, pAllocator);
}
}
+235 -238
View File
@@ -4,302 +4,299 @@
namespace Seele
{
namespace Vulkan
{
VkBool32 debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char* layerPrefix, const char* msg, void* userData);
namespace Vulkan
{
VkBool32 debugCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t obj, size_t location, int32_t code, const char *layerPrefix, const char *msg, void *userData);
VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback);
void DestroyDebugReportCallbackEXT(VkInstance instance, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT pCallback);
VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pCallback);
void DestroyDebugReportCallbackEXT(VkInstance instance, const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT pCallback);
namespace init
{
VkApplicationInfo ApplicationInfo(
const char* appName,
uint32_t appVersion,
const char* engineName,
uint32_t engineVersion,
uint32_t apiVersion);
namespace init
{
VkApplicationInfo ApplicationInfo(
const char *appName,
uint32_t appVersion,
const char *engineName,
uint32_t engineVersion,
uint32_t apiVersion);
VkInstanceCreateInfo InstanceCreateInfo(
VkApplicationInfo* appInfo,
const Array<const char*>& extensions,
const Array<const char*>& layers);
VkInstanceCreateInfo InstanceCreateInfo(
VkApplicationInfo *appInfo,
const Array<const char *> &extensions,
const Array<const char *> &layers);
VkDebugReportCallbackCreateInfoEXT DebugReportCallbackCreateInfo(
VkDebugReportFlagsEXT flags);
VkDebugReportCallbackCreateInfoEXT DebugReportCallbackCreateInfo(
VkDebugReportFlagsEXT flags);
VkDeviceQueueCreateInfo DeviceQueueCreateInfo(
int queueFamilyIndex,
int queueCount);
VkDeviceQueueCreateInfo DeviceQueueCreateInfo(
int queueFamilyIndex,
int queueCount);
VkDeviceQueueCreateInfo DeviceQueueCreateInfo(
int queueFamilyIndex,
int queueCount,
float* queuePriority);
VkDeviceQueueCreateInfo DeviceQueueCreateInfo(
int queueFamilyIndex,
int queueCount,
float *queuePriority);
VkDeviceCreateInfo DeviceCreateInfo(
VkDeviceQueueCreateInfo* queueInfos,
uint32_t queueCount,
VkPhysicalDeviceFeatures* features,
const char* const* deviceExtensions,
uint32_t deviceExtensionCount,
const char* const* layers,
uint32_t layerCount);
VkDeviceCreateInfo DeviceCreateInfo(
VkDeviceQueueCreateInfo *queueInfos,
uint32_t queueCount,
VkPhysicalDeviceFeatures *features,
const char *const *deviceExtensions,
uint32_t deviceExtensionCount,
const char *const *layers,
uint32_t layerCount);
VkDeviceCreateInfo DeviceCreateInfo(
VkDeviceQueueCreateInfo* queueInfos,
uint32_t queueCount,
VkPhysicalDeviceFeatures* features);
VkDeviceCreateInfo DeviceCreateInfo(
VkDeviceQueueCreateInfo *queueInfos,
uint32_t queueCount,
VkPhysicalDeviceFeatures *features);
VkSwapchainCreateInfoKHR SwapchainCreateInfo(
VkSurfaceKHR surface,
uint32_t minImageCount,
VkFormat imageFormat,
VkColorSpaceKHR colorSpace,
VkExtent2D extent,
uint32_t arrayLayers,
VkImageUsageFlags usage,
VkSurfaceTransformFlagBitsKHR Transform,
VkCompositeAlphaFlagBitsKHR alpha,
VkPresentModeKHR presentMode,
VkBool32 clipped);
VkSwapchainCreateInfoKHR SwapchainCreateInfo(
VkSurfaceKHR surface,
uint32_t minImageCount,
VkFormat imageFormat,
VkColorSpaceKHR colorSpace,
VkExtent2D extent,
uint32_t arrayLayers,
VkImageUsageFlags usage,
VkSurfaceTransformFlagBitsKHR Transform,
VkCompositeAlphaFlagBitsKHR alpha,
VkPresentModeKHR presentMode,
VkBool32 clipped);
VkSwapchainCreateInfoKHR SwapchainCreateInfo(
VkSurfaceKHR surface,
uint32_t minImageCount,
VkFormat imageFormat,
VkColorSpaceKHR colorSpace,
uint32_t width,
uint32_t height,
uint32_t arrayLayers,
VkImageUsageFlags usage,
VkSurfaceTransformFlagBitsKHR Transform,
VkCompositeAlphaFlagBitsKHR alpha,
VkPresentModeKHR presentMode,
VkBool32 clipped);
VkSwapchainCreateInfoKHR SwapchainCreateInfo(
VkSurfaceKHR surface,
uint32_t minImageCount,
VkFormat imageFormat,
VkColorSpaceKHR colorSpace,
uint32_t width,
uint32_t height,
uint32_t arrayLayers,
VkImageUsageFlags usage,
VkSurfaceTransformFlagBitsKHR Transform,
VkCompositeAlphaFlagBitsKHR alpha,
VkPresentModeKHR presentMode,
VkBool32 clipped);
VkFramebufferCreateInfo FramebufferCreateInfo(
VkRenderPass renderPass,
uint32_t attachmentCount,
VkImageView* attachments,
uint32_t width,
uint32_t height,
uint32_t layers);
VkFramebufferCreateInfo FramebufferCreateInfo(
VkRenderPass renderPass,
uint32_t attachmentCount,
VkImageView *attachments,
uint32_t width,
uint32_t height,
uint32_t layers);
VkAttachmentDescription AttachmentDescription(
VkFormat format,
VkSampleCountFlagBits sample,
VkAttachmentLoadOp loadOp,
VkAttachmentStoreOp storeOp,
VkAttachmentLoadOp stencilLoadOp,
VkAttachmentStoreOp stencilStoreOp,
VkImageLayout imageLayout,
VkImageLayout finalLayout);
VkAttachmentDescription AttachmentDescription(
VkFormat format,
VkSampleCountFlagBits sample,
VkAttachmentLoadOp loadOp,
VkAttachmentStoreOp storeOp,
VkAttachmentLoadOp stencilLoadOp,
VkAttachmentStoreOp stencilStoreOp,
VkImageLayout imageLayout,
VkImageLayout finalLayout);
VkSubpassDescription SubpassDescription(
VkPipelineBindPoint bindPoint,
uint32_t colorAttachmentCount,
VkAttachmentReference* colorReference,
uint32_t depthAttachmentCount = 0,
VkAttachmentReference* depthReference = nullptr,
uint32_t inputAttachmentCount = 0,
VkAttachmentReference* inputReference = nullptr,
uint32_t resolveAttachmentCount = 0,
VkAttachmentReference* resolveReference = nullptr,
uint32_t preserveAttachmentCount = 0,
VkAttachmentReference* preserveReference = nullptr);
VkSubpassDescription SubpassDescription(
VkPipelineBindPoint bindPoint,
uint32_t colorAttachmentCount,
VkAttachmentReference *colorReference,
VkAttachmentReference *depthReference = nullptr,
uint32_t inputAttachmentCount = 0,
VkAttachmentReference *inputReference = nullptr,
VkAttachmentReference *resolveReference = nullptr,
uint32_t preserveAttachmentCount = 0,
uint32_t *preserveReference = nullptr);
VkRenderPassCreateInfo RenderPassCreateInfo(
uint32_t attachmentCount,
const VkAttachmentDescription* attachments,
uint32_t subpassCount,
const VkSubpassDescription* subpasses,
uint32_t dependencyCount,
const VkSubpassDependency* subpassDependencies);
VkRenderPassCreateInfo RenderPassCreateInfo(
uint32_t attachmentCount,
const VkAttachmentDescription *attachments,
uint32_t subpassCount,
const VkSubpassDescription *subpasses,
uint32_t dependencyCount,
const VkSubpassDependency *subpassDependencies);
VkMemoryAllocateInfo MemoryAllocateInfo();
VkMemoryAllocateInfo MemoryAllocateInfo();
VkCommandBufferAllocateInfo CommandBufferAllocateInfo(
VkCommandPool cmdPool,
VkCommandBufferLevel level,
uint32_t bufferCount);
VkCommandBufferAllocateInfo CommandBufferAllocateInfo(
VkCommandPool cmdPool,
VkCommandBufferLevel level,
uint32_t bufferCount);
VkCommandPoolCreateInfo CommandPoolCreateInfo();
VkCommandPoolCreateInfo CommandPoolCreateInfo();
VkCommandBufferBeginInfo CommandBufferBeginInfo();
VkCommandBufferBeginInfo CommandBufferBeginInfo();
VkCommandBufferInheritanceInfo CommandBufferInheritanceInfo();
VkCommandBufferInheritanceInfo CommandBufferInheritanceInfo();
VkRenderPassBeginInfo RenderPassBeginInfo();
VkRenderPassBeginInfo RenderPassBeginInfo();
VkRenderPassCreateInfo RenderPassCreateInfo();
VkRenderPassCreateInfo RenderPassCreateInfo();
VkImageMemoryBarrier ImageMemoryBarrier(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, uint32_t srcQueue = VK_QUEUE_FAMILY_IGNORED, uint32_t dstQueue = VK_QUEUE_FAMILY_IGNORED);
VkImageMemoryBarrier ImageMemoryBarrier();
VkImageMemoryBarrier ImageMemoryBarrier(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, uint32_t srcQueue = VK_QUEUE_FAMILY_IGNORED, uint32_t dstQueue = VK_QUEUE_FAMILY_IGNORED);
VkImageMemoryBarrier ImageMemoryBarrier();
VkBufferMemoryBarrier BufferMemoryBarrier();
VkBufferMemoryBarrier BufferMemoryBarrier();
VkMemoryBarrier MemoryBarrier();
VkMemoryBarrier MemoryBarrier();
VkImageCreateInfo ImageCreateInfo();
VkImageCreateInfo ImageCreateInfo();
VkSamplerCreateInfo SamplerCreateInfo();
VkSamplerCreateInfo SamplerCreateInfo();
VkImageViewCreateInfo ImageViewCreateInfo();
VkImageViewCreateInfo ImageViewCreateInfo();
VkSemaphoreCreateInfo SemaphoreCreateInfo();
VkSemaphoreCreateInfo SemaphoreCreateInfo();
VkFenceCreateInfo FenceCreateInfo(
VkFenceCreateFlags flags);
VkFenceCreateInfo FenceCreateInfo(
VkFenceCreateFlags flags);
VkEventCreateInfo EventCreateInfo();
VkEventCreateInfo EventCreateInfo();
VkSubmitInfo SubmitInfo();
VkSubmitInfo SubmitInfo();
VkImageSubresourceRange ImageSubresourceRange(
VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT,
uint32_t startMip = 0);
VkImageSubresourceRange ImageSubresourceRange(
VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT,
uint32_t startMip = 0);
VkViewport Viewport(
float width,
float height,
float minDepth,
float maxDepth);
VkViewport Viewport(
float width,
float height,
float minDepth,
float maxDepth);
VkRect2D Rect2D(
int32_t width,
int32_t height,
int32_t offsetX,
int32_t offsetY);
VkRect2D Rect2D(
int32_t width,
int32_t height,
int32_t offsetX,
int32_t offsetY);
VkBufferCreateInfo BufferCreateInfo();
VkBufferCreateInfo BufferCreateInfo();
VkBufferCreateInfo BufferCreateInfo(
VkBufferUsageFlags usage,
VkDeviceSize size);
VkBufferCreateInfo BufferCreateInfo(
VkBufferUsageFlags usage,
VkDeviceSize size);
VkDescriptorPoolCreateInfo DescriptorPoolCreateInfo(
uint32_t poolSizeCount,
VkDescriptorPoolSize* pPoolSizes,
uint32_t maxSets);
VkDescriptorPoolCreateInfo DescriptorPoolCreateInfo(
uint32_t poolSizeCount,
VkDescriptorPoolSize *pPoolSizes,
uint32_t maxSets);
VkDescriptorPoolSize DescriptorPoolSize(
VkDescriptorType type,
uint32_t descriptorCount);
VkDescriptorPoolSize DescriptorPoolSize(
VkDescriptorType type,
uint32_t descriptorCount);
VkDescriptorSetLayoutBinding DescriptorSetLayoutBinding(
VkDescriptorType type,
VkShaderStageFlags stageFlags,
uint32_t binding,
uint32_t count);
VkDescriptorSetLayoutBinding DescriptorSetLayoutBinding(
VkDescriptorType type,
VkShaderStageFlags stageFlags,
uint32_t binding,
uint32_t count);
VkDescriptorSetLayoutCreateInfo DescriptorSetLayoutCreateInfo(
const VkDescriptorSetLayoutBinding* pBindings,
uint32_t bindingCount);
VkDescriptorSetLayoutCreateInfo DescriptorSetLayoutCreateInfo(
const VkDescriptorSetLayoutBinding *pBindings,
uint32_t bindingCount);
VkPipelineLayoutCreateInfo PipelineLayoutCreateInfo(
const VkDescriptorSetLayout* pSetLayouts,
uint32_t setLayoutCount);
VkPipelineLayoutCreateInfo PipelineLayoutCreateInfo(
const VkDescriptorSetLayout *pSetLayouts,
uint32_t setLayoutCount);
VkDescriptorSetAllocateInfo DescriptorSetAllocateInfo(
VkDescriptorPool descriptorPool,
const VkDescriptorSetLayout* pSetLayouts,
uint32_t descriptorSetCount);
VkDescriptorSetAllocateInfo DescriptorSetAllocateInfo(
VkDescriptorPool descriptorPool,
const VkDescriptorSetLayout *pSetLayouts,
uint32_t descriptorSetCount);
VkDescriptorBufferInfo DescriptorBufferInfo(
VkBuffer buffer,
VkDeviceSize offset,
VkDeviceSize range);
VkDescriptorImageInfo DescriptorImageInfo(
VkSampler sampler,
VkImageView imageView,
VkImageLayout imageLayout);
VkDescriptorBufferInfo DescriptorBufferInfo(
VkBuffer buffer,
VkDeviceSize offset,
VkDeviceSize range);
VkDescriptorImageInfo DescriptorImageInfo(
VkSampler sampler,
VkImageView imageView,
VkImageLayout imageLayout);
VkWriteDescriptorSet WriteDescriptorSet(
VkDescriptorSet dstSet,
VkDescriptorType type,
uint32_t binding,
VkDescriptorBufferInfo* bufferInfo);
VkWriteDescriptorSet WriteDescriptorSet(
VkDescriptorSet dstSet,
VkDescriptorType type,
uint32_t binding,
VkDescriptorBufferInfo *bufferInfo);
VkWriteDescriptorSet WriteDescriptorSet(
VkDescriptorSet dstSet,
VkDescriptorType type,
uint32_t binding,
VkDescriptorImageInfo* bufferInfo);
VkWriteDescriptorSet WriteDescriptorSet(
VkDescriptorSet dstSet,
VkDescriptorType type,
uint32_t binding,
VkDescriptorImageInfo *bufferInfo);
VkVertexInputBindingDescription VertexInputBindingDescription(
uint32_t binding,
uint32_t stride,
VkVertexInputRate inputRate);
VkVertexInputBindingDescription VertexInputBindingDescription(
uint32_t binding,
uint32_t stride,
VkVertexInputRate inputRate);
VkVertexInputAttributeDescription VertexInputAttributeDescription(
uint32_t binding,
uint32_t location,
VkFormat format,
uint32_t offset);
VkVertexInputAttributeDescription VertexInputAttributeDescription(
uint32_t binding,
uint32_t location,
VkFormat format,
uint32_t offset);
VkPipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo();
VkPipelineVertexInputStateCreateInfo PipelineVertexInputStateCreateInfo();
VkPipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo(
VkPrimitiveTopology topology,
VkPipelineInputAssemblyStateCreateFlags flags,
VkBool32 primitiveRestartEnable);
VkPipelineInputAssemblyStateCreateInfo PipelineInputAssemblyStateCreateInfo(
VkPrimitiveTopology topology,
VkPipelineInputAssemblyStateCreateFlags flags,
VkBool32 primitiveRestartEnable);
VkPipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo(
VkPolygonMode polygonMode,
VkCullModeFlags cullMode,
VkFrontFace frontFace,
VkPipelineRasterizationStateCreateFlags flags);
VkPipelineRasterizationStateCreateInfo PipelineRasterizationStateCreateInfo(
VkPolygonMode polygonMode,
VkCullModeFlags cullMode,
VkFrontFace frontFace,
VkPipelineRasterizationStateCreateFlags flags);
VkPipelineColorBlendAttachmentState PipelineColorBlendAttachmentState(
VkColorComponentFlags colorWriteMask,
VkBool32 blendEnable);
VkPipelineColorBlendAttachmentState PipelineColorBlendAttachmentState(
VkColorComponentFlags colorWriteMask,
VkBool32 blendEnable);
VkPipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo(
uint32_t attachmentCount,
const VkPipelineColorBlendAttachmentState *pAttachments);
VkPipelineColorBlendStateCreateInfo PipelineColorBlendStateCreateInfo(
uint32_t attachmentCount,
const VkPipelineColorBlendAttachmentState* pAttachments);
VkPipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo(
VkBool32 depthTestEnable,
VkBool32 depthWriteEnable,
VkCompareOp depthCompareOp);
VkPipelineDepthStencilStateCreateInfo PipelineDepthStencilStateCreateInfo(
VkBool32 depthTestEnable,
VkBool32 depthWriteEnable,
VkCompareOp depthCompareOp);
VkPipelineViewportStateCreateInfo PipelineViewportStateCreateInfo(
uint32_t viewportCount,
uint32_t scissorCount,
VkPipelineViewportStateCreateFlags flags);
VkPipelineViewportStateCreateInfo PipelineViewportStateCreateInfo(
uint32_t viewportCount,
uint32_t scissorCount,
VkPipelineViewportStateCreateFlags flags);
VkPipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo(
VkSampleCountFlagBits rasterizationSamples,
VkPipelineMultisampleStateCreateFlags flags);
VkPipelineMultisampleStateCreateInfo PipelineMultisampleStateCreateInfo(
VkSampleCountFlagBits rasterizationSamples,
VkPipelineMultisampleStateCreateFlags flags);
VkPipelineDynamicStateCreateInfo PipelineDynamicStateCreateInfo(
const VkDynamicState *pDynamicStates,
uint32_t dynamicStateCount,
VkPipelineDynamicStateCreateFlags flags);
VkPipelineDynamicStateCreateInfo PipelineDynamicStateCreateInfo(
const VkDynamicState* pDynamicStates,
uint32_t dynamicStateCount,
VkPipelineDynamicStateCreateFlags flags);
VkPipelineTessellationStateCreateInfo PipelineTessellationStateCreateInfo(
uint32_t patchControlPoints);
VkPipelineTessellationStateCreateInfo PipelineTessellationStateCreateInfo(
uint32_t patchControlPoints);
VkGraphicsPipelineCreateInfo PipelineCreateInfo(
VkPipelineLayout layout,
VkRenderPass renderPass,
VkPipelineCreateFlags flags);
VkGraphicsPipelineCreateInfo PipelineCreateInfo(
VkPipelineLayout layout,
VkRenderPass renderPass,
VkPipelineCreateFlags flags);
VkComputePipelineCreateInfo ComputePipelineCreateInfo(
VkPipelineLayout layout,
VkPipelineCreateFlags flags);
VkComputePipelineCreateInfo ComputePipelineCreateInfo(
VkPipelineLayout layout,
VkPipelineCreateFlags flags);
VkPushConstantRange PushConstantRange(
VkShaderStageFlags stageFlags,
uint32_t size,
uint32_t offset);
VkPushConstantRange PushConstantRange(
VkShaderStageFlags stageFlags,
uint32_t size,
uint32_t offset);
VkPipelineShaderStageCreateInfo PipelineShaderStageCreateInfo(
VkShaderStageFlagBits stage,
VkShaderModule module,
const char* entryName);
}
}
}
VkPipelineShaderStageCreateInfo PipelineShaderStageCreateInfo(
VkShaderStageFlagBits stage,
VkShaderModule module,
const char *entryName);
} // namespace init
} // namespace Vulkan
} // namespace Seele
+47 -1
View File
@@ -1,11 +1,14 @@
#include "VulkanQueue.h"
#include "VulkanInitializer.h"
#include "VulkanGraphics.h"
#include "VulkanAllocator.h"
#include "VulkanCommandBuffer.h"
#include "VulkanGraphicsEnums.h"
using namespace Seele;
using namespace Seele::Vulkan;
Queue::Queue(PGraphics graphics, QueueType queueType, uint32 familyIndex, uint32 queueIndex)
Queue::Queue(PGraphics graphics, Gfx::QueueType queueType, uint32 familyIndex, uint32 queueIndex)
: familyIndex(familyIndex)
, graphics(graphics)
, queueType(queueType)
@@ -16,4 +19,47 @@ Queue::Queue(PGraphics graphics, QueueType queueType, uint32 familyIndex, uint32
Queue::~Queue()
{
}
void Queue::submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores, VkSemaphore* signalSemaphores)
{
assert(cmdBuffer->state == CmdBuffer::State::Ended);
PFence fence = cmdBuffer->fence;
assert(!fence->isSignaled());
const VkCommandBuffer cmdBuffers[] = {cmdBuffer->handle};
VkSubmitInfo submitInfo =
init::SubmitInfo();
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = cmdBuffers;
submitInfo.signalSemaphoreCount = static_cast<uint32>(numSignalSemaphores);
submitInfo.pSignalSemaphores = signalSemaphores;
Array<VkSemaphore> waitSemaphores;
if(cmdBuffer->waitSemaphores.size() > 0)
{
for(PSemaphore semaphore : cmdBuffer->waitSemaphores)
{
waitSemaphores.add(semaphore->getHandle());
}
submitInfo.waitSemaphoreCount = static_cast<uint32>(cmdBuffer->waitSemaphores.size());
submitInfo.pWaitSemaphores = waitSemaphores.data();
submitInfo.pWaitDstStageMask = cmdBuffer->waitFlags.data();
}
VK_CHECK(vkQueueSubmit(queue, 1, &submitInfo, fence->getHandle()));
cmdBuffer->state = CmdBuffer::State::Submitted;
cmdBuffer->waitFlags.clear();
cmdBuffer->waitSemaphores.clear();
if(Gfx::waitIdleOnSubmit)
{
fence->wait(200 * 1000ull);
}
cmdBuffer->refreshFence();
graphics->getStagingManager()->clearPending();
}
+30 -29
View File
@@ -3,34 +3,35 @@
namespace Seele
{
namespace Vulkan
namespace Vulkan
{
DECLARE_REF(CmdBuffer);
DECLARE_REF(Graphics);
class Queue
{
public:
Queue(PGraphics graphics, Gfx::QueueType queueType, uint32 familyIndex, uint32 queueIndex);
virtual ~Queue();
void submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores = 0, VkSemaphore *signalSemaphore = nullptr);
inline void submitCommandBuffer(PCmdBuffer cmdBuffer, VkSemaphore signalSemaphore)
{
DECLARE_REF(CmdBuffer);
DECLARE_REF(Graphics);
class Queue
{
public:
Queue(PGraphics graphics, QueueType queueType, uint32 familyIndex, uint32 queueIndex);
virtual ~Queue();
void submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores = 0, VkSemaphore* signalSemaphore = nullptr);
inline void submitCommandBuffer(PCmdBuffer cmdBuffer, VkSemaphore signalSemaphore)
{
submitCommandBuffer(cmdBuffer, 1, &signalSemaphore);
}
uint32 getFamilyIndex() const
{
return familyIndex;
}
inline VkQueue getHandle() const
{
return queue;
}
private:
PGraphics graphics;
VkQueue queue;
uint32 familyIndex;
QueueType queueType;
};
DEFINE_REF(Queue)
submitCommandBuffer(cmdBuffer, 1, &signalSemaphore);
}
}
uint32 getFamilyIndex() const
{
return familyIndex;
}
inline VkQueue getHandle() const
{
return queue;
}
private:
PGraphics graphics;
VkQueue queue;
uint32 familyIndex;
Gfx::QueueType queueType;
};
DEFINE_REF(Queue)
} // namespace Vulkan
} // namespace Seele
@@ -0,0 +1,127 @@
#include "VulkanRenderPass.h"
#include "VulkanInitializer.h"
#include "VulkanGraphicsEnums.h"
#include "VulkanGraphics.h"
#include "VulkanFramebuffer.h"
using namespace Seele;
using namespace Seele::Vulkan;
RenderPass::RenderPass(PGraphics graphics, Gfx::PRenderTargetLayout layout)
: layout(layout), graphics(graphics)
{
Array<VkAttachmentDescription> attachments;
Array<VkAttachmentReference> inputRefs;
Array<VkAttachmentReference> colorRefs;
VkAttachmentReference depthRef;
uint32 attachmentCounter = 0;
for (auto inputAttachment : layout->inputAttachments)
{
PTexture2D image = inputAttachment->getTexture().cast<Texture2D>();
VkAttachmentDescription desc = attachments.add();
desc.flags = 0;
desc.format = cast(image->getFormat());
desc.storeOp = cast(inputAttachment->getStoreOp());
desc.loadOp = cast(inputAttachment->getLoadOp());
desc.stencilStoreOp = cast(inputAttachment->getStencilStoreOp());
desc.stencilLoadOp = cast(inputAttachment->getStencilLoadOp());
desc.initialLayout = image->isDepthStencil() ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
desc.finalLayout = desc.initialLayout;
VkAttachmentReference &ref = inputRefs.add();
ref.layout = desc.initialLayout;
ref.attachment = attachmentCounter;
attachmentCounter++;
}
for (auto colorAttachment : layout->colorAttachments)
{
PTexture2D image = colorAttachment->getTexture().cast<Texture2D>();
VkAttachmentDescription desc = attachments.add();
desc.flags = 0;
desc.format = cast(image->getFormat());
desc.storeOp = cast(colorAttachment->getStoreOp());
desc.loadOp = cast(colorAttachment->getLoadOp());
desc.stencilStoreOp = cast(colorAttachment->getStencilStoreOp());
desc.stencilLoadOp = cast(colorAttachment->getStencilLoadOp());
desc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
desc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentReference &ref = colorRefs.add();
ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
ref.attachment = attachmentCounter;
attachmentCounter++;
}
if (layout->depthAttachment != nullptr)
{
PTexture2D image = layout->depthAttachment->getTexture().cast<Texture2D>();
VkAttachmentDescription desc = attachments.add();
desc.flags = 0;
desc.format = cast(image->getFormat());
desc.storeOp = cast(layout->depthAttachment->getStoreOp());
desc.loadOp = cast(layout->depthAttachment->getLoadOp());
desc.stencilStoreOp = cast(layout->depthAttachment->getStencilStoreOp());
desc.stencilLoadOp = cast(layout->depthAttachment->getStencilLoadOp());
desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkAttachmentReference &ref = depthRef;
ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
ref.attachment = attachmentCounter;
attachmentCounter++;
}
VkSubpassDescription subPassDesc =
init::SubpassDescription(
VK_PIPELINE_BIND_POINT_GRAPHICS,
colorRefs.size(),
colorRefs.data(),
&depthRef,
inputRefs.size(),
inputRefs.data());
VkSubpassDependency dependency = {};
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0;
dependency.srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
dependency.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
VkRenderPassCreateInfo info =
init::RenderPassCreateInfo(
attachments.size(),
attachments.data(),
1,
&subPassDesc,
1,
&dependency);
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)
{
PTexture2D tex = inputAttachment->getTexture().cast<Texture2D>();
description.inputAttachments[description.numInputAttachments++] = tex->getView();
}
for(auto colorAttachment : layout->colorAttachments)
{
PTexture2D tex = colorAttachment->getTexture().cast<Texture2D>();
description.colorAttachments[description.numColorAttachments++] = tex->getView();
}
if(layout->depthAttachment != nullptr)
{
PTexture2D tex = layout->depthAttachment->getTexture().cast<Texture2D>();
description.depthAttachment = tex->getView();
}
return memCrc32(&description, sizeof(FramebufferDescription));
}
+41 -34
View File
@@ -2,39 +2,46 @@
namespace Seele
{
namespace Vulkan
namespace Vulkan
{
class RenderPass : public Gfx::RenderPass
{
public:
RenderPass(PGraphics graphics, Gfx::PRenderTargetLayout layout);
virtual ~RenderPass();
uint32 getFramebufferHash();
inline VkRenderPass getHandle() const
{
class RenderPass
{
public:
RenderPass();
virtual ~RenderPass();
inline VkRenderPass getHandle() const
{
return renderPass;
}
inline uint32 getClearValueCount() const
{
return clearValues.size();
}
inline VkClearValue* getClearValues() const
{
return clearValues.data();
}
inline VkRect2D getRenderArea() const
{
return renderArea;
}
inline VkSubpassContents getSubpassContents() const
{
return subpassContents;
}
private:
VkRenderPass renderPass;
Array<VkClearValue> clearValues;
VkRect2D renderArea;
VkSubpassContents subpassContents;
};
DEFINE_REF(RenderPass);
return renderPass;
}
}
inline uint32 getClearValueCount() const
{
return clearValues.size();
}
inline VkClearValue *getClearValues() const
{
return clearValues.data();
}
inline VkRect2D getRenderArea() const
{
return renderArea;
}
inline VkSubpassContents getSubpassContents() const
{
return subpassContents;
}
inline Gfx::PRenderTargetLayout getLayout()
{
return layout;
}
private:
PGraphics graphics;
Gfx::PRenderTargetLayout layout;
VkRenderPass renderPass;
Array<VkClearValue> clearValues;
VkRect2D renderArea;
VkSubpassContents subpassContents;
};
DEFINE_REF(RenderPass);
} // namespace Vulkan
} // namespace Seele
+165 -59
View File
@@ -2,90 +2,196 @@
#include "VulkanGraphics.h"
#include "VulkanInitializer.h"
#include "VulkanGraphicsEnums.h"
#include "VulkanAllocator.h"
#include "VulkanCommandBuffer.h"
#include <math.h>
using namespace Seele;
using namespace Seele::Vulkan;
TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType, uint32 sizeX, uint32 sizeY, uint32 sizeZ,
bool bArray, uint32 arraySize, uint32 mipLevel,
Gfx::SeFormat format, uint32 samples, Gfx::SeImageUsageFlags usage)
: graphics(graphics)
, sizeX(sizeX)
, sizeY(sizeY)
, sizeZ(sizeZ)
, mipLevels(mipLevel)
, format(format)
, arrayCount(bArray ? arraySize : 1)
VkImageAspectFlags getAspectFromFormat(Gfx::SeFormat format)
{
PAllocator allocator = graphics->getAllocator();
VkImageCreateInfo info =
init::ImageCreateInfo();
info.extent.width = sizeX;
info.extent.height = sizeY;
info.extent.depth = sizeZ;
info.arrayLayers = arraySize;
info.format = cast(format);
switch (format)
{
case Gfx::SE_FORMAT_D16_UNORM:
return VK_IMAGE_ASPECT_DEPTH_BIT;
case Gfx::SE_FORMAT_D32_SFLOAT:
return VK_IMAGE_ASPECT_DEPTH_BIT;
case Gfx::SE_FORMAT_S8_UINT:
return VK_IMAGE_ASPECT_STENCIL_BIT;
case Gfx::SE_FORMAT_D16_UNORM_S8_UINT:
case Gfx::SE_FORMAT_D24_UNORM_S8_UINT:
case Gfx::SE_FORMAT_D32_SFLOAT_S8_UINT:
case Gfx::SE_FORMAT_X8_D24_UNORM_PACK32:
return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
default:
return VK_IMAGE_ASPECT_COLOR_BIT;
}
}
TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, uint32 sizeX, uint32 sizeY, uint32 sizeZ,
bool bArray, uint32 arraySize, uint32 mipLevel,
Gfx::SeFormat format, uint32 samples, Gfx::SeImageUsageFlags usage, Gfx::QueueType owner, VkImage existingImage)
: QueueOwnedResource(graphics, owner), graphics(graphics), sizeX(sizeX), sizeY(sizeY), sizeZ(sizeZ), mipLevels(mipLevel), format(format), samples(samples), usage(usage), arrayCount(bArray ? arraySize : 1), aspect(getAspectFromFormat(format))
{
if (existingImage == VK_NULL_HANDLE)
{
PAllocator allocator = graphics->getAllocator();
VkImageCreateInfo info =
init::ImageCreateInfo();
info.extent.width = sizeX;
info.extent.height = sizeY;
info.extent.depth = sizeZ;
info.arrayLayers = arraySize;
info.format = cast(format);
uint32 layerCount = 1;
switch (viewType)
{
case VK_IMAGE_VIEW_TYPE_1D:
case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
info.imageType = VK_IMAGE_TYPE_1D;
break;
case VK_IMAGE_VIEW_TYPE_2D:
case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
info.imageType = VK_IMAGE_TYPE_2D;
break;
case VK_IMAGE_VIEW_TYPE_3D:
info.imageType = VK_IMAGE_TYPE_3D;
break;
case VK_IMAGE_VIEW_TYPE_CUBE:
case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
info.imageType = VK_IMAGE_TYPE_2D;
layerCount = 6 * arrayCount;
break;
default:
break;
}
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
info.mipLevels = mipLevel;
info.arrayLayers = arrayCount * layerCount;
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
info.samples = (VkSampleCountFlagBits)samples;
info.tiling = VK_IMAGE_TILING_OPTIMAL;
info.usage = usage;
VK_CHECK(vkCreateImage(graphics->getDevice(), &info, nullptr, &image));
VkMemoryDedicatedRequirements memDedicatedRequirements;
memDedicatedRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
memDedicatedRequirements.pNext = nullptr;
VkImageMemoryRequirementsInfo2 reqInfo;
reqInfo.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2;
reqInfo.pNext = nullptr;
reqInfo.image = image;
VkMemoryRequirements2 requirements;
requirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
requirements.pNext = &memDedicatedRequirements;
vkGetImageMemoryRequirements2(graphics->getDevice(), &reqInfo, &requirements);
allocation = allocator->allocate(requirements, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, image);
vkBindImageMemory(graphics->getDevice(), image, allocation->getHandle(), allocation->getOffset());
}
VkImageViewCreateInfo viewInfo =
init::ImageViewCreateInfo();
viewInfo.subresourceRange = init::ImageSubresourceRange(aspect);
viewInfo.viewType = viewType;
uint32 layerCount = 1;
switch (viewType)
{
case VK_IMAGE_VIEW_TYPE_1D:
case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
info.imageType = VK_IMAGE_TYPE_1D;
break;
case VK_IMAGE_VIEW_TYPE_2D:
case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
info.imageType = VK_IMAGE_TYPE_2D;
break;
case VK_IMAGE_VIEW_TYPE_3D:
info.imageType = VK_IMAGE_TYPE_3D;
break;
case VK_IMAGE_VIEW_TYPE_CUBE:
info.imageType = VK_IMAGE_TYPE_2D;
layerCount = 6 * arrayCount;
break;
default:
break;
}
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
info.mipLevels = mipLevel;
info.arrayLayers = arrayCount * layerCount;
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
info.samples = (VkSampleCountFlagBits)samples;
info.tiling = VK_IMAGE_TILING_OPTIMAL;
info.usage = usage;
VK_CHECK(vkCreateImage(graphics->getDevice(), &info, nullptr, &image));
viewInfo.image = image;
viewInfo.format = cast(format);
viewInfo.subresourceRange.layerCount = layerCount;
viewInfo.subresourceRange.layerCount = (viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY || viewType == VK_IMAGE_VIEW_TYPE_CUBE) ? 6 : 1;
viewInfo.subresourceRange.levelCount = mipLevels;
VK_CHECK(vkCreateImageView(graphics->getDevice(), &viewInfo, nullptr, &defaultView));
}
TextureBase::~TextureBase()
TextureHandle::~TextureHandle()
{
vkDestroyImageView(graphics->getDevice(), defaultView, nullptr);
vkDestroyImage(graphics->getDevice(), image, nullptr);
}
Texture2D::Texture2D(PGraphics graphics, uint32 sizeX, uint32 sizeY,
bool bArray, uint32 arraySize, uint32 mipLevels,
Gfx::SeFormat format, uint32 samples, Gfx::SeImageUsageFlags usage)
{
textureHandle = new TextureBase(graphics, bArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
sizeX, sizeY, 1, bArray, arraySize, mipLevels, format, samples, usage);
void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
VkImageMemoryBarrier imageBarrier =
init::ImageMemoryBarrier();
imageBarrier.image = image;
imageBarrier.oldLayout = layout;
imageBarrier.newLayout = layout;
imageBarrier.subresourceRange = init::ImageSubresourceRange(aspect);
PCommandBufferManager sourceManager = getCommands();
PCommandBufferManager dstManager = nullptr;
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
QueueFamilyMapping mapping = graphics->getFamilyMapping();
imageBarrier.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(currentOwner);
imageBarrier.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner);
if (currentOwner == Gfx::QueueType::TRANSFER || currentOwner == Gfx::QueueType::DEDICATED_TRANSFER)
{
imageBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
}
else if (currentOwner == Gfx::QueueType::COMPUTE)
{
imageBarrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
}
else if (currentOwner == Gfx::QueueType::GRAPHICS)
{
imageBarrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
}
if (newOwner == Gfx::QueueType::TRANSFER)
{
imageBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstManager = graphics->getTransferCommands();
}
else if(currentOwner == Gfx::QueueType::DEDICATED_TRANSFER)
{
imageBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstManager = graphics->getDedicatedTransferCommands();
}
else if (newOwner == Gfx::QueueType::COMPUTE)
{
imageBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
dstManager = graphics->getComputeCommands();
}
else if (newOwner == Gfx::QueueType::GRAPHICS)
{
imageBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
dstManager = graphics->getGraphicsCommands();
}
VkCommandBuffer sourceCmd = sourceManager->getCommands()->getHandle();
VkCommandBuffer destCmd = dstManager->getCommands()->getHandle();
vkCmdPipelineBarrier(sourceCmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
vkCmdPipelineBarrier(destCmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
sourceManager->submitCommands();
cachedCmdBufferManager = dstManager;
}
void TextureBase::changeLayout(VkImageLayout newLayout)
{
VkImageMemoryBarrier barrier =
init::ImageMemoryBarrier(
textureHandle->image,
textureHandle->layout,
newLayout);
vkCmdPipelineBarrier(textureHandle->getCommands()->getCommands()->getHandle(),
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
0, 0, nullptr, 0, nullptr, 1, &barrier);
textureHandle->layout = newLayout;
}
Texture2D::Texture2D(PGraphics graphics, uint32 sizeX, uint32 sizeY,
bool bArray, uint32 arraySize, uint32 mipLevels, Gfx::SeFormat format,
uint32 samples, Gfx::SeImageUsageFlags usage, Gfx::QueueType owner, VkImage existingImage)
{
textureHandle = new TextureHandle(graphics, bArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
sizeX, sizeY, 1, bArray, arraySize, mipLevels, format, samples, usage, owner, existingImage);
}
Texture2D::~Texture2D()
{
}
@@ -0,0 +1,243 @@
#include "VulkanGraphicsResources.h"
#include "VulkanGraphics.h"
#include "VulkanInitializer.h"
#include "VulkanGraphicsEnums.h"
#include "VulkanCommandBuffer.h"
#include <glfw/glfw3.h>
using namespace Seele;
using namespace Seele::Vulkan;
Window::Window(PGraphics graphics, const WindowCreateInfo &createInfo)
: Gfx::Window(createInfo), graphics(graphics), instance(graphics->getInstance())
{
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWwindow *handle = glfwCreateWindow(createInfo.width, createInfo.height, createInfo.title, createInfo.bFullscreen ? glfwGetPrimaryMonitor() : nullptr, nullptr);
windowHandle = handle;
//TODO: callbacks
glfwCreateWindowSurface(instance, handle, nullptr, &surface);
createSwapchain();
}
Window::~Window()
{
vkDestroySurfaceKHR(instance, surface, nullptr);
glfwDestroyWindow(static_cast<GLFWwindow *>(windowHandle));
}
void Window::beginFrame()
{
advanceBackBuffer();
}
void Window::endFrame()
{
present();
}
void Window::onWindowCloseEvent()
{
}
Gfx::PTexture2D Window::getBackBuffer()
{
return backBufferImages[currentImageIndex];
}
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;
VkImageMemoryBarrier barrier =
init::ImageMemoryBarrier(
backBufferImages[currentImageIndex]->getHandle(),
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands();
vkCmdPipelineBarrier(cmdBuffer->getHandle(),
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
0, 0, nullptr, 0, nullptr, 1, &barrier);
cmdBuffer->addWaitSemaphore(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, imageAcquiredSemaphore);
graphics->getGraphicsCommands()->submitCommands();
}
void Window::recreateSwapchain(const WindowCreateInfo &windowInfo)
{
destroySwapchain();
sizeX = windowInfo.width;
sizeY = windowInfo.height;
pixelFormat = cast(windowInfo.pixelFormat);
bFullscreen = windowInfo.bFullscreen;
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();
}
void Window::present()
{
backBufferImages[currentImageIndex]->changeLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
graphics->getGraphicsCommands()->submitCommands(renderFinished[currentImageIndex]);
VkSemaphore renderFinishedHandle = renderFinished[currentImageIndex]->getHandle();
VkPresentInfoKHR info;
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
info.pNext = nullptr;
info.swapchainCount = 1;
info.pSwapchains = &swapchain;
info.pImageIndices = (uint32 *)&currentImageIndex;
info.pResults = 0;
info.waitSemaphoreCount = 1;
info.pWaitSemaphores = &renderFinishedHandle;
VkResult presentResult = VK_ERROR_OUT_OF_DATE_KHR;
// Trial and error
while (presentResult != VK_SUCCESS)
{
presentResult = vkQueuePresentKHR(graphics->getGraphicsCommands()->getQueue()->getHandle(), &info);
}
}
void Window::createSwapchain()
{
VkSurfaceCapabilitiesKHR surfProperties;
VK_CHECK(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(graphics->getPhysicalDevice(), surface, &surfProperties));
uint32 desiredNumBuffers = Gfx::numFramesBuffered;
VkExtent2D extent;
extent.width = sizeX;
extent.height = sizeY;
VkSwapchainCreateInfoKHR swapchainInfo =
init::SwapchainCreateInfo(
surface,
desiredNumBuffers,
surfaceFormat.format,
surfaceFormat.colorSpace,
extent,
1,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
presentMode,
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()));
PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands();
for (uint32 i = 0; i < numSwapchainImages; ++i)
{
imageAcquired[i] = new Semaphore(graphics);
renderFinished[i] = new Semaphore(graphics);
backBufferImages[i] = new Texture2D(graphics, sizeX, sizeY, false, 1, 1,
cast(surfaceFormat.format), 1, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
Gfx::QueueType::GRAPHICS, swapchainImages[i]);
VkClearColorValue clearColor;
std::memset(&clearColor, 0, sizeof(VkClearColorValue));
backBufferImages[i]->changeLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkImageSubresourceRange range = init::ImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT);
vkCmdClearColorImage(cmdBuffer->getHandle(), backBufferImages[i]->getHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
backBufferImages[i]->changeLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
}
graphics->getGraphicsCommands()->submitCommands();
currentImageIndex = -1;
}
void Window::destroySwapchain()
{
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)
{
}
Viewport::~Viewport()
{
}
-35
View File
@@ -1,35 +0,0 @@
#include "Window.h"
#include "SceneView.h"
using namespace Seele;
Window::Window(const WindowCreateInfo& createInfo, Gfx::PGraphics graphics)
: width(createInfo.width)
, height(createInfo.height)
, graphics(graphics)
{
center = new Section();
center->resizeArea(Rect(1, 1, 0, 0));
center->addView(new SceneView(graphics));
windowHandle = graphics->createWindow(createInfo);
}
Window::~Window()
{
}
void Window::onWindowCloseEvent()
{
}
void Window::beginFrame()
{
graphics->beginFrame(windowHandle);
center->beginFrame();
}
void Window::endFrame()
{
graphics->endFrame(windowHandle);
}
-69
View File
@@ -1,69 +0,0 @@
#pragma once
#include "GraphicsResources.h"
#include "View.h"
namespace Seele {
// A window is divided into 5 sections, using a border layout
// +--------------TOP------------------+
// | |
// L R
// E I
// F CENTER G
// T H
// | T
// +-------------BOTTOM----------------+
// In every section, there can be any number
// of views, when there are multiple, they stack to tabs
class Section
{
public:
Section()
{}
void resizeArea(Rect area)
{
this->area = area;
}
void beginFrame()
{
views[0]->beginFrame();
}
void endFrame()
{
views[0]->endFrame();
}
void addView(PView view)
{
view->applyArea(area);
views.add(view);
}
void clearViews(PView view)
{
views.clear();
}
void removeView(PView view)
{
views.remove(views.find(view));
}
private:
Rect area;
Array<PView> views;
};
DEFINE_REF(Section)
class Gfx::Graphics;
class Window
{
public:
Window(const WindowCreateInfo& createInfo, Gfx::PGraphics graphics);
~Window();
void onWindowCloseEvent();
void beginFrame();
void endFrame();
private:
void* windowHandle;
PSection center;
uint32 width;
uint32 height;
Gfx::PGraphics graphics;
};
DEFINE_REF(Window)
}
+14 -2
View File
@@ -6,15 +6,27 @@ Seele::WindowManager::WindowManager()
graphics = new Vulkan::Graphics();
GraphicsInitializer initializer;
graphics->init(initializer);
TextureCreateInfo info;
info.width = 4096;
info.height = 4096;
Gfx::PTexture2D testTexture = graphics->createTexture2D(info);
BulkResourceData resourceData;
resourceData.size = 4096;
resourceData.data = new uint8[4096];
for (int i = 0; i < 4096; ++i)
{
resourceData.data[i] = (uint8)i;
}
Gfx::PUniformBuffer testUniform = graphics->createUniformBuffer(resourceData);
}
Seele::WindowManager::~WindowManager()
{
}
void Seele::WindowManager::addWindow(const WindowCreateInfo& createInfo)
void Seele::WindowManager::addWindow(const WindowCreateInfo &createInfo)
{
PWindow window = new Window(createInfo, graphics);
Gfx::PWindow window = graphics->createWindow(createInfo);
windows.add(window);
}
+19 -18
View File
@@ -1,25 +1,26 @@
#pragma once
#include "GraphicsResources.h"
#include "Window.h"
#include "Graphics.h"
#include "Containers/Array.h"
namespace Seele
{
class WindowManager
class WindowManager
{
public:
WindowManager();
~WindowManager();
void addWindow(const WindowCreateInfo &createInfo);
void beginFrame();
void endFrame();
inline bool isActive() const
{
public:
WindowManager();
~WindowManager();
void addWindow(const WindowCreateInfo& createInfo);
void beginFrame();
void endFrame();
inline bool isActive() const
{
return windows.size();
}
private:
Array<PWindow> windows;
Gfx::PGraphics graphics;
};
DEFINE_REF(WindowManager);
}
return windows.size();
}
private:
Array<Gfx::PWindow> windows;
Gfx::PGraphics graphics;
};
DEFINE_REF(WindowManager);
} // namespace Seele