Provisional light culling

This commit is contained in:
Dynamitos
2021-05-10 23:57:55 +02:00
parent 0cf13bcff5
commit e00b382d4a
41 changed files with 1072 additions and 330 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ struct ComputeShaderInput
uint groupIndex : SV_GroupIndex; uint groupIndex : SV_GroupIndex;
}; };
layout(set = 0, binding = 0, std430) layout(set = 0, binding = 1, std430)
cbuffer DispatchParams cbuffer DispatchParams
{ {
uint3 numThreadGroups; uint3 numThreadGroups;
+11 -11
View File
@@ -8,10 +8,10 @@ import MATERIAL_IMPORT;
import PrimitiveSceneData; import PrimitiveSceneData;
import MaterialParameter; import MaterialParameter;
//layout(set = 0, binding = 2) layout(set = INDEX_LIGHT_ENV, binding = 1)
//StructuredBuffer<uint> lightIndexList; StructuredBuffer<uint> lightIndexList;
//layout(set = 0, binding = 3) layout(set = INDEX_LIGHT_ENV, binding = 2)
//RWTexture2D<uint2> lightGrid; RWTexture2D<uint2> lightGrid;
struct VertexStageOutput struct VertexStageOutput
@@ -56,20 +56,20 @@ float4 fragmentMain(
float3 result = float3(0, 0, 0); float3 result = float3(0, 0, 0);
for (int i = 0; i < gLightEnv.numDirectionalLights; i++) for (int i = 0; i < gLightEnv[0].numDirectionalLights; i++)
{ {
result += gLightEnv.directionalLights[i].illuminate(materialParams, brdf, viewDir); result += gLightEnv[0].directionalLights[i].illuminate(materialParams, brdf, viewDir);
} }
uint2 tileIndex = uint2(floor(materialParams.clipPosition.xy) / BLOCK_SIZE); uint2 tileIndex = uint2(floor(materialParams.clipPosition.xy) / BLOCK_SIZE);
//uint startOffset = lightGrid[tileIndex].x; uint startOffset = lightGrid[tileIndex].x;
//uint lightCount = lightGrid[tileIndex].y; uint lightCount = lightGrid[tileIndex].y;
for (int j = 0; j < gLightEnv.numPointLights; ++j) for (int j = 0; j < gLightEnv[0].numPointLights; ++j)
{ {
//uint lightIndex = lightIndexList[startOffset + j]; uint lightIndex = lightIndexList[startOffset + j];
PointLight pointLight = gLightEnv.pointLights[j]; PointLight pointLight = gLightEnv[0].pointLights[lightIndex];
result += pointLight.illuminate(materialParams, brdf, viewDir); result += pointLight.illuminate(materialParams, brdf, viewDir);
} }
+15 -14
View File
@@ -8,7 +8,7 @@ struct ComputeShaderInput
uint3 dispatchThreadID : SV_DispatchThreadID; uint3 dispatchThreadID : SV_DispatchThreadID;
uint groupIndex : SV_GroupIndex; uint groupIndex : SV_GroupIndex;
}; };
layout(binding = 0) layout(set = INDEX_VIEW_PARAMS, binding = 1)
cbuffer DispatchParams cbuffer DispatchParams
{ {
uint3 numThreadGroups; uint3 numThreadGroups;
@@ -17,23 +17,23 @@ cbuffer DispatchParams
uint pad1; uint pad1;
} }
layout(binding = 2) layout(set = INDEX_VIEW_PARAMS, binding = 2)
RWTexture2D depthTextureVS; Texture2D depthTextureVS;
layout(binding = 4) layout(set = INDEX_VIEW_PARAMS, binding = 3)
StructuredBuffer<Frustum> frustums; StructuredBuffer<Frustum> frustums;
layout(binding = 5) layout(set = INDEX_VIEW_PARAMS, binding = 4)
RWStructuredBuffer<uint> oLightIndexCounter; RWStructuredBuffer<uint> oLightIndexCounter;
layout(binding = 6) layout(set = INDEX_VIEW_PARAMS, binding = 5)
RWStructuredBuffer<uint> tLightIndexCounter; RWStructuredBuffer<uint> tLightIndexCounter;
layout(binding = 7) layout(set = INDEX_VIEW_PARAMS, binding = 6)
RWStructuredBuffer<uint> oLightIndexList; RWStructuredBuffer<uint> oLightIndexList;
layout(binding = 8) layout(set = INDEX_VIEW_PARAMS, binding = 7)
RWStructuredBuffer<uint> tLightIndexList; RWStructuredBuffer<uint> tLightIndexList;
layout(binding = 9) layout(set = INDEX_VIEW_PARAMS, binding = 8)
RWTexture2D<uint2> oLightGrid; RWTexture2D<uint2> oLightGrid;
layout(binding = 10) layout(set = INDEX_VIEW_PARAMS, binding = 9)
RWTexture2D<uint2> tLightGrid; RWTexture2D<uint2> tLightGrid;
groupshared uint uMinDepth; groupshared uint uMinDepth;
@@ -71,9 +71,10 @@ void tAppendLight(uint lightIndex)
} }
[numthreads(BLOCK_SIZE, BLOCK_SIZE, 1)] [numthreads(BLOCK_SIZE, BLOCK_SIZE, 1)]
[shader("compute")]
void cullLights(ComputeShaderInput in) void cullLights(ComputeShaderInput in)
{ {
int2 texCoord = in.dispatchThreadID.xy; int3 texCoord = int3(in.dispatchThreadID.xy, 0);
float fDepth = depthTextureVS.Load(texCoord).r; float fDepth = depthTextureVS.Load(texCoord).r;
uint uDepth = asuint(fDepth); uint uDepth = asuint(fDepth);
@@ -101,10 +102,10 @@ void cullLights(ComputeShaderInput in)
Plane minPlane = {float3(0, 0, -1), -minDepthVS}; Plane minPlane = {float3(0, 0, -1), -minDepthVS};
for ( uint i = in.groupIndex; i < lights.numPointLights; i += BLOCK_SIZE * BLOCK_SIZE ) for ( uint i = in.groupIndex; i < gLightEnv[0].numPointLights; i += BLOCK_SIZE * BLOCK_SIZE )
{ {
PointLight light = lights.pointLights[i]; PointLight light = gLightEnv[0].pointLights[i];
//if(light.insideFrustum(groupFrustum, nearClipVS, maxDepthVS)) //if(gLightEnv.insideFrustum(groupFrustum, nearClipVS, maxDepthVS))
{ {
//InterlockedAdd(tLightCount, 1, index); //InterlockedAdd(tLightCount, 1, index);
//if(index < 1024) //if(index < 1024)
+4 -10
View File
@@ -6,24 +6,18 @@ struct ViewParameter
{ {
float4x4 viewMatrix; float4x4 viewMatrix;
float4x4 projectionMatrix; float4x4 projectionMatrix;
float4x4 inverseProjection;
float2 screenDimensions;
float4 cameraPos_WS; float4 cameraPos_WS;
} }
layout(set = INDEX_VIEW_PARAMS, binding = 0, std430) layout(set = INDEX_VIEW_PARAMS, binding = 0, std430)
ConstantBuffer<ViewParameter> gViewParams; ConstantBuffer<ViewParameter> gViewParams;
struct ScreenToViewParams
{
float4x4 inverseProjection;
float2 screenDimensions;
}
layout(set = INDEX_VIEW_PARAMS, binding = 1, std430)
ConstantBuffer<ScreenToViewParams> gScreenToViewParams;
// Convert clip space coordinates to view space // Convert clip space coordinates to view space
float4 clipToView( float4 clip ) float4 clipToView( float4 clip )
{ {
// View space position. // View space position.
float4 view = mul( gScreenToViewParams.inverseProjection, clip ); float4 view = mul( gViewParams.inverseProjection, clip );
// Perspective projection. // Perspective projection.
view = view / view.w; view = view / view.w;
@@ -34,7 +28,7 @@ float4 clipToView( float4 clip )
float4 screenToView( float4 screen ) float4 screenToView( float4 screen )
{ {
// Convert to normalized texture coordinates // Convert to normalized texture coordinates
float2 texCoord = screen.xy / gScreenToViewParams.screenDimensions; float2 texCoord = screen.xy / gViewParams.screenDimensions;
// Convert to clip space // Convert to clip space
float4 clip = float4( float2( texCoord.x, -texCoord.y ) * 2.0f - 1.0f, screen.z, screen.w ); float4 clip = float4( float2( texCoord.x, -texCoord.y ) * 2.0f - 1.0f, screen.z, screen.w );
+1 -1
View File
@@ -69,4 +69,4 @@ struct Lights
}; };
layout(set = INDEX_LIGHT_ENV, binding = 0, std430) layout(set = INDEX_LIGHT_ENV, binding = 0, std430)
ConstantBuffer<Lights> gLightEnv; StructuredBuffer<Lights> gLightEnv;
+1 -1
View File
@@ -32,7 +32,7 @@ void TextureLoader::importAsset(const std::filesystem::path& filePath)
AssetRegistry::get().textures[asset->getFileName()] = asset; AssetRegistry::get().textures[asset->getFileName()] = asset;
futures.add(std::async(std::launch::async, [this, filePath, asset] () mutable { futures.add(std::async(std::launch::async, [this, filePath, asset] () mutable {
using namespace std::chrono_literals; using namespace std::chrono_literals;
std::this_thread::sleep_for(5s); //std::this_thread::sleep_for(5s);
Gfx::PTexture2D texture = import(filePath); Gfx::PTexture2D texture = import(filePath);
asset->setTexture(texture); asset->setTexture(texture);
asset->setStatus(Asset::Status::Ready); asset->setStatus(Asset::Status::Ready);
+2 -2
View File
@@ -70,7 +70,7 @@ namespace Seele
_data = new T[other.allocated]; _data = new T[other.allocated];
assert(_data != nullptr); assert(_data != nullptr);
markIteratorDirty(); markIteratorDirty();
std::copy(other.begin(), other.end(), beginIt); std::copy(other.begin(), other.end(), begin());
} }
Array(Array &&other) noexcept Array(Array &&other) noexcept
: arraySize(std::move(other.arraySize)) : arraySize(std::move(other.arraySize))
@@ -97,7 +97,7 @@ namespace Seele
} }
arraySize = other.arraySize; arraySize = other.arraySize;
markIteratorDirty(); markIteratorDirty();
std::copy(other.begin(), other.end(), beginIt); std::copy(other.begin(), other.end(), begin());
} }
return *this; return *this;
} }
+8 -3
View File
@@ -33,20 +33,23 @@ public:
virtual void beginRenderPass(PRenderPass renderPass) = 0; virtual void beginRenderPass(PRenderPass renderPass) = 0;
virtual void endRenderPass() = 0; virtual void endRenderPass() = 0;
virtual void executeCommands(Array<PRenderCommand> commands) = 0; virtual void executeCommands(const Array<PRenderCommand>& commands) = 0;
virtual void executeCommands(const Array<PComputeCommand>& commands) = 0;
virtual PTexture2D createTexture2D(const TextureCreateInfo &createInfo) = 0; virtual PTexture2D createTexture2D(const TextureCreateInfo &createInfo) = 0;
virtual PUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) = 0; virtual PUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) = 0;
virtual PStructuredBuffer createStructuredBuffer(const BulkResourceData &bulkData) = 0; virtual PStructuredBuffer createStructuredBuffer(const StructuredBufferCreateInfo &bulkData) = 0;
virtual PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) = 0; virtual PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) = 0;
virtual PIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) = 0; virtual PIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) = 0;
virtual PRenderCommand createRenderCommand() = 0; virtual PRenderCommand createRenderCommand(const std::string& name = "") = 0;
virtual PComputeCommand createComputeCommand(const std::string& name = "") = 0;
virtual PVertexDeclaration createVertexDeclaration(const Array<VertexElement>& element) = 0; virtual PVertexDeclaration createVertexDeclaration(const Array<VertexElement>& element) = 0;
virtual PVertexShader createVertexShader(const ShaderCreateInfo& createInfo) = 0; virtual PVertexShader createVertexShader(const ShaderCreateInfo& createInfo) = 0;
virtual PControlShader createControlShader(const ShaderCreateInfo& createInfo) = 0; virtual PControlShader createControlShader(const ShaderCreateInfo& createInfo) = 0;
virtual PEvaluationShader createEvaluationShader(const ShaderCreateInfo& createInfo) = 0; virtual PEvaluationShader createEvaluationShader(const ShaderCreateInfo& createInfo) = 0;
virtual PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) = 0; virtual PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) = 0;
virtual PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) = 0; virtual PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) = 0;
virtual PComputeShader createComputeShader(const ShaderCreateInfo& createInfo) = 0;
virtual PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) = 0; virtual PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) = 0;
virtual PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) = 0; virtual PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) = 0;
virtual PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) = 0; virtual PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) = 0;
@@ -54,6 +57,8 @@ public:
virtual PDescriptorLayout createDescriptorLayout(const std::string& name = "") = 0; virtual PDescriptorLayout createDescriptorLayout(const std::string& name = "") = 0;
virtual PPipelineLayout createPipelineLayout() = 0; virtual PPipelineLayout createPipelineLayout() = 0;
virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) = 0;
PVertexBuffer getNullVertexBuffer(); PVertexBuffer getNullVertexBuffer();
protected: protected:
+11 -1
View File
@@ -59,7 +59,7 @@ struct BulkResourceData
{ {
uint32 size; uint32 size;
uint8 *data; uint8 *data;
Gfx::QueueType owner; Gfx::QueueType owner = Gfx::QueueType::GRAPHICS;
BulkResourceData() BulkResourceData()
: size(0), data(nullptr), owner(Gfx::QueueType::GRAPHICS) : size(0), data(nullptr), owner(Gfx::QueueType::GRAPHICS)
{ {
@@ -116,6 +116,15 @@ struct UniformBufferCreateInfo
{ {
} }
}; };
struct StructuredBufferCreateInfo
{
BulkResourceData resourceData;
uint8 bDynamic: 1;
StructuredBufferCreateInfo()
: resourceData(), bDynamic(0)
{
}
};
struct ShaderCreateInfo struct ShaderCreateInfo
{ {
//It's possible to input multiple source files for materials or vertexFactories //It's possible to input multiple source files for materials or vertexFactories
@@ -208,6 +217,7 @@ DECLARE_NAME_REF(Gfx, ControlShader)
DECLARE_NAME_REF(Gfx, EvaluationShader) DECLARE_NAME_REF(Gfx, EvaluationShader)
DECLARE_NAME_REF(Gfx, GeometryShader) DECLARE_NAME_REF(Gfx, GeometryShader)
DECLARE_NAME_REF(Gfx, FragmentShader) DECLARE_NAME_REF(Gfx, FragmentShader)
DECLARE_NAME_REF(Gfx, ComputeShader)
DECLARE_NAME_REF(Gfx, PipelineLayout) DECLARE_NAME_REF(Gfx, PipelineLayout)
DECLARE_NAME_REF(Gfx, RenderPass) DECLARE_NAME_REF(Gfx, RenderPass)
struct GraphicsPipelineCreateInfo struct GraphicsPipelineCreateInfo
+18 -2
View File
@@ -109,7 +109,7 @@ void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorTyp
descriptorBindings[bindingIndex] = binding; descriptorBindings[bindingIndex] = binding;
} }
PDescriptorSet DescriptorLayout::allocatedDescriptorSet() PDescriptorSet DescriptorLayout::allocateDescriptorSet()
{ {
PDescriptorSet result; PDescriptorSet result;
allocator->allocateDescriptorSet(result); allocator->allocateDescriptorSet(result);
@@ -168,8 +168,14 @@ void QueueOwnedResource::transferOwnership(QueueType newOwner)
if(mapping.needsTransfer(currentOwner, newOwner)) if(mapping.needsTransfer(currentOwner, newOwner))
{ {
executeOwnershipBarrier(newOwner); executeOwnershipBarrier(newOwner);
currentOwner = newOwner;
} }
currentOwner = newOwner;
}
void QueueOwnedResource::pipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, SePipelineStageFlags dstStage)
{
// maybe add some checks
executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
} }
Buffer::Buffer(QueueFamilyMapping mapping, QueueType startQueue) Buffer::Buffer(QueueFamilyMapping mapping, QueueType startQueue)
@@ -314,6 +320,16 @@ RenderCommand::~RenderCommand()
{ {
} }
ComputeCommand::ComputeCommand()
{
}
ComputeCommand::~ComputeCommand()
{
}
RenderTargetLayout::RenderTargetLayout() RenderTargetLayout::RenderTargetLayout()
: inputAttachments() : inputAttachments()
, colorAttachments() , colorAttachments()
+33 -9
View File
@@ -148,14 +148,6 @@ private:
}; };
DEFINE_REF(ShaderMap) DEFINE_REF(ShaderMap)
class ComputeShader
{
public:
ComputeShader() {}
virtual ~ComputeShader() {}
};
DEFINE_REF(ComputeShader)
class DescriptorBinding class DescriptorBinding
{ {
public: public:
@@ -233,7 +225,7 @@ public:
virtual void create() = 0; virtual void create() = 0;
virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1); virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1);
virtual void reset(); virtual void reset();
virtual PDescriptorSet allocatedDescriptorSet(); virtual PDescriptorSet allocateDescriptorSet();
const Array<DescriptorBinding> &getBindings() const { return descriptorBindings; } const Array<DescriptorBinding> &getBindings() const { return descriptorBindings; }
inline uint32 getSetIndex() const { return setIndex; } inline uint32 getSetIndex() const { return setIndex; }
@@ -301,9 +293,12 @@ public:
//Preliminary checks to see if the barrier should be executed at all //Preliminary checks to see if the barrier should be executed at all
void transferOwnership(QueueType newOwner); void transferOwnership(QueueType newOwner);
void pipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess, SePipelineStageFlags dstStage);
protected: protected:
virtual void executeOwnershipBarrier(QueueType newOwner) = 0; virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
Gfx::QueueType currentOwner; Gfx::QueueType currentOwner;
QueueFamilyMapping mapping; QueueFamilyMapping mapping;
}; };
@@ -353,6 +348,8 @@ protected:
Array<uint8> contents; Array<uint8> contents;
// Inherited via QueueOwnedResource // Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0; virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
}; };
DEFINE_REF(UniformBuffer) DEFINE_REF(UniformBuffer)
@@ -374,6 +371,8 @@ public:
protected: protected:
// Inherited via QueueOwnedResource // Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0; virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
uint32 numVertices; uint32 numVertices;
uint32 vertexSize; uint32 vertexSize;
}; };
@@ -396,6 +395,8 @@ public:
protected: protected:
// Inherited via QueueOwnedResource // Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0; virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
Gfx::SeIndexType indexType; Gfx::SeIndexType indexType;
uint32 numIndices; uint32 numIndices;
}; };
@@ -409,6 +410,8 @@ public:
protected: protected:
// Inherited via QueueOwnedResource // Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0; virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
}; };
DEFINE_REF(StructuredBuffer) DEFINE_REF(StructuredBuffer)
@@ -480,10 +483,14 @@ public:
virtual uint32 getSizeX() const = 0; virtual uint32 getSizeX() const = 0;
virtual uint32 getSizeY() const = 0; virtual uint32 getSizeY() const = 0;
virtual SeSampleCountFlags getNumSamples() const = 0; virtual SeSampleCountFlags getNumSamples() const = 0;
virtual void changeLayout(SeImageLayout newLayout) = 0;
virtual class Texture2D* getTexture2D() { return nullptr; } virtual class Texture2D* getTexture2D() { return nullptr; }
virtual void* getNativeHandle() { return nullptr; }
protected: protected:
// Inherited via QueueOwnedResource // Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0; virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
}; };
DEFINE_REF(Texture) DEFINE_REF(Texture)
class Texture2D : public Texture class Texture2D : public Texture
@@ -496,10 +503,13 @@ public:
virtual uint32 getSizeX() const = 0; virtual uint32 getSizeX() const = 0;
virtual uint32 getSizeY() const = 0; virtual uint32 getSizeY() const = 0;
virtual SeSampleCountFlags getNumSamples() const = 0; virtual SeSampleCountFlags getNumSamples() const = 0;
virtual void changeLayout(SeImageLayout newLayout) = 0;
virtual class Texture2D* getTexture2D() { return this; } virtual class Texture2D* getTexture2D() { return this; }
protected: protected:
//Inherited via QueueOwnedResource //Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0; virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage,
SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0;
}; };
DEFINE_REF(Texture2D) DEFINE_REF(Texture2D)
@@ -517,8 +527,22 @@ public:
virtual void bindVertexBuffer(const Array<VertexInputStream>& streams) = 0; virtual void bindVertexBuffer(const Array<VertexInputStream>& streams) = 0;
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0; virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0;
virtual void draw(const MeshBatchElement& data) = 0; virtual void draw(const MeshBatchElement& data) = 0;
std::string name;
}; };
DEFINE_REF(RenderCommand) DEFINE_REF(RenderCommand)
class ComputeCommand
{
public:
ComputeCommand();
virtual ~ComputeCommand();
virtual bool isReady() = 0;
virtual void bindPipeline(Gfx::PComputePipeline pipeline) = 0;
virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0;
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) = 0;
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) = 0;
std::string name;
};
DEFINE_REF(ComputeCommand)
class Window class Window
{ {
+21 -24
View File
@@ -38,7 +38,7 @@ void BasePassMeshProcessor::addMeshBatch(
assert(collection != nullptr); assert(collection != nullptr);
for(uint32 i = 0; i < batch.elements.size(); ++i) for(uint32 i = 0; i < batch.elements.size(); ++i)
{ {
Gfx::PDescriptorSet descriptorSet = primitiveLayout->allocatedDescriptorSet(); Gfx::PDescriptorSet descriptorSet = primitiveLayout->allocateDescriptorSet();
descriptorSet->updateBuffer(0, batch.elements[i].uniformBuffer); descriptorSet->updateBuffer(0, batch.elements[i].uniformBuffer);
descriptorSet->writeChanges(); descriptorSet->writeChanges();
cachedPrimitiveSets.add(descriptorSet); cachedPrimitiveSets.add(descriptorSet);
@@ -92,14 +92,12 @@ BasePass::BasePass(PRenderGraph renderGraph, const PScene scene, Gfx::PGraphics
basePassLayout = graphics->createPipelineLayout(); basePassLayout = graphics->createPipelineLayout();
lightLayout = graphics->createDescriptorLayout("LightLayout"); lightLayout = graphics->createDescriptorLayout("LightLayout");
lightLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); lightLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
uniformInitializer.resourceData.size = sizeof(LightEnv); lightLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
uniformInitializer.resourceData.data = nullptr; lightLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE);
uniformInitializer.bDynamic = true;
lightUniform = graphics->createUniformBuffer(uniformInitializer);
lightLayout->create(); lightLayout->create();
basePassLayout->addDescriptorLayout(INDEX_LIGHT_ENV, lightLayout); basePassLayout->addDescriptorLayout(INDEX_LIGHT_ENV, lightLayout);
descriptorSets[INDEX_LIGHT_ENV] = lightLayout->allocatedDescriptorSet(); descriptorSets[INDEX_LIGHT_ENV] = lightLayout->allocateDescriptorSet();
viewLayout = graphics->createDescriptorLayout("ViewLayout"); viewLayout = graphics->createDescriptorLayout("ViewLayout");
viewLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); viewLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
@@ -107,14 +105,9 @@ BasePass::BasePass(PRenderGraph renderGraph, const PScene scene, Gfx::PGraphics
uniformInitializer.resourceData.data = (uint8*)&viewParams; uniformInitializer.resourceData.data = (uint8*)&viewParams;
uniformInitializer.bDynamic = true; uniformInitializer.bDynamic = true;
viewParamBuffer = graphics->createUniformBuffer(uniformInitializer); viewParamBuffer = graphics->createUniformBuffer(uniformInitializer);
viewLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
uniformInitializer.resourceData.size = sizeof(ScreenToViewParameter);
uniformInitializer.resourceData.data = (uint8*)&screenToViewParams;
uniformInitializer.bDynamic = true;
screenToViewParamBuffer = graphics->createUniformBuffer(uniformInitializer);
viewLayout->create(); viewLayout->create();
basePassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewLayout); basePassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewLayout);
descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocatedDescriptorSet(); descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet();
primitiveLayout = graphics->createDescriptorLayout("PrimitiveLayout"); primitiveLayout = graphics->createDescriptorLayout("PrimitiveLayout");
primitiveLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); primitiveLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
@@ -131,25 +124,16 @@ void BasePass::beginFrame()
processor->clearCommands(); processor->clearCommands();
primitiveLayout->reset(); primitiveLayout->reset();
BulkResourceData uniformUpdate; BulkResourceData uniformUpdate;
uniformUpdate.size = sizeof(LightEnv);
uniformUpdate.data = (uint8*)&scene->getLightEnvironment();
lightUniform->updateContents(uniformUpdate);
descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(0, lightUniform);
descriptorSets[INDEX_LIGHT_ENV]->writeChanges();
viewParams.viewMatrix = source->getViewMatrix(); viewParams.viewMatrix = source->getViewMatrix();
viewParams.projectionMatrix = source->getProjectionMatrix(); viewParams.projectionMatrix = source->getProjectionMatrix();
viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0); viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0);
screenToViewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix); viewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix);
screenToViewParams.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY())); viewParams.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
uniformUpdate.size = sizeof(ViewParameter); uniformUpdate.size = sizeof(ViewParameter);
uniformUpdate.data = (uint8*)&viewParams; uniformUpdate.data = (uint8*)&viewParams;
viewParamBuffer->updateContents(uniformUpdate); viewParamBuffer->updateContents(uniformUpdate);
uniformUpdate.size = sizeof(ScreenToViewParameter);
uniformUpdate.data = (uint8*)&screenToViewParams;
screenToViewParamBuffer->updateContents(uniformUpdate);
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer); descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer);
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(1, screenToViewParamBuffer);
descriptorSets[INDEX_VIEW_PARAMS]->writeChanges(); descriptorSets[INDEX_VIEW_PARAMS]->writeChanges();
for(auto &&meshBatch : scene->getStaticMeshes()) for(auto &&meshBatch : scene->getStaticMeshes())
{ {
@@ -159,6 +143,17 @@ void BasePass::beginFrame()
void BasePass::render() void BasePass::render()
{ {
descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(0, scene->getLightBuffer());
oLightIndexList->pipelineBarrier(
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
oLightGrid->pipelineBarrier(
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(1, oLightIndexList);
descriptorSets[INDEX_LIGHT_ENV]->updateTexture(2, oLightGrid);
descriptorSets[INDEX_LIGHT_ENV]->writeChanges();
graphics->beginRenderPass(renderPass); graphics->beginRenderPass(renderPass);
for (auto &&meshBatch : scene->getStaticMeshes()) for (auto &&meshBatch : scene->getStaticMeshes())
{ {
@@ -184,6 +179,8 @@ void BasePass::createRenderPass()
depthAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD; depthAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD;
Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(colorAttachment, depthAttachment); Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(colorAttachment, depthAttachment);
renderPass = graphics->createRenderPass(layout); renderPass = graphics->createRenderPass(layout);
oLightIndexList = renderGraph->requestBuffer("LIGHTCULLING_OLIGHTLIST");
oLightGrid = renderGraph->requestTexture("LIGHTCULLING_OLIGHTGRID");
} }
void BasePass::modifyRenderPassMacros(Map<const char*, const char*>& defines) void BasePass::modifyRenderPassMacros(Map<const char*, const char*>& defines)
+2 -2
View File
@@ -54,13 +54,13 @@ private:
Gfx::PPipelineLayout basePassLayout; Gfx::PPipelineLayout basePassLayout;
// Set 0: Light environment // Set 0: Light environment
static constexpr uint32 INDEX_LIGHT_ENV = 0; static constexpr uint32 INDEX_LIGHT_ENV = 0;
Gfx::PStructuredBuffer oLightIndexList;
Gfx::PTexture oLightGrid;
Gfx::PDescriptorLayout lightLayout; Gfx::PDescriptorLayout lightLayout;
Gfx::PUniformBuffer lightUniform;
// Set 1: viewParameter // Set 1: viewParameter
static constexpr uint32 INDEX_VIEW_PARAMS = 1; static constexpr uint32 INDEX_VIEW_PARAMS = 1;
Gfx::PDescriptorLayout viewLayout; Gfx::PDescriptorLayout viewLayout;
Gfx::PUniformBuffer viewParamBuffer; Gfx::PUniformBuffer viewParamBuffer;
Gfx::PUniformBuffer screenToViewParamBuffer;
// Set 2: materials, generated // Set 2: materials, generated
static constexpr uint32 INDEX_MATERIAL = 2; static constexpr uint32 INDEX_MATERIAL = 2;
// Set 3: primitive scene data // Set 3: primitive scene data
@@ -37,7 +37,7 @@ void DepthPrepassMeshProcessor::addMeshBatch(
assert(collection != nullptr); assert(collection != nullptr);
for(uint32 i = 0; i < batch.elements.size(); ++i) for(uint32 i = 0; i < batch.elements.size(); ++i)
{ {
Gfx::PDescriptorSet descriptorSet = primitiveLayout->allocatedDescriptorSet(); Gfx::PDescriptorSet descriptorSet = primitiveLayout->allocateDescriptorSet();
descriptorSet->updateBuffer(0, batch.elements[i].uniformBuffer); descriptorSet->updateBuffer(0, batch.elements[i].uniformBuffer);
descriptorSet->writeChanges(); descriptorSet->writeChanges();
cachedPrimitiveSets.add(descriptorSet); cachedPrimitiveSets.add(descriptorSet);
@@ -97,14 +97,9 @@ DepthPrepass::DepthPrepass(PRenderGraph renderGraph, const PScene scene, Gfx::PG
uniformInitializer.resourceData.data = (uint8*)&viewParams; uniformInitializer.resourceData.data = (uint8*)&viewParams;
uniformInitializer.bDynamic = true; uniformInitializer.bDynamic = true;
viewParamBuffer = graphics->createUniformBuffer(uniformInitializer); viewParamBuffer = graphics->createUniformBuffer(uniformInitializer);
viewLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
uniformInitializer.resourceData.size = sizeof(ScreenToViewParameter);
uniformInitializer.resourceData.data = (uint8*)&screenToViewParams;
uniformInitializer.bDynamic = true;
screenToViewParamBuffer = graphics->createUniformBuffer(uniformInitializer);
viewLayout->create(); viewLayout->create();
depthPrepassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewLayout); depthPrepassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewLayout);
descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocatedDescriptorSet(); descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocateDescriptorSet();
primitiveLayout = graphics->createDescriptorLayout("PrimitiveLayout"); primitiveLayout = graphics->createDescriptorLayout("PrimitiveLayout");
primitiveLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); primitiveLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
@@ -125,16 +120,12 @@ void DepthPrepass::beginFrame()
viewParams.viewMatrix = source->getViewMatrix(); viewParams.viewMatrix = source->getViewMatrix();
viewParams.projectionMatrix = source->getProjectionMatrix(); viewParams.projectionMatrix = source->getProjectionMatrix();
viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0); viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0);
screenToViewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix); viewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix);
screenToViewParams.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY())); viewParams.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
uniformUpdate.size = sizeof(ViewParameter); uniformUpdate.size = sizeof(ViewParameter);
uniformUpdate.data = (uint8*)&viewParams; uniformUpdate.data = (uint8*)&viewParams;
viewParamBuffer->updateContents(uniformUpdate); viewParamBuffer->updateContents(uniformUpdate);
uniformUpdate.size = sizeof(ScreenToViewParameter);
uniformUpdate.data = (uint8*)&screenToViewParams;
screenToViewParamBuffer->updateContents(uniformUpdate);
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer); descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer);
descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(1, screenToViewParamBuffer);
descriptorSets[INDEX_VIEW_PARAMS]->writeChanges(); descriptorSets[INDEX_VIEW_PARAMS]->writeChanges();
for(auto &&meshBatch : scene->getStaticMeshes()) for(auto &&meshBatch : scene->getStaticMeshes())
{ {
@@ -144,6 +135,10 @@ void DepthPrepass::beginFrame()
void DepthPrepass::render() void DepthPrepass::render()
{ {
depthAttachment->getTexture()->pipelineBarrier(
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
depthAttachment->getTexture()->transferOwnership(Gfx::QueueType::GRAPHICS);
graphics->beginRenderPass(renderPass); graphics->beginRenderPass(renderPass);
for (auto &&meshBatch : scene->getStaticMeshes()) for (auto &&meshBatch : scene->getStaticMeshes())
{ {
@@ -55,7 +55,6 @@ private:
static constexpr uint32 INDEX_VIEW_PARAMS = 0; static constexpr uint32 INDEX_VIEW_PARAMS = 0;
Gfx::PDescriptorLayout viewLayout; Gfx::PDescriptorLayout viewLayout;
Gfx::PUniformBuffer viewParamBuffer; Gfx::PUniformBuffer viewParamBuffer;
Gfx::PUniformBuffer screenToViewParamBuffer;
// Set 1: materials, generated // Set 1: materials, generated
static constexpr uint32 INDEX_MATERIAL = 1; static constexpr uint32 INDEX_MATERIAL = 1;
// Set 2: primitive scene data // Set 2: primitive scene data
@@ -1,12 +1,15 @@
#include "LightCullingPass.h" #include "LightCullingPass.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "Scene/Scene.h"
#include "Scene/Actor/CameraActor.h" #include "Scene/Actor/CameraActor.h"
#include "Scene/Components/CameraComponent.h" #include "Scene/Components/CameraComponent.h"
#include "RenderGraph.h"
using namespace Seele; using namespace Seele;
LightCullingPass::LightCullingPass(PRenderGraph renderGraph, Gfx::PViewport viewport, Gfx::PGraphics graphics, PCameraActor camera) LightCullingPass::LightCullingPass(PRenderGraph renderGraph, const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor camera)
: RenderPass(renderGraph) : RenderPass(renderGraph)
, scene(scene)
, viewport(viewport) , viewport(viewport)
, graphics(graphics) , graphics(graphics)
, source(camera->getCameraComponent()) , source(camera->getCameraComponent())
@@ -20,46 +23,58 @@ LightCullingPass::~LightCullingPass()
void LightCullingPass::beginFrame() void LightCullingPass::beginFrame()
{ {
uint32_t viewportWidth = viewport->getSizeX(); BulkResourceData uniformUpdate;
uint32_t viewportHeight = viewport->getSizeY(); viewParams.viewMatrix = source->getViewMatrix();
viewParams.projectionMatrix = source->getProjectionMatrix();
viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0);
viewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix);
viewParams.screenDimensions = Vector2(static_cast<float>(viewport->getSizeX()), static_cast<float>(viewport->getSizeY()));
uniformUpdate.size = sizeof(ViewParameter);
uniformUpdate.data = (uint8*)&viewParams;
viewParamsBuffer->updateContents(uniformUpdate);
glm::uvec3 numThreads = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1)); cullingDescriptorLayout->reset();
glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1)); lightEnvDescriptorLayout->reset();
cullingDescriptorSet = cullingDescriptorLayout->allocateDescriptorSet();
dispatchParams.numThreads = numThreads; lightEnvDescriptorSet = lightEnvDescriptorLayout->allocateDescriptorSet();
dispatchParams.numThreadGroups = numThreadGroups; cullingDescriptorSet->updateBuffer(0, viewParamsBuffer);
ScreenToView screenToView; cullingDescriptorSet->updateBuffer(1, dispatchParamsBuffer);
screenToView.inverseProjection = glm::inverse(source->getProjectionMatrix()); cullingDescriptorSet->updateBuffer(3, frustumBuffer);
screenToView.screenDimensions = glm::vec2(viewportWidth, viewportHeight); cullingDescriptorSet->updateBuffer(4, oLightIndexCounter);
cullingDescriptorSet->updateBuffer(5, tLightIndexCounter);
frustumShader = renderDevice->createComputeShader(loadPlaintext("./_Game/shaders/ComputeFrustums.slang"), "computeFrustums"); cullingDescriptorSet->updateBuffer(6, oLightIndexList);
frustumDescriptorLayout = renderDevice->createDescriptorLayout(); cullingDescriptorSet->updateBuffer(7, tLightIndexList);
frustumDescriptorLayout->addDescriptorBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); cullingDescriptorSet->updateTexture(8, oLightGrid);
frustumDescriptorLayout->addDescriptorBinding(1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); cullingDescriptorSet->updateTexture(9, tLightGrid);
frustumDescriptorLayout->addDescriptorBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
frustumLayout = renderDevice->createPipelineLayout();
frustumLayout->addPushConstants(init::PushConstantRange(VK_SHADER_STAGE_COMPUTE_BIT, sizeof(DispatchParams), 0));
frustumLayout->addDescriptorLayout(0, frustumDescriptorLayout);
frustumLayout->create();
frustumShader->setPipelineLayout(frustumLayout);
RHIResourceCreateInfo frustumInfo;
frustumBuffer = renderDevice->createStructuredBuffer(sizeof(Frustum), sizeof(Frustum) * numThreads.x * numThreads.y * numThreads.z, BufferUsageFlags::BUF_UnorderedAccess, frustumInfo);
dispatchParamsBuffer = renderDevice->createUniformBuffer(&dispatchParams, sizeof(DispatchParams), UniformBuffer_MultiFrame);
screenToViewParams = renderDevice->createUniformBuffer(&screenToView, sizeof(ScreenToView), UniformBuffer_MultiFrame);
frustumDescriptorSet = frustumDescriptorLayout->allocateDescriptorSet();
frustumDescriptorSet->updateBuffer(0, dispatchParamsBuffer);
frustumDescriptorSet->updateBuffer(1, screenToViewParams);
frustumDescriptorSet->updateBuffer(2, frustumBuffer);
frustumDescriptorSet->writeChanges();
renderDevice->setComputeShader(frustumShader);
renderDevice->bindComputeDescriptors(frustumLayout, frustumDescriptorSet);
renderDevice->dispatchComputeShader(numThreadGroups.x, numThreadGroups.y, numThreadGroups.z);
renderDevice->pipelineBarrier(frustumBuffer, VK_ACCESS_SHADER_WRITE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
} }
void LightCullingPass::render() void LightCullingPass::render()
{ {
oLightIndexList->pipelineBarrier(
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
oLightGrid->pipelineBarrier(
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
depthAttachment->pipelineBarrier(
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
depthAttachment->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
depthAttachment->transferOwnership(Gfx::QueueType::COMPUTE);
cullingDescriptorSet->updateTexture(2, depthAttachment);
cullingDescriptorSet->writeChanges();
lightEnvDescriptorSet->updateBuffer(0, scene->getLightBuffer());
lightEnvDescriptorSet->writeChanges();
Gfx::PComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand");
computeCommand->bindPipeline(cullingPipeline);
Array<Gfx::PDescriptorSet> descriptorSets = {cullingDescriptorSet, lightEnvDescriptorSet};
computeCommand->bindDescriptor(descriptorSets);
computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z);
Array<Gfx::PComputeCommand> commands = {computeCommand};
graphics->executeCommands(commands);
depthAttachment->changeLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
depthAttachment->transferOwnership(Gfx::QueueType::GRAPHICS);
} }
void LightCullingPass::endFrame() void LightCullingPass::endFrame()
@@ -69,15 +84,172 @@ void LightCullingPass::endFrame()
void LightCullingPass::publishOutputs() void LightCullingPass::publishOutputs()
{ {
setupFrustums();
BulkResourceData resourceData;
StructuredBufferCreateInfo createInfo;
resourceData.size = sizeof(uint32);
resourceData.data = nullptr;
resourceData.owner = Gfx::QueueType::COMPUTE;
createInfo.bDynamic = false;
createInfo.resourceData = resourceData;
oLightIndexCounter = graphics->createStructuredBuffer(createInfo);
tLightIndexCounter = graphics->createStructuredBuffer(createInfo);
resourceData.size = sizeof(uint32_t) * dispatchParams.numThreadGroups.x * dispatchParams.numThreadGroups.y * dispatchParams.numThreadGroups.z * 1024;
oLightIndexList = graphics->createStructuredBuffer(createInfo);
tLightIndexList = graphics->createStructuredBuffer(createInfo);
renderGraph->registerBufferOutput("LIGHTCULLING_OLIGHTLIST", oLightIndexList);
renderGraph->registerBufferOutput("LIGHTCULLING_TLIGHTLIST", tLightIndexList);
TextureCreateInfo textureInfo;
textureInfo.width = dispatchParams.numThreadGroups.x;
textureInfo.height = dispatchParams.numThreadGroups.y;
textureInfo.format = Gfx::SE_FORMAT_R16G16_UINT;
textureInfo.usage = Gfx::SE_IMAGE_USAGE_STORAGE_BIT;
oLightGrid = graphics->createTexture2D(textureInfo);
tLightGrid = graphics->createTexture2D(textureInfo);
renderGraph->registerTextureOutput("LIGHTCULLING_OLIGHTGRID", oLightGrid);
renderGraph->registerTextureOutput("LIGHTCULLING_TLIGHTGRID", tLightGrid);
} }
void LightCullingPass::createRenderPass() void LightCullingPass::createRenderPass()
{ {
cullingDescriptorLayout = graphics->createDescriptorLayout("CullingLayout");
//ViewParams
cullingDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
//Dispatchparams
cullingDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
//DepthTexture
cullingDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
//Frustums
cullingDescriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
//o_lightIndexCounter
cullingDescriptorLayout->addDescriptorBinding(4, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
//t_lightIndexCounter
cullingDescriptorLayout->addDescriptorBinding(5, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
//o_lightIndexList
cullingDescriptorLayout->addDescriptorBinding(6, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
//t_lightIndexList
cullingDescriptorLayout->addDescriptorBinding(7, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
//o_lightGrid
cullingDescriptorLayout->addDescriptorBinding(8, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE);
//t_lightGrid
cullingDescriptorLayout->addDescriptorBinding(9, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE);
lightEnvDescriptorLayout = graphics->createDescriptorLayout("LightEnv");
//LightEnv
lightEnvDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
cullingLayout = graphics->createPipelineLayout();
cullingLayout->addDescriptorLayout(0, cullingDescriptorLayout);
cullingLayout->addDescriptorLayout(1, lightEnvDescriptorLayout);
cullingLayout->create();
ShaderCreateInfo createInfo;
createInfo.name = "Culling";
std::ifstream codeStream("./shaders/LightCulling.slang", std::ios::ate);
auto fileSize = codeStream.tellg();
codeStream.seekg(0);
Array<char> buffer(static_cast<uint32>(fileSize));
codeStream.read(buffer.data(), fileSize);
createInfo.shaderCode.add(std::string(buffer.data()));
createInfo.entryPoint = "cullLights";
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
createInfo.defines["INDEX_LIGHT_ENV"] = "1";
createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "0";
cullingShader = graphics->createComputeShader(createInfo);
ComputePipelineCreateInfo pipelineInfo;
pipelineInfo.computeShader = cullingShader;
pipelineInfo.pipelineLayout = cullingLayout;
cullingPipeline = graphics->createComputePipeline(pipelineInfo);
depthAttachment = renderGraph->requestRenderTarget("DEPTHPREPASS_DEPTH")->getTexture();
} }
void LightCullingPass::modifyRenderPassMacros(Map<const char*, const char*>& defines) void LightCullingPass::modifyRenderPassMacros(Map<const char*, const char*>& defines)
{ {
}
void LightCullingPass::setupFrustums()
{
uint32_t viewportWidth = viewport->getSizeX();
uint32_t viewportHeight = viewport->getSizeY();
glm::uvec3 numThreads = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1));
glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1));
viewParams.viewMatrix = source->getViewMatrix();
viewParams.projectionMatrix = source->getProjectionMatrix();
viewParams.inverseProjectionMatrix = glm::inverse(source->getProjectionMatrix());
viewParams.screenDimensions = glm::vec2(viewportWidth, viewportHeight);
viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0);
dispatchParams.numThreads = numThreads;
dispatchParams.numThreadGroups = numThreadGroups;
Gfx::PDescriptorLayout frustumDescriptorLayout = graphics->createDescriptorLayout("FrustumLayout");
frustumDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
frustumDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
frustumDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
frustumLayout = graphics->createPipelineLayout();
frustumLayout->addDescriptorLayout(0, frustumDescriptorLayout);
frustumLayout->create();
ShaderCreateInfo createInfo;
createInfo.name = "Frustum";
std::ifstream codeStream("./shaders/ComputeFrustums.slang", std::ios::ate);
auto fileSize = codeStream.tellg();
codeStream.seekg(0);
Array<char> buffer(static_cast<uint32>(fileSize));
codeStream.read(buffer.data(), fileSize);
createInfo.shaderCode.add(std::string(buffer.data()));
createInfo.entryPoint = "computeFrustums";
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
frustumShader = graphics->createComputeShader(createInfo);
ComputePipelineCreateInfo pipelineInfo;
pipelineInfo.computeShader = frustumShader;
pipelineInfo.pipelineLayout = frustumLayout;
frustumPipeline = graphics->createComputePipeline(pipelineInfo);
BulkResourceData resourceInfo;
UniformBufferCreateInfo uniformInfo;
resourceInfo.size = sizeof(ViewParameter);
resourceInfo.data = (uint8*)&viewParams;
resourceInfo.owner = Gfx::QueueType::COMPUTE;
uniformInfo.resourceData = resourceInfo;
uniformInfo.bDynamic = false;
viewParamsBuffer = graphics->createUniformBuffer(uniformInfo);
resourceInfo.size = sizeof(DispatchParams);
resourceInfo.data = (uint8*)&dispatchParams;
uniformInfo.resourceData = resourceInfo;
uniformInfo.bDynamic = false;
dispatchParamsBuffer = graphics->createUniformBuffer(uniformInfo);
StructuredBufferCreateInfo structuredInfo;
resourceInfo.size = sizeof(Frustum) * numThreads.x * numThreads.y * numThreads.z;
resourceInfo.data = nullptr;
structuredInfo.resourceData = resourceInfo;
structuredInfo.bDynamic = false;
frustumBuffer = graphics->createStructuredBuffer(structuredInfo);
frustumDescriptorSet = frustumDescriptorLayout->allocateDescriptorSet();
frustumDescriptorSet->updateBuffer(0, viewParamsBuffer);
frustumDescriptorSet->updateBuffer(1, dispatchParamsBuffer);
frustumDescriptorSet->updateBuffer(2, frustumBuffer);
frustumDescriptorSet->writeChanges();
Gfx::PComputeCommand command = graphics->createComputeCommand("FrustumCommand");
command->bindPipeline(frustumPipeline);
command->bindDescriptor(frustumDescriptorSet);
command->dispatch(numThreadGroups.x, numThreadGroups.y, numThreadGroups.z);
Array<Gfx::PComputeCommand> commands = {command};
graphics->executeCommands(commands);
frustumBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
} }
@@ -1,16 +1,17 @@
#pragma once #pragma once
#include "RenderPass.h" #include "RenderPass.h"
#include "Graphics/GraphicsResources.h"
namespace Seele namespace Seele
{ {
DECLARE_REF(CameraActor) DECLARE_REF(CameraActor)
DECLARE_REF(CameraComponent) DECLARE_REF(CameraComponent)
DECLARE_NAME_REF(Gfx, Viewport) DECLARE_REF(Scene)
DECLARE_NAME_REF(Gfx, Graphics) DECLARE_REF(Viewport)
class LightCullingPass : public RenderPass class LightCullingPass : public RenderPass
{ {
public: public:
LightCullingPass(PRenderGraph renderGraph, Gfx::PViewport viewport, Gfx::PGraphics graphics, PCameraActor camera); LightCullingPass(PRenderGraph renderGraph, const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor camera);
virtual ~LightCullingPass(); virtual ~LightCullingPass();
virtual void beginFrame() override; virtual void beginFrame() override;
virtual void render() override; virtual void render() override;
@@ -19,7 +20,9 @@ public:
virtual void createRenderPass() override; virtual void createRenderPass() override;
static void modifyRenderPassMacros(Map<const char*, const char*>& defines); static void modifyRenderPassMacros(Map<const char*, const char*>& defines);
private: private:
void setupFrustums();
static constexpr uint32 BLOCK_SIZE = 8; static constexpr uint32 BLOCK_SIZE = 8;
static constexpr uint32 INDEX_LIGHT_ENV = 1;
_declspec(align(16)) struct DispatchParams _declspec(align(16)) struct DispatchParams
{ {
glm::uvec3 numThreadGroups; glm::uvec3 numThreadGroups;
@@ -39,13 +42,36 @@ private:
{ {
Plane planes[4]; Plane planes[4];
}; };
struct ScreenToView
{ PScene scene;
Matrix4 inverseProjection;
Vector2 screenDimensions;
};
Gfx::PViewport viewport; Gfx::PViewport viewport;
Gfx::PGraphics graphics; Gfx::PGraphics graphics;
Gfx::PStructuredBuffer frustumBuffer;
Gfx::PUniformBuffer dispatchParamsBuffer;
Gfx::PUniformBuffer viewParamsBuffer;
Gfx::PDescriptorSet frustumDescriptorSet;
Gfx::PComputeShader frustumShader;
Gfx::PPipelineLayout frustumLayout;
Gfx::PComputePipeline frustumPipeline;
Gfx::PTexture2D depthAttachment;
//Gfx::PTexture2D depthComputeTexture;
Gfx::PStructuredBuffer frustums;
Gfx::PStructuredBuffer oLightIndexCounter;
Gfx::PStructuredBuffer tLightIndexCounter;
Gfx::PStructuredBuffer oLightIndexList;
Gfx::PStructuredBuffer tLightIndexList;
Gfx::PTexture2D oLightGrid;
Gfx::PTexture2D tLightGrid;
Gfx::PDescriptorSet lightEnvDescriptorSet;
Gfx::PDescriptorSet cullingDescriptorSet;
Gfx::PDescriptorLayout lightEnvDescriptorLayout;
Gfx::PDescriptorLayout cullingDescriptorLayout;
Gfx::PComputeShader cullingShader;
Gfx::PPipelineLayout cullingLayout;
Gfx::PComputePipeline cullingPipeline;
PCameraComponent source; PCameraComponent source;
}; };
DEFINE_REF(LightCullingPass)
} // namespace Seele } // namespace Seele
@@ -23,6 +23,11 @@ void RenderGraph::setup()
} }
} }
void RenderGraph::addRenderPass(PRenderPass renderPass)
{
renderPasses.add(renderPass);
}
Gfx::PRenderTargetAttachment RenderGraph::requestRenderTarget(const std::string& outputName) Gfx::PRenderTargetAttachment RenderGraph::requestRenderTarget(const std::string& outputName)
{ {
if(registeredAttachments.find(outputName) == registeredAttachments.end()) if(registeredAttachments.find(outputName) == registeredAttachments.end())
@@ -33,7 +38,38 @@ Gfx::PRenderTargetAttachment RenderGraph::requestRenderTarget(const std::string&
return registeredAttachments[outputName]; return registeredAttachments[outputName];
} }
Gfx::PTexture RenderGraph::requestTexture(const std::string& outputName)
{
if(registeredTextures.find(outputName) == registeredTextures.end())
{
std::cout << "Attachment " << outputName << " not found" << std::endl;
return nullptr;
}
return registeredTextures[outputName];
}
Gfx::PStructuredBuffer RenderGraph::requestBuffer(const std::string& outputName)
{
if(registeredBuffers.find(outputName) == registeredBuffers.end())
{
std::cout << "Attachment " << outputName << " not found" << std::endl;
return nullptr;
}
return registeredBuffers[outputName];
}
void RenderGraph::registerRenderPassOutput(const std::string& outputName, Gfx::PRenderTargetAttachment attachment) void RenderGraph::registerRenderPassOutput(const std::string& outputName, Gfx::PRenderTargetAttachment attachment)
{ {
registeredAttachments[outputName] = attachment; registeredAttachments[outputName] = attachment;
} }
void RenderGraph::registerTextureOutput(const std::string& outputName, Gfx::PTexture texture)
{
registeredTextures[outputName] = texture;
}
void RenderGraph::registerBufferOutput(const std::string& outputName, Gfx::PStructuredBuffer buffer)
{
registeredBuffers[outputName] = buffer;
}
+8 -1
View File
@@ -11,10 +11,17 @@ public:
RenderGraph(); RenderGraph();
~RenderGraph(); ~RenderGraph();
void setup(); void setup();
void addRenderPass(PRenderPass renderPass);
Gfx::PRenderTargetAttachment requestRenderTarget(const std::string& outputName); Gfx::PRenderTargetAttachment requestRenderTarget(const std::string& outputName);
void registerRenderPassOutput(const std::string& ouputName, Gfx::PRenderTargetAttachment attachment); Gfx::PTexture requestTexture(const std::string& outputName);
Gfx::PStructuredBuffer requestBuffer(const std::string& outputName);
void registerRenderPassOutput(const std::string& outputName, Gfx::PRenderTargetAttachment attachment);
void registerTextureOutput(const std::string& outputName, Gfx::PTexture buffer);
void registerBufferOutput(const std::string& outputName, Gfx::PStructuredBuffer buffer);
private: private:
Map<std::string, Gfx::PRenderTargetAttachment> registeredAttachments; Map<std::string, Gfx::PRenderTargetAttachment> registeredAttachments;
Map<std::string, Gfx::PTexture> registeredTextures;
Map<std::string, Gfx::PStructuredBuffer> registeredBuffers;
List<PRenderPass> renderPasses; List<PRenderPass> renderPasses;
}; };
DEFINE_REF(RenderGraph) DEFINE_REF(RenderGraph)
+2 -5
View File
@@ -21,13 +21,10 @@ protected:
{ {
Matrix4 viewMatrix; Matrix4 viewMatrix;
Matrix4 projectionMatrix; Matrix4 projectionMatrix;
Vector4 cameraPosition;
} viewParams;
struct ScreenToViewParameter
{
Matrix4 inverseProjectionMatrix; Matrix4 inverseProjectionMatrix;
Vector2 screenDimensions; Vector2 screenDimensions;
} screenToViewParams; Vector4 cameraPosition;
} viewParams;
Gfx::PRenderPass renderPass; Gfx::PRenderPass renderPass;
PRenderGraph renderGraph; PRenderGraph renderGraph;
}; };
+77 -37
View File
@@ -16,21 +16,19 @@ struct PendingBuffer
static Map<ShaderBuffer *, PendingBuffer> pendingBuffers; static Map<ShaderBuffer *, PendingBuffer> pendingBuffers;
ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType) ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic)
: graphics(graphics) : graphics(graphics)
, currentBuffer(0) , currentBuffer(0)
, size(size) , size(size)
, currentOwner(queueType) , owner(queueType)
{ {
if (usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT || if(bDynamic)
usage & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT ||
usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)
{ {
numBuffers = 1; numBuffers = Gfx::numFramesBuffered;
} }
else else
{ {
numBuffers = Gfx::numFramesBuffered; numBuffers = 1;
} }
usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
@@ -63,7 +61,7 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags u
ShaderBuffer::~ShaderBuffer() ShaderBuffer::~ShaderBuffer()
{ {
auto cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands(); auto cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
auto &deletionQueue = graphics->getDeletionQueue(); auto &deletionQueue = graphics->getDeletionQueue();
VkDevice device = graphics->getDevice(); VkDevice device = graphics->getDevice();
VkBuffer buf[Gfx::numFramesBuffered]; VkBuffer buf[Gfx::numFramesBuffered];
@@ -85,25 +83,25 @@ void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{ {
VkBufferMemoryBarrier barrier = VkBufferMemoryBarrier barrier =
init::BufferMemoryBarrier(); init::BufferMemoryBarrier();
PCommandBufferManager sourceManager = graphics->getQueueCommands(currentOwner); PCommandBufferManager sourceManager = graphics->getQueueCommands(owner);
PCommandBufferManager dstManager = nullptr; PCommandBufferManager dstManager = nullptr;
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping(); Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
barrier.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(currentOwner); barrier.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner);
barrier.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner); barrier.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner);
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex); assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
if (currentOwner == Gfx::QueueType::TRANSFER || currentOwner == Gfx::QueueType::DEDICATED_TRANSFER) if (owner == Gfx::QueueType::TRANSFER || owner == Gfx::QueueType::DEDICATED_TRANSFER)
{ {
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT; srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
} }
else if (currentOwner == Gfx::QueueType::COMPUTE) else if (owner == Gfx::QueueType::COMPUTE)
{ {
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
} }
else if (currentOwner == Gfx::QueueType::GRAPHICS) else if (owner == Gfx::QueueType::GRAPHICS)
{ {
barrier.srcAccessMask = getSourceAccessMask(); barrier.srcAccessMask = getSourceAccessMask();
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
@@ -135,17 +133,36 @@ void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
VkCommandBuffer srcCommand = sourceManager->getCommands()->getHandle(); VkCommandBuffer srcCommand = sourceManager->getCommands()->getHandle();
VkCommandBuffer dstCommand = dstManager->getCommands()->getHandle(); VkCommandBuffer dstCommand = dstManager->getCommands()->getHandle();
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered]; VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
for (uint32_t i = 0; i < numBuffers; ++i) barrier.offset = 0;
barrier.size = size;
for (uint32 i = 0; i < numBuffers; ++i)
{ {
dynamicBarriers[i] = barrier; dynamicBarriers[i] = barrier;
dynamicBarriers[i].buffer = buffers[i].buffer; dynamicBarriers[i].buffer = buffers[i].buffer;
dynamicBarriers[i].offset = 0;
dynamicBarriers[i].size = size;
} }
vkCmdPipelineBarrier(srcCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr); vkCmdPipelineBarrier(srcCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
vkCmdPipelineBarrier(dstCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr); vkCmdPipelineBarrier(dstCommand, srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
sourceManager->submitCommands(); sourceManager->submitCommands();
currentOwner = newOwner; }
void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
PCmdBuffer commandBuffer = graphics->getQueueCommands(owner)->getCommands();
VkBufferMemoryBarrier barrier = init::BufferMemoryBarrier();
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstAccessMask = dstAccess;
barrier.srcAccessMask = srcAccess;
barrier.offset = 0;
barrier.size = size;
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
for(uint32 i = 0; i < numBuffers; ++i)
{
dynamicBarriers[i] = barrier;
dynamicBarriers[i].buffer = buffers[i].buffer;
}
vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
} }
void *ShaderBuffer::lock(bool bWriteOnly) void *ShaderBuffer::lock(bool bWriteOnly)
@@ -168,7 +185,7 @@ void *ShaderBuffer::lock(bool bWriteOnly)
PendingBuffer pending; PendingBuffer pending;
pending.bWriteOnly = bWriteOnly; pending.bWriteOnly = bWriteOnly;
pending.prevQueue = currentOwner; pending.prevQueue = owner;
if (bWriteOnly) if (bWriteOnly)
{ {
//requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER); //requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
@@ -178,12 +195,12 @@ void *ShaderBuffer::lock(bool bWriteOnly)
} }
else else
{ {
PCmdBuffer current = graphics->getQueueCommands(currentOwner)->getCommands(); PCmdBuffer current = graphics->getQueueCommands(owner)->getCommands();
graphics->getQueueCommands(currentOwner)->submitCommands(); graphics->getQueueCommands(owner)->submitCommands();
graphics->getQueueCommands(currentOwner)->waitForCommands(current); current->waitForCommand();
requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER); requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
VkCommandBuffer handle = graphics->getQueueCommands(currentOwner)->getCommands()->getHandle(); VkCommandBuffer handle = graphics->getQueueCommands(owner)->getCommands()->getHandle();
VkBufferMemoryBarrier barrier = VkBufferMemoryBarrier barrier =
init::BufferMemoryBarrier(); init::BufferMemoryBarrier();
@@ -205,8 +222,8 @@ void *ShaderBuffer::lock(bool bWriteOnly)
vkCmdCopyBuffer(handle, buffers[currentBuffer].buffer, stagingBuffer->getHandle(), 1, &regions); vkCmdCopyBuffer(handle, buffers[currentBuffer].buffer, stagingBuffer->getHandle(), 1, &regions);
graphics->getQueueCommands(currentOwner)->submitCommands(); graphics->getQueueCommands(owner)->submitCommands();
vkQueueWaitIdle(graphics->getQueueCommands(currentOwner)->getQueue()->getHandle()); vkQueueWaitIdle(graphics->getQueueCommands(owner)->getQueue()->getHandle());
stagingBuffer->flushMappedMemory(); stagingBuffer->flushMappedMemory();
pending.stagingBuffer = stagingBuffer; pending.stagingBuffer = stagingBuffer;
@@ -230,14 +247,14 @@ void ShaderBuffer::unlock()
if (pending.bWriteOnly) if (pending.bWriteOnly)
{ {
PStagingBuffer stagingBuffer = pending.stagingBuffer; PStagingBuffer stagingBuffer = pending.stagingBuffer;
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands(); PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
VkCommandBuffer cmdHandle = cmdBuffer->getHandle(); VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
VkBufferCopy region; VkBufferCopy region;
std::memset(&region, 0, sizeof(VkBufferCopy)); std::memset(&region, 0, sizeof(VkBufferCopy));
region.size = size; region.size = size;
vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, &region); vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, &region);
graphics->getQueueCommands(currentOwner)->submitCommands(); graphics->getQueueCommands(owner)->submitCommands();
} }
//requestOwnershipTransfer(pending.prevQueue); //requestOwnershipTransfer(pending.prevQueue);
graphics->getStagingManager()->releaseStagingBuffer(pending.stagingBuffer); graphics->getStagingManager()->releaseStagingBuffer(pending.stagingBuffer);
@@ -246,7 +263,7 @@ void ShaderBuffer::unlock()
UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &createInfo) UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &createInfo)
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.resourceData) : Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.resourceData)
, Vulkan::ShaderBuffer(graphics, createInfo.resourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, createInfo.resourceData.owner) , Vulkan::ShaderBuffer(graphics, createInfo.resourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, createInfo.bDynamic)
, dedicatedStagingBuffer(nullptr) , dedicatedStagingBuffer(nullptr)
{ {
if(createInfo.bDynamic) if(createInfo.bDynamic)
@@ -291,14 +308,14 @@ void UniformBuffer::unlock()
if(dedicatedStagingBuffer != nullptr) if(dedicatedStagingBuffer != nullptr)
{ {
dedicatedStagingBuffer->flushMappedMemory(); dedicatedStagingBuffer->flushMappedMemory();
PCmdBuffer cmdBuffer = graphics->getQueueCommands(ShaderBuffer::currentOwner)->getCommands(); PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
VkCommandBuffer cmdHandle = cmdBuffer->getHandle(); VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
VkBufferCopy region; VkBufferCopy region;
std::memset(&region, 0, sizeof(VkBufferCopy)); std::memset(&region, 0, sizeof(VkBufferCopy));
region.size = ShaderBuffer::size; region.size = ShaderBuffer::size;
vkCmdCopyBuffer(cmdHandle, dedicatedStagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, &region); vkCmdCopyBuffer(cmdHandle, dedicatedStagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, &region);
graphics->getQueueCommands(ShaderBuffer::currentOwner)->submitCommands(); graphics->getQueueCommands(currentOwner)->submitCommands();
} }
else else
{ {
@@ -309,7 +326,6 @@ void UniformBuffer::unlock()
void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
{ {
Gfx::QueueOwnedResource::transferOwnership(newOwner); Gfx::QueueOwnedResource::transferOwnership(newOwner);
Vulkan::ShaderBuffer::currentOwner = newOwner;
} }
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
@@ -317,6 +333,12 @@ void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner); Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
} }
void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
Vulkan::ShaderBuffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
VkAccessFlags UniformBuffer::getSourceAccessMask() VkAccessFlags UniformBuffer::getSourceAccessMask()
{ {
return VK_ACCESS_MEMORY_WRITE_BIT; return VK_ACCESS_MEMORY_WRITE_BIT;
@@ -327,14 +349,14 @@ VkAccessFlags UniformBuffer::getDestAccessMask()
return VK_ACCESS_UNIFORM_READ_BIT; return VK_ACCESS_UNIFORM_READ_BIT;
} }
StructuredBuffer::StructuredBuffer(PGraphics graphics, const BulkResourceData &resourceData) StructuredBuffer::StructuredBuffer(PGraphics graphics, const StructuredBufferCreateInfo &resourceData)
: Gfx::StructuredBuffer(graphics->getFamilyMapping(), resourceData.owner) : Gfx::StructuredBuffer(graphics->getFamilyMapping(), resourceData.resourceData.owner)
, Vulkan::ShaderBuffer(graphics, resourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, resourceData.owner) , Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, resourceData.bDynamic)
{ {
if (resourceData.data != nullptr) if (resourceData.resourceData.data != nullptr)
{ {
void *data = lock(); void *data = lock();
std::memcpy(data, resourceData.data, resourceData.size); std::memcpy(data, resourceData.resourceData.data, resourceData.resourceData.size);
unlock(); unlock();
} }
} }
@@ -353,6 +375,12 @@ void StructuredBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner); Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
} }
void StructuredBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
Vulkan::ShaderBuffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
VkAccessFlags StructuredBuffer::getSourceAccessMask() VkAccessFlags StructuredBuffer::getSourceAccessMask()
{ {
return VK_ACCESS_MEMORY_WRITE_BIT; return VK_ACCESS_MEMORY_WRITE_BIT;
@@ -365,7 +393,7 @@ VkAccessFlags StructuredBuffer::getDestAccessMask()
VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData) VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData)
: Gfx::VertexBuffer(graphics->getFamilyMapping(), resourceData.numVertices, resourceData.vertexSize, resourceData.resourceData.owner) : Gfx::VertexBuffer(graphics->getFamilyMapping(), resourceData.numVertices, resourceData.vertexSize, resourceData.resourceData.owner)
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, resourceData.resourceData.owner) , Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, currentOwner)
{ {
if (resourceData.resourceData.data != nullptr) if (resourceData.resourceData.data != nullptr)
{ {
@@ -389,6 +417,12 @@ void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner); Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
} }
void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
Vulkan::ShaderBuffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
VkAccessFlags VertexBuffer::getSourceAccessMask() VkAccessFlags VertexBuffer::getSourceAccessMask()
{ {
return VK_ACCESS_MEMORY_WRITE_BIT; return VK_ACCESS_MEMORY_WRITE_BIT;
@@ -401,7 +435,7 @@ VkAccessFlags VertexBuffer::getDestAccessMask()
IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData) IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData)
: Gfx::IndexBuffer(graphics->getFamilyMapping(), resourceData.resourceData.size, resourceData.indexType, resourceData.resourceData.owner) : Gfx::IndexBuffer(graphics->getFamilyMapping(), resourceData.resourceData.size, resourceData.indexType, resourceData.resourceData.owner)
, Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, resourceData.resourceData.owner) , Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, currentOwner)
{ {
if (resourceData.resourceData.data != nullptr) if (resourceData.resourceData.data != nullptr)
{ {
@@ -425,6 +459,12 @@ void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner); Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
} }
void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
Vulkan::ShaderBuffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
VkAccessFlags IndexBuffer::getSourceAccessMask() VkAccessFlags IndexBuffer::getSourceAccessMask()
{ {
return VK_ACCESS_MEMORY_WRITE_BIT; return VK_ACCESS_MEMORY_WRITE_BIT;
@@ -84,20 +84,38 @@ void CmdBuffer::endRenderPass()
state = State::InsideBegin; state = State::InsideBegin;
} }
void CmdBuffer::executeCommands(Array<Gfx::PRenderCommand> commands) void CmdBuffer::executeCommands(const Array<Gfx::PRenderCommand>& commands)
{ {
assert(state == State::RenderPassActive); assert(state == State::RenderPassActive);
Array<VkCommandBuffer> cmdBuffers(commands.size()); Array<VkCommandBuffer> cmdBuffers(commands.size());
for (uint32 i = 0; i < commands.size(); ++i) for (uint32 i = 0; i < commands.size(); ++i)
{ {
auto command = commands[i].cast<SecondaryCmdBuffer>(); auto command = commands[i].cast<RenderCommand>();
// Cache array and size to save on pointer access // Cache array and size to save on pointer access
for(auto boundDescriptor : command->boundDescriptors) for(auto boundDescriptor : command->boundDescriptors)
{ {
boundDescriptor->currentlyBound = this; boundDescriptor->currentlyBound = this;
} }
command->end(); command->end();
executingCommands.add(command); executingRenders.add(command);
cmdBuffers[i] = command->getHandle();
}
vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data());
}
void CmdBuffer::executeCommands(const Array<Gfx::PComputeCommand>& commands)
{
Array<VkCommandBuffer> cmdBuffers(commands.size());
for (uint32 i = 0; i < commands.size(); ++i)
{
auto command = commands[i].cast<ComputeCommand>();
// Cache array and size to save on pointer access
for(auto boundDescriptor : command->boundDescriptors)
{
boundDescriptor->currentlyBound = this;
}
command->end();
executingComputes.add(command);
cmdBuffers[i] = command->getHandle(); cmdBuffers[i] = command->getHandle();
} }
vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data()); vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data());
@@ -117,11 +135,16 @@ void CmdBuffer::refreshFence()
{ {
vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT); vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
fence->reset(); fence->reset();
for(auto command : executingCommands) for(auto command : executingComputes)
{ {
command->reset(); command->reset();
} }
executingCommands.clear(); executingComputes.clear();
for(auto command : executingRenders)
{
command->reset();
}
executingRenders.clear();
state = State::ReadyBegin; state = State::ReadyBegin;
} }
} }
@@ -131,6 +154,13 @@ void CmdBuffer::refreshFence()
} }
} }
void CmdBuffer::waitForCommand(uint32 timeout)
{
fence->wait(timeout);
refreshFence();
}
PFence CmdBuffer::getFence() PFence CmdBuffer::getFence()
{ {
return fence; return fence;
@@ -157,20 +187,6 @@ SecondaryCmdBuffer::~SecondaryCmdBuffer()
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle); vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
} }
void SecondaryCmdBuffer::begin(PCmdBuffer parent)
{
ready = false;
VkCommandBufferBeginInfo beginInfo =
init::CommandBufferBeginInfo();
VkCommandBufferInheritanceInfo inheritanceInfo =
init::CommandBufferInheritanceInfo();
inheritanceInfo.framebuffer = parent->framebuffer->getHandle();
inheritanceInfo.renderPass = parent->renderPass->getHandle();
inheritanceInfo.subpass = parent->subpassIndex;
beginInfo.pInheritanceInfo = &inheritanceInfo;
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
}
void SecondaryCmdBuffer::end() void SecondaryCmdBuffer::end()
{ {
@@ -188,12 +204,37 @@ void SecondaryCmdBuffer::reset()
ready = true; ready = true;
} }
bool SecondaryCmdBuffer::isReady() RenderCommand::RenderCommand(PGraphics graphics, VkCommandPool cmdPool)
: SecondaryCmdBuffer(graphics, cmdPool)
{}
RenderCommand::~RenderCommand()
{
}
void RenderCommand::begin(PCmdBuffer parent)
{
ready = false;
VkCommandBufferBeginInfo beginInfo =
init::CommandBufferBeginInfo();
VkCommandBufferInheritanceInfo inheritanceInfo =
init::CommandBufferInheritanceInfo();
inheritanceInfo.framebuffer = parent->framebuffer->getHandle();
inheritanceInfo.renderPass = parent->renderPass->getHandle();
inheritanceInfo.subpass = parent->subpassIndex;
beginInfo.pInheritanceInfo = &inheritanceInfo;
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
}
bool RenderCommand::isReady()
{ {
return ready; return ready;
} }
void SecondaryCmdBuffer::setViewport(Gfx::PViewport viewport) void RenderCommand::setViewport(Gfx::PViewport viewport)
{ {
VkViewport vp = viewport.cast<Viewport>()->getHandle(); VkViewport vp = viewport.cast<Viewport>()->getHandle();
VkRect2D scissors = init::Rect2D(viewport->getSizeX(), viewport->getSizeY(), viewport->getOffsetX(), viewport->getOffsetY()); VkRect2D scissors = init::Rect2D(viewport->getSizeX(), viewport->getSizeY(), viewport->getOffsetX(), viewport->getOffsetY());
@@ -201,19 +242,19 @@ void SecondaryCmdBuffer::setViewport(Gfx::PViewport viewport)
vkCmdSetScissor(handle, 0, 1, &scissors); vkCmdSetScissor(handle, 0, 1, &scissors);
} }
void SecondaryCmdBuffer::bindPipeline(Gfx::PGraphicsPipeline gfxPipeline) void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline gfxPipeline)
{ {
pipeline = gfxPipeline.cast<GraphicsPipeline>(); pipeline = gfxPipeline.cast<GraphicsPipeline>();
pipeline->bind(handle); pipeline->bind(handle);
} }
void SecondaryCmdBuffer::bindDescriptor(Gfx::PDescriptorSet descriptorSet) void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet)
{ {
auto descriptor = descriptorSet.cast<DescriptorSet>(); auto descriptor = descriptorSet.cast<DescriptorSet>();
boundDescriptors.add(descriptor.getHandle()); boundDescriptors.add(descriptor.getHandle());
VkDescriptorSet setHandle = descriptor->getHandle(); VkDescriptorSet setHandle = descriptor->getHandle();
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), descriptorSet->getSetIndex(), 1, &setHandle, 0, nullptr); vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), descriptorSet->getSetIndex(), 1, &setHandle, 0, nullptr);
} }
void SecondaryCmdBuffer::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets)
{ {
VkDescriptorSet* sets = new VkDescriptorSet[descriptorSets.size()]; VkDescriptorSet* sets = new VkDescriptorSet[descriptorSets.size()];
for(uint32 i = 0; i < descriptorSets.size(); ++i) for(uint32 i = 0; i < descriptorSets.size(); ++i)
@@ -225,7 +266,7 @@ void SecondaryCmdBuffer::bindDescriptor(const Array<Gfx::PDescriptorSet>& descri
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets, 0, nullptr); vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets, 0, nullptr);
delete[] sets; delete[] sets;
} }
void SecondaryCmdBuffer::bindVertexBuffer(const Array<VertexInputStream>& streams) void RenderCommand::bindVertexBuffer(const Array<VertexInputStream>& streams)
{ {
Array<VkBuffer> buffers(streams.size()); Array<VkBuffer> buffers(streams.size());
Array<VkDeviceSize> offsets(streams.size()); Array<VkDeviceSize> offsets(streams.size());
@@ -237,16 +278,76 @@ void SecondaryCmdBuffer::bindVertexBuffer(const Array<VertexInputStream>& stream
}; };
vkCmdBindVertexBuffers(handle, 0, (uint32)streams.size(), buffers.data(), offsets.data()); vkCmdBindVertexBuffers(handle, 0, (uint32)streams.size(), buffers.data(), offsets.data());
} }
void SecondaryCmdBuffer::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer)
{ {
PIndexBuffer buf = indexBuffer.cast<IndexBuffer>(); PIndexBuffer buf = indexBuffer.cast<IndexBuffer>();
vkCmdBindIndexBuffer(handle, buf->getHandle(), 0, cast(buf->getIndexType())); vkCmdBindIndexBuffer(handle, buf->getHandle(), 0, cast(buf->getIndexType()));
} }
void SecondaryCmdBuffer::draw(const MeshBatchElement& data) void RenderCommand::draw(const MeshBatchElement& data)
{ {
vkCmdDrawIndexed(handle, data.indexBuffer->getNumIndices(), data.numInstances, data.minVertexIndex, data.baseVertexIndex, 0); vkCmdDrawIndexed(handle, data.indexBuffer->getNumIndices(), data.numInstances, data.minVertexIndex, data.baseVertexIndex, 0);
} }
ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool)
: SecondaryCmdBuffer(graphics, cmdPool)
{
}
ComputeCommand::~ComputeCommand()
{
}
void ComputeCommand::begin(PCmdBuffer parent)
{
ready = false;
VkCommandBufferBeginInfo beginInfo =
init::CommandBufferBeginInfo();
VkCommandBufferInheritanceInfo inheritanceInfo =
init::CommandBufferInheritanceInfo();
inheritanceInfo.framebuffer = VK_NULL_HANDLE;
inheritanceInfo.renderPass = VK_NULL_HANDLE;
inheritanceInfo.subpass = 0;
beginInfo.pInheritanceInfo = &inheritanceInfo;
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
}
bool ComputeCommand::isReady()
{
return ready;
}
void ComputeCommand::bindPipeline(Gfx::PComputePipeline computePipeline)
{
pipeline = computePipeline.cast<ComputePipeline>();
pipeline->bind(handle);
}
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet)
{
auto descriptor = descriptorSet.cast<DescriptorSet>();
boundDescriptors.add(descriptor.getHandle());
VkDescriptorSet setHandle = descriptor->getHandle();
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(), descriptorSet->getSetIndex(), 1, &setHandle, 0, nullptr);
}
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets)
{
VkDescriptorSet* sets = new VkDescriptorSet[descriptorSets.size()];
for(uint32 i = 0; i < descriptorSets.size(); ++i)
{
auto descriptorSet = descriptorSets[i].cast<DescriptorSet>();
boundDescriptors.add(descriptorSet.getHandle());
sets[descriptorSet->getSetIndex()] = descriptorSet->getHandle();
}
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets, 0, nullptr);
delete[] sets;
}
void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ)
{
vkCmdDispatch(handle, threadX, threadY, threadZ);
}
CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue) CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue)
: graphics(graphics), queue(queue), queueFamilyIndex(queue->getFamilyIndex()) : graphics(graphics), queue(queue), queueFamilyIndex(queue->getFamilyIndex())
{ {
@@ -275,20 +376,40 @@ PCmdBuffer CommandBufferManager::getCommands()
return activeCmdBuffer; return activeCmdBuffer;
} }
PSecondaryCmdBuffer CommandBufferManager::createSecondaryCmdBuffer() PRenderCommand CommandBufferManager::createRenderCommand(const std::string& name)
{ {
std::scoped_lock lck(allocatedSecondBufferLock); std::scoped_lock lck(allocatedRenderLock);
for (uint32 i = 0; i < allocatedSecondBuffers.size(); ++i) for (uint32 i = 0; i < allocatedRenderCommands.size(); ++i)
{ {
PSecondaryCmdBuffer cmdBuffer = allocatedSecondBuffers[i]; PRenderCommand cmdBuffer = allocatedRenderCommands[i];
if (cmdBuffer->isReady()) if (cmdBuffer->ready)
{ {
cmdBuffer->begin(activeCmdBuffer); cmdBuffer->begin(activeCmdBuffer);
return cmdBuffer; return cmdBuffer;
} }
} }
PSecondaryCmdBuffer result = new SecondaryCmdBuffer(graphics, commandPool); PRenderCommand result = new RenderCommand(graphics, commandPool);
allocatedSecondBuffers.add(result); result->name = name;
allocatedRenderCommands.add(result);
result->begin(activeCmdBuffer);
return result;
}
PComputeCommand CommandBufferManager::createComputeCommand(const std::string& name)
{
std::scoped_lock lck(allocatedComputeLock);
for (uint32 i = 0; i < allocatedComputeCommands.size(); ++i)
{
PComputeCommand cmdBuffer = allocatedComputeCommands[i];
if (cmdBuffer->ready)
{
cmdBuffer->begin(activeCmdBuffer);
return cmdBuffer;
}
}
PComputeCommand result = new ComputeCommand(graphics, commandPool);
result->name = name;
allocatedComputeCommands.add(result);
result->begin(activeCmdBuffer); result->begin(activeCmdBuffer);
return result; return result;
} }
@@ -332,9 +453,3 @@ void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
allocatedBuffers.add(activeCmdBuffer); allocatedBuffers.add(activeCmdBuffer);
activeCmdBuffer->begin(); activeCmdBuffer->begin();
} }
void CommandBufferManager::waitForCommands(PCmdBuffer cmdBuffer, uint32 timeout)
{
cmdBuffer->fence->wait(timeout);
cmdBuffer->refreshFence();
}
@@ -29,7 +29,8 @@ protected:
}; };
DEFINE_REF(CmdBufferBase) DEFINE_REF(CmdBufferBase)
DECLARE_REF(SecondaryCmdBuffer) DECLARE_REF(RenderCommand)
DECLARE_REF(ComputeCommand)
DECLARE_REF(CommandBufferManager) DECLARE_REF(CommandBufferManager)
class CmdBuffer : public CmdBufferBase class CmdBuffer : public CmdBufferBase
{ {
@@ -40,9 +41,11 @@ public:
void end(); void end();
void beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer); void beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer);
void endRenderPass(); void endRenderPass();
void executeCommands(Array<Gfx::PRenderCommand> secondaryCommands); void executeCommands(const Array<Gfx::PRenderCommand>& secondaryCommands);
void executeCommands(const Array<Gfx::PComputeCommand>& secondaryCommands);
void addWaitSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore); void addWaitSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore);
void refreshFence(); void refreshFence();
void waitForCommand(uint32 timeToWait = 1000000u);
PFence getFence(); PFence getFence();
PCommandBufferManager getManager(); PCommandBufferManager getManager();
enum State enum State
@@ -63,23 +66,40 @@ private:
State state; State state;
Array<PSemaphore> waitSemaphores; Array<PSemaphore> waitSemaphores;
Array<VkPipelineStageFlags> waitFlags; Array<VkPipelineStageFlags> waitFlags;
Array<PSecondaryCmdBuffer> executingCommands; Array<PRenderCommand> executingRenders;
friend class SecondaryCmdBuffer; Array<PComputeCommand> executingComputes;
friend class RenderCommand;
friend class CommandBufferManager; friend class CommandBufferManager;
friend class Queue; friend class Queue;
}; };
DEFINE_REF(CmdBuffer) DEFINE_REF(CmdBuffer)
DECLARE_REF(GraphicsPipeline) DECLARE_REF(GraphicsPipeline)
DECLARE_REF(ComputePipeline)
DECLARE_REF(DescriptorSet) DECLARE_REF(DescriptorSet)
class SecondaryCmdBuffer : public Gfx::RenderCommand, public CmdBufferBase
class SecondaryCmdBuffer: public CmdBufferBase
{ {
public: public:
SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool); SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool);
virtual ~SecondaryCmdBuffer(); virtual ~SecondaryCmdBuffer();
void begin(PCmdBuffer parent); virtual void begin(PCmdBuffer parent) = 0;
void end(); void end();
void reset(); void reset();
bool ready;
protected:
Array<DescriptorSet*> boundDescriptors;
friend class CmdBuffer;
};
DEFINE_REF(SecondaryCmdBuffer);
class RenderCommand : public Gfx::RenderCommand, public SecondaryCmdBuffer
{
public:
RenderCommand(PGraphics graphics, VkCommandPool cmdPool);
virtual ~RenderCommand();
virtual void begin(PCmdBuffer parent) override;
virtual bool isReady() override; virtual bool isReady() override;
virtual void setViewport(Gfx::PViewport viewport) override; virtual void setViewport(Gfx::PViewport viewport) override;
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override; virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
@@ -91,12 +111,26 @@ public:
private: private:
PGraphicsPipeline pipeline; PGraphicsPipeline pipeline;
Array<DescriptorSet*> boundDescriptors;
bool ready;
friend class CmdBuffer; friend class CmdBuffer;
}; };
DEFINE_REF(SecondaryCmdBuffer) DEFINE_REF(RenderCommand)
class ComputeCommand : public Gfx::ComputeCommand, public SecondaryCmdBuffer
{
public:
ComputeCommand(PGraphics graphics, VkCommandPool cmdPool);
virtual ~ComputeCommand();
virtual void begin(PCmdBuffer parent) override;
virtual bool isReady() override;
virtual void bindPipeline(Gfx::PComputePipeline pipeline) override;
virtual void bindDescriptor(Gfx::PDescriptorSet set) override;
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) override;
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override;
private:
PComputePipeline pipeline;
friend class CmdBuffer;
};
DEFINE_REF(ComputeCommand)
class CommandBufferManager class CommandBufferManager
{ {
public: public:
@@ -107,9 +141,9 @@ public:
return queue; return queue;
} }
PCmdBuffer getCommands(); PCmdBuffer getCommands();
PSecondaryCmdBuffer createSecondaryCmdBuffer(); PRenderCommand createRenderCommand(const std::string& name);
PComputeCommand createComputeCommand(const std::string& name);
void submitCommands(PSemaphore signalSemaphore = nullptr); void submitCommands(PSemaphore signalSemaphore = nullptr);
void waitForCommands(PCmdBuffer cmdBuffer, uint32 timeToWait = 1000000u);
private: private:
PGraphics graphics; PGraphics graphics;
@@ -119,8 +153,10 @@ private:
PCmdBuffer activeCmdBuffer; PCmdBuffer activeCmdBuffer;
std::mutex allocatedBufferLock; std::mutex allocatedBufferLock;
Array<PCmdBuffer> allocatedBuffers; Array<PCmdBuffer> allocatedBuffers;
std::mutex allocatedSecondBufferLock; std::mutex allocatedRenderLock;
Array<PSecondaryCmdBuffer> allocatedSecondBuffers; std::mutex allocatedComputeLock;
Array<PRenderCommand> allocatedRenderCommands;
Array<PComputeCommand> allocatedComputeCommands;
}; };
DEFINE_REF(CommandBufferManager) DEFINE_REF(CommandBufferManager)
} // namespace Vulkan } // namespace Vulkan
@@ -117,7 +117,7 @@ DescriptorSet::~DescriptorSet()
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer)
{ {
PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>(); PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>();
UniformBuffer* cachedBuffer = reinterpret_cast<UniformBuffer*>(cachedData[Gfx::currentFrameIndex][binding]); UniformBuffer* cachedBuffer = reinterpret_cast<UniformBuffer*>(cachedData[binding]);
/*if(vulkanBuffer->isDataEquals(cachedBuffer)) /*if(vulkanBuffer->isDataEquals(cachedBuffer))
{ {
std::cout << "uniform data equal, skip" << std::endl; std::cout << "uniform data equal, skip" << std::endl;
@@ -125,32 +125,32 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBu
}*/ }*/
bufferInfos.add(init::DescriptorBufferInfo(vulkanBuffer->getHandle(), 0, vulkanBuffer->getSize())); bufferInfos.add(init::DescriptorBufferInfo(vulkanBuffer->getHandle(), 0, vulkanBuffer->getSize()));
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle[Gfx::currentFrameIndex], VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, binding, &bufferInfos.back()); VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, binding, &bufferInfos.back());
writeDescriptors.add(writeDescriptor); writeDescriptors.add(writeDescriptor);
cachedData[Gfx::currentFrameIndex][binding] = new UniformBuffer(*vulkanBuffer.getHandle()); cachedData[binding] = new UniformBuffer(*vulkanBuffer.getHandle());
} }
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer) void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer)
{ {
PStructuredBuffer vulkanBuffer = uniformBuffer.cast<StructuredBuffer>(); PStructuredBuffer vulkanBuffer = uniformBuffer.cast<StructuredBuffer>();
StructuredBuffer* cachedBuffer = reinterpret_cast<StructuredBuffer*>(cachedData[Gfx::currentFrameIndex][binding]); StructuredBuffer* cachedBuffer = reinterpret_cast<StructuredBuffer*>(cachedData[binding]);
if(vulkanBuffer.getHandle() == cachedBuffer) if(vulkanBuffer.getHandle() == cachedBuffer)
{ {
return; return;
} }
bufferInfos.add(init::DescriptorBufferInfo(vulkanBuffer->getHandle(), 0, vulkanBuffer->getSize())); bufferInfos.add(init::DescriptorBufferInfo(vulkanBuffer->getHandle(), 0, vulkanBuffer->getSize()));
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle[Gfx::currentFrameIndex], VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, binding, &bufferInfos.back()); VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, binding, &bufferInfos.back());
writeDescriptors.add(writeDescriptor); writeDescriptors.add(writeDescriptor);
cachedData[Gfx::currentFrameIndex][binding] = vulkanBuffer.getHandle(); cachedData[binding] = vulkanBuffer.getHandle();
} }
void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSamplerState samplerState) void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSamplerState samplerState)
{ {
PSamplerState vulkanSampler = samplerState.cast<SamplerState>(); PSamplerState vulkanSampler = samplerState.cast<SamplerState>();
SamplerState* cachedSampler = reinterpret_cast<SamplerState*>(cachedData[Gfx::currentFrameIndex][binding]); SamplerState* cachedSampler = reinterpret_cast<SamplerState*>(cachedData[binding]);
if(vulkanSampler.getHandle() == cachedSampler) if(vulkanSampler.getHandle() == cachedSampler)
{ {
return; return;
@@ -162,16 +162,16 @@ void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSamplerState samplerSt
VK_IMAGE_LAYOUT_UNDEFINED); VK_IMAGE_LAYOUT_UNDEFINED);
imageInfos.add(imageInfo); imageInfos.add(imageInfo);
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle[Gfx::currentFrameIndex], VK_DESCRIPTOR_TYPE_SAMPLER, binding, &imageInfos.back()); VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_SAMPLER, binding, &imageInfos.back());
writeDescriptors.add(writeDescriptor); writeDescriptors.add(writeDescriptor);
cachedData[Gfx::currentFrameIndex][binding] = vulkanSampler.getHandle(); cachedData[binding] = vulkanSampler.getHandle();
} }
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState samplerState) void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState samplerState)
{ {
TextureHandle* vulkanTexture = TextureBase::cast(texture); TextureHandle* vulkanTexture = TextureBase::cast(texture);
TextureHandle* cachedTexture = reinterpret_cast<TextureHandle*>(cachedData[Gfx::currentFrameIndex][binding]); TextureHandle* cachedTexture = reinterpret_cast<TextureHandle*>(cachedData[binding]);
if(vulkanTexture == cachedTexture) if(vulkanTexture == cachedTexture)
{ {
return; return;
@@ -181,7 +181,7 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
init::DescriptorImageInfo( init::DescriptorImageInfo(
VK_NULL_HANDLE, VK_NULL_HANDLE,
vulkanTexture->getView(), vulkanTexture->getView(),
vulkanTexture->getLayout()); cast(vulkanTexture->getLayout()));
if (samplerState != nullptr) if (samplerState != nullptr)
{ {
PSamplerState vulkanSampler = samplerState.cast<SamplerState>(); PSamplerState vulkanSampler = samplerState.cast<SamplerState>();
@@ -190,7 +190,7 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
imageInfos.add(imageInfo); imageInfos.add(imageInfo);
VkWriteDescriptorSet writeDescriptor = VkWriteDescriptorSet writeDescriptor =
init::WriteDescriptorSet( init::WriteDescriptorSet(
setHandle[Gfx::currentFrameIndex], setHandle,
samplerState != nullptr ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, samplerState != nullptr ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
binding, binding,
&imageInfos.back()); &imageInfos.back());
@@ -200,7 +200,7 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
} }
writeDescriptors.add(writeDescriptor); writeDescriptors.add(writeDescriptor);
cachedData[Gfx::currentFrameIndex][binding] = vulkanTexture; cachedData[binding] = vulkanTexture;
} }
bool DescriptorSet::operator<(Gfx::PDescriptorSet other) bool DescriptorSet::operator<(Gfx::PDescriptorSet other)
@@ -220,8 +220,8 @@ void DescriptorSet::writeChanges()
{ {
if(isCurrentlyBound()) if(isCurrentlyBound())
{ {
graphics->getGraphicsCommands()->waitForCommands(currentlyBound); currentlyBound->waitForCommand(1000000000u);
currentlyBound = nullptr; assert(!isCurrentlyBound());
} }
vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr); vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr);
writeDescriptors.clear(); writeDescriptors.clear();
@@ -258,7 +258,11 @@ DescriptorAllocator::DescriptorAllocator(PGraphics graphics, DescriptorLayout &l
poolSizes.add(size); poolSizes.add(size);
} }
} }
VkDescriptorPoolCreateInfo createInfo = init::DescriptorPoolCreateInfo((uint32)poolSizes.size(), poolSizes.data(), maxSets * Gfx::numFramesBuffered); VkDescriptorPoolCreateInfo createInfo
= init::DescriptorPoolCreateInfo(
(uint32)poolSizes.size(),
poolSizes.data(),
maxSets * Gfx::numFramesBuffered);
VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle)); VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle));
} }
@@ -271,14 +275,8 @@ DescriptorAllocator::~DescriptorAllocator()
void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet) void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet &descriptorSet)
{ {
VkDescriptorSetLayout layoutHandle = layout.getHandle(); VkDescriptorSetLayout layoutHandle = layout.getHandle();
VkDescriptorSetLayout layoutArray[Gfx::numFramesBuffered];
for (uint32 i = 0; i < Gfx::numFramesBuffered; i++)
{
layoutArray[i] = layoutHandle;
}
VkDescriptorSetAllocateInfo allocInfo = VkDescriptorSetAllocateInfo allocInfo =
init::DescriptorSetAllocateInfo(poolHandle, layoutArray, Gfx::numFramesBuffered); init::DescriptorSetAllocateInfo(poolHandle, &layoutHandle, 1);
for(uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex) for(uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex)
{ {
@@ -290,18 +288,17 @@ void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet &descriptorS
if(cachedHandles[setIndex]->getHandle() == VK_NULL_HANDLE) if(cachedHandles[setIndex]->getHandle() == VK_NULL_HANDLE)
{ {
//If it hasnt been initialized, allocate it //If it hasnt been initialized, allocate it
VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, cachedHandles[setIndex]->setHandle)); VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &cachedHandles[setIndex]->setHandle));
} }
cachedHandles[setIndex]->currentlyInUse = true; cachedHandles[setIndex]->currentlyInUse = true;
descriptorSet = cachedHandles[setIndex]; descriptorSet = cachedHandles[setIndex];
PDescriptorSet vulkanSet = descriptorSet.cast<DescriptorSet>(); PDescriptorSet vulkanSet = descriptorSet.cast<DescriptorSet>();
for(uint32 frameIndex = 0; frameIndex < Gfx::numFramesBuffered; ++frameIndex) vulkanSet->cachedData.resize(layout.bindings.size());
{ // Not really pretty, but this way the set knows which ones are valid
vulkanSet->cachedData[frameIndex].resize(layout.bindings.size()); std::memset(vulkanSet->cachedData.data(), 0, sizeof(void*) * vulkanSet->cachedData.size());
// Not really pretty, but this way the set knows which ones are valid
std::memset(vulkanSet->cachedData[frameIndex].data(), 0, sizeof(void*) * vulkanSet->cachedData[frameIndex].size());
}
//Found set, stop searching //Found set, stop searching
return; return;
} }
@@ -60,9 +60,12 @@ class DescriptorSet : public Gfx::DescriptorSet
{ {
public: public:
DescriptorSet(PGraphics graphics, PDescriptorAllocator owner) DescriptorSet(PGraphics graphics, PDescriptorAllocator owner)
: graphics(graphics), owner(owner), currentlyInUse(false), currentlyBound(nullptr) : setHandle(VK_NULL_HANDLE)
, graphics(graphics)
, owner(owner)
, currentlyInUse(false)
, currentlyBound(nullptr)
{ {
std::memset(setHandle, 0, sizeof(setHandle));
} }
virtual ~DescriptorSet(); virtual ~DescriptorSet();
virtual void writeChanges(); virtual void writeChanges();
@@ -86,7 +89,7 @@ public:
} }
inline VkDescriptorSet getHandle() const inline VkDescriptorSet getHandle() const
{ {
return setHandle[Gfx::currentFrameIndex]; return setHandle;
} }
virtual uint32 getSetIndex() const; virtual uint32 getSetIndex() const;
@@ -97,8 +100,8 @@ private:
// contains the previously bound resources at every binding // contains the previously bound resources at every binding
// since the layout is fixed, trying to bind a texture to a buffer // since the layout is fixed, trying to bind a texture to a buffer
// would not work anyways, so casts should be safe // would not work anyways, so casts should be safe
Array<void*> cachedData[Gfx::numFramesBuffered]; Array<void*> cachedData;
VkDescriptorSet setHandle[Gfx::numFramesBuffered]; VkDescriptorSet setHandle;
PGraphics graphics; PGraphics graphics;
PDescriptorAllocator owner; PDescriptorAllocator owner;
PCmdBuffer currentlyBound; PCmdBuffer currentlyBound;
+90 -4
View File
@@ -81,13 +81,19 @@ void Graphics::beginRenderPass(Gfx::PRenderPass renderPass)
void Graphics::endRenderPass() void Graphics::endRenderPass()
{ {
getGraphicsCommands()->getCommands()->endRenderPass(); getGraphicsCommands()->getCommands()->endRenderPass();
getGraphicsCommands()->submitCommands();
} }
void Graphics::executeCommands(Array<Gfx::PRenderCommand> commands) void Graphics::executeCommands(const Array<Gfx::PRenderCommand>& commands)
{ {
getGraphicsCommands()->getCommands()->executeCommands(commands); getGraphicsCommands()->getCommands()->executeCommands(commands);
} }
void Graphics::executeCommands(const Array<Gfx::PComputeCommand>& commands)
{
getComputeCommands()->getCommands()->executeCommands(commands);
}
Gfx::PTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo) Gfx::PTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo)
{ {
PTexture2D result = new Texture2D(this, createInfo); PTexture2D result = new Texture2D(this, createInfo);
@@ -100,7 +106,7 @@ Gfx::PUniformBuffer Graphics::createUniformBuffer(const UniformBufferCreateInfo
return uniformBuffer; return uniformBuffer;
} }
Gfx::PStructuredBuffer Graphics::createStructuredBuffer(const BulkResourceData &bulkData) Gfx::PStructuredBuffer Graphics::createStructuredBuffer(const StructuredBufferCreateInfo &bulkData)
{ {
PStructuredBuffer structuredBuffer = new StructuredBuffer(this, bulkData); PStructuredBuffer structuredBuffer = new StructuredBuffer(this, bulkData);
return structuredBuffer; return structuredBuffer;
@@ -116,9 +122,15 @@ Gfx::PIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkD
PIndexBuffer indexBuffer = new IndexBuffer(this, bulkData); PIndexBuffer indexBuffer = new IndexBuffer(this, bulkData);
return indexBuffer; return indexBuffer;
} }
Gfx::PRenderCommand Graphics::createRenderCommand() Gfx::PRenderCommand Graphics::createRenderCommand(const std::string& name)
{ {
PSecondaryCmdBuffer cmdBuffer = getGraphicsCommands()->createSecondaryCmdBuffer(); PRenderCommand cmdBuffer = getGraphicsCommands()->createRenderCommand(name);
return cmdBuffer;
}
Gfx::PComputeCommand Graphics::createComputeCommand(const std::string& name)
{
PComputeCommand cmdBuffer = getComputeCommands()->createComputeCommand(name);
return cmdBuffer; return cmdBuffer;
} }
@@ -158,6 +170,13 @@ Gfx::PFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& crea
shader->create(createInfo); shader->create(createInfo);
return shader; return shader;
} }
Gfx::PComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo)
{
PComputeShader shader = new ComputeShader(this);
shader->create(createInfo);
return shader;
}
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo)
{ {
PGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo); PGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo);
@@ -189,6 +208,73 @@ Gfx::PPipelineLayout Graphics::createPipelineLayout()
return layout; return layout;
} }
void Graphics::copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture)
{
Texture2D* src = (Texture2D*)srcTexture->getTexture2D();
Texture2D* dst = (Texture2D*)dstTexture->getTexture2D();
TextureHandle* srcHandle = (TextureHandle*)src->getNativeHandle();
TextureHandle* dstHandle = (TextureHandle*)dst->getNativeHandle();
Gfx::SeImageLayout srcLayout = srcHandle->getLayout();
Gfx::SeImageLayout dstLayout = dstHandle->getLayout();
Gfx::QueueType dstOwner = dstHandle->currentOwner;
src->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
dst->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
dstTexture->transferOwnership(srcHandle->currentOwner);
PCmdBuffer cmdBuffer = getQueueCommands(srcHandle->currentOwner)->getCommands();
if(srcHandle->getAspect() != dstHandle->getAspect())
{
/*VkMemoryRequirements imageRequirements;
vkGetImageMemoryRequirements(handle, srcHandle->getImage(), &imageRequirements);
PStructuredBuffer tempBuffer = createStructuredBuffer();
VkBufferImageCopy bufferImageCopy;
bufferImageCopy.bufferOffset = 0;
bufferImageCopy.bufferRowLength = srcTexture->getSizeX();
bufferImageCopy.bufferImageHeight = srcTexture->getSizeY();
bufferImageCopy.imageExtent.width = srcTexture->getSizeX();
bufferImageCopy.imageExtent.height = srcTexture->getSizeY();
bufferImageCopy.imageExtent.depth = 1;
bufferImageCopy.imageOffset.x = 0;
bufferImageCopy.imageOffset.y = 0;
bufferImageCopy.imageOffset.z = 0;
bufferImageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
bufferImageCopy.imageSubresource.baseArrayLayer = 0;
bufferImageCopy.imageSubresource.layerCount = 1;
bufferImageCopy.imageSubresource.mipLevel = 0;
vkCmdCopyImageToBuffer(cmdBuffer->getHandle(), srcHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, tempBufferAllocation->getHandle(), 1, &bufferImageCopy);
bufferImageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
vkCmdCopyBufferToImage(cmdBuffer->getHandle(), tempBufferAllocation->getHandle(), dstHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopy);
delete tempBufferAllocation;*/
throw new std::logic_error("Not yet implemented!");
}
else if (src->getSizeX() != dst->getSizeX()
|| src->getSizeY() != dst->getSizeY())
{
throw new std::logic_error("Not yet implemented!");
}
else
{
VkImageCopy copy;
std::memset(&copy, 0, sizeof(VkImageCopy));
copy.extent.width = srcTexture->getSizeX();
copy.extent.height = srcTexture->getSizeY();
copy.extent.depth = 1;
copy.srcSubresource.aspectMask = srcHandle->getAspect();
copy.srcSubresource.layerCount = 1;
copy.dstSubresource.aspectMask = dstHandle->getAspect();
copy.dstSubresource.layerCount = 1;
vkCmdCopyImage(cmdBuffer->getHandle(),
srcHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
dstHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &copy);
src->changeLayout(srcLayout);
dst->changeLayout(dstLayout);
dstTexture->transferOwnership(dstOwner);
}
}
VkInstance Graphics::getInstance() const VkInstance Graphics::getInstance() const
{ {
return instance; return instance;
+7 -3
View File
@@ -45,20 +45,23 @@ public:
virtual void beginRenderPass(Gfx::PRenderPass renderPass) override; virtual void beginRenderPass(Gfx::PRenderPass renderPass) override;
virtual void endRenderPass() override; virtual void endRenderPass() override;
virtual void executeCommands(Array<Gfx::PRenderCommand> commands) override; virtual void executeCommands(const Array<Gfx::PRenderCommand>& commands) override;
virtual void executeCommands(const Array<Gfx::PComputeCommand>& commands) override;
virtual Gfx::PTexture2D createTexture2D(const TextureCreateInfo &createInfo) override; virtual Gfx::PTexture2D createTexture2D(const TextureCreateInfo &createInfo) override;
virtual Gfx::PUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) override; virtual Gfx::PUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) override;
virtual Gfx::PStructuredBuffer createStructuredBuffer(const BulkResourceData &bulkData) override; virtual Gfx::PStructuredBuffer createStructuredBuffer(const StructuredBufferCreateInfo &bulkData) override;
virtual Gfx::PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) override; virtual Gfx::PVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) override;
virtual Gfx::PIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) override; virtual Gfx::PIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) override;
virtual Gfx::PRenderCommand createRenderCommand() override; virtual Gfx::PRenderCommand createRenderCommand(const std::string& name) override;
virtual Gfx::PComputeCommand createComputeCommand(const std::string& name) override;
virtual Gfx::PVertexDeclaration createVertexDeclaration(const Array<Gfx::VertexElement>& element) override; virtual Gfx::PVertexDeclaration createVertexDeclaration(const Array<Gfx::VertexElement>& element) override;
virtual Gfx::PVertexShader createVertexShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PVertexShader createVertexShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::PControlShader createControlShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PControlShader createControlShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::PEvaluationShader createEvaluationShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PEvaluationShader createEvaluationShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::PComputeShader createComputeShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) override; virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) override;
virtual Gfx::PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) override; virtual Gfx::PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) override;
virtual Gfx::PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) override; virtual Gfx::PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) override;
@@ -66,6 +69,7 @@ public:
virtual Gfx::PDescriptorLayout createDescriptorLayout(const std::string& name = "") override; virtual Gfx::PDescriptorLayout createDescriptorLayout(const std::string& name = "") override;
virtual Gfx::PPipelineLayout createPipelineLayout() override; virtual Gfx::PPipelineLayout createPipelineLayout() override;
virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) override;
protected: protected:
Array<const char *> getRequiredExtensions(); Array<const char *> getRequiredExtensions();
void initInstance(GraphicsInitializer initInfo); void initInstance(GraphicsInitializer initInfo);
@@ -1093,6 +1093,83 @@ Seele::Gfx::SeFormat Seele::Vulkan::cast(const VkFormat &format)
return SE_FORMAT_MAX_ENUM; return SE_FORMAT_MAX_ENUM;
} }
} }
VkImageLayout Seele::Vulkan::cast(const Gfx::SeImageLayout &imageLayout)
{
switch (imageLayout)
{
case SE_IMAGE_LAYOUT_UNDEFINED:
return VK_IMAGE_LAYOUT_UNDEFINED;
case SE_IMAGE_LAYOUT_GENERAL:
return VK_IMAGE_LAYOUT_GENERAL;
case SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
case SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
case SE_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
case SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
case SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
case SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
case SE_IMAGE_LAYOUT_PREINITIALIZED:
return VK_IMAGE_LAYOUT_PREINITIALIZED;
case SE_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
return VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
case SE_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL;
case SE_IMAGE_LAYOUT_PRESENT_SRC_KHR:
return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
case SE_IMAGE_LAYOUT_SHARED_PRESENT_KHR:
return VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR;
case SE_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV:
return VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV;
case SE_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:
return VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT;
default:
return VK_IMAGE_LAYOUT_MAX_ENUM;
}
}
Gfx::SeImageLayout Seele::Vulkan::cast(const VkImageLayout &imageLayout)
{
switch (imageLayout)
{
case VK_IMAGE_LAYOUT_UNDEFINED:
return SE_IMAGE_LAYOUT_UNDEFINED;
case VK_IMAGE_LAYOUT_GENERAL:
return SE_IMAGE_LAYOUT_GENERAL;
case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
return SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
return SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
return SE_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
return SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
return SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
return SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
case VK_IMAGE_LAYOUT_PREINITIALIZED:
return SE_IMAGE_LAYOUT_PREINITIALIZED;
case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
return SE_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL;
case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
return SE_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL;
case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
return SE_IMAGE_LAYOUT_PRESENT_SRC_KHR;
case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR:
return SE_IMAGE_LAYOUT_SHARED_PRESENT_KHR;
case VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV:
return SE_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV;
case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:
return SE_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT;
default:
return SE_IMAGE_LAYOUT_MAX_ENUM;
}
}
VkAttachmentStoreOp Seele::Vulkan::cast(const Gfx::SeAttachmentStoreOp &storeOp) VkAttachmentStoreOp Seele::Vulkan::cast(const Gfx::SeAttachmentStoreOp &storeOp)
{ {
switch (storeOp) switch (storeOp)
@@ -34,6 +34,8 @@ VkShaderStageFlagBits cast(const Gfx::SeShaderStageFlagBits &stage);
Gfx::SeShaderStageFlagBits cast(const VkShaderStageFlagBits &stage); Gfx::SeShaderStageFlagBits cast(const VkShaderStageFlagBits &stage);
VkFormat cast(const Gfx::SeFormat &format); VkFormat cast(const Gfx::SeFormat &format);
Gfx::SeFormat cast(const VkFormat &format); Gfx::SeFormat cast(const VkFormat &format);
VkImageLayout cast(const Gfx::SeImageLayout &imageLayout);
Gfx::SeImageLayout cast(const VkImageLayout &imageLayout);
VkAttachmentStoreOp cast(const Gfx::SeAttachmentStoreOp &storeOp); VkAttachmentStoreOp cast(const Gfx::SeAttachmentStoreOp &storeOp);
Gfx::SeAttachmentStoreOp cast(const VkAttachmentStoreOp &storeOp); Gfx::SeAttachmentStoreOp cast(const VkAttachmentStoreOp &storeOp);
VkAttachmentLoadOp cast(const Gfx::SeAttachmentLoadOp &loadOp); VkAttachmentLoadOp cast(const Gfx::SeAttachmentLoadOp &loadOp);
@@ -49,7 +49,6 @@ void QueueOwnedResourceDeletion::run()
} }
} }
Semaphore::Semaphore(PGraphics graphics) Semaphore::Semaphore(PGraphics graphics)
: graphics(graphics) : graphics(graphics)
{ {
@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
#include "Graphics/GraphicsResources.h"
#include <functional> #include <functional>
#include "Graphics/GraphicsResources.h"
namespace Seele namespace Seele
{ {
@@ -88,7 +88,7 @@ private:
class ShaderBuffer class ShaderBuffer
{ {
public: public:
ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType); ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false);
virtual ~ShaderBuffer(); virtual ~ShaderBuffer();
VkBuffer getHandle() const VkBuffer getHandle() const
{ {
@@ -115,11 +115,14 @@ protected:
PGraphics graphics; PGraphics graphics;
uint32 currentBuffer; uint32 currentBuffer;
uint32 size; uint32 size;
Gfx::QueueType currentOwner; Gfx::QueueType& owner;
BufferAllocation buffers[Gfx::numFramesBuffered]; BufferAllocation buffers[Gfx::numFramesBuffered];
uint32 numBuffers; uint32 numBuffers;
void executeOwnershipBarrier(Gfx::QueueType newOwner); void executeOwnershipBarrier(Gfx::QueueType newOwner);
void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0; virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0;
virtual VkAccessFlags getSourceAccessMask() = 0; virtual VkAccessFlags getSourceAccessMask() = 0;
@@ -139,11 +142,14 @@ public:
virtual void unlock() override; virtual void unlock() override;
protected: protected:
// Inherited via Vulkan::Buffer // Inherited via Vulkan::Buffer
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
virtual VkAccessFlags getSourceAccessMask(); virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask(); virtual VkAccessFlags getDestAccessMask();
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
// Inherited via QueueOwnedResource // Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
private: private:
PStagingBuffer dedicatedStagingBuffer; PStagingBuffer dedicatedStagingBuffer;
}; };
@@ -152,7 +158,7 @@ DEFINE_REF(UniformBuffer)
class StructuredBuffer : public Gfx::StructuredBuffer, public ShaderBuffer class StructuredBuffer : public Gfx::StructuredBuffer, public ShaderBuffer
{ {
public: public:
StructuredBuffer(PGraphics graphics, const BulkResourceData &resourceData); StructuredBuffer(PGraphics graphics, const StructuredBufferCreateInfo &resourceData);
virtual ~StructuredBuffer(); virtual ~StructuredBuffer();
protected: protected:
@@ -162,6 +168,10 @@ protected:
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
// Inherited via QueueOwnedResource // Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
private:
PStagingBuffer dedicatedStagingBuffer;
}; };
DEFINE_REF(StructuredBuffer) DEFINE_REF(StructuredBuffer)
@@ -178,6 +188,8 @@ protected:
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner); virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
// Inherited via QueueOwnedResource // Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
}; };
DEFINE_REF(VertexBuffer) DEFINE_REF(VertexBuffer)
@@ -189,11 +201,13 @@ public:
protected: protected:
// Inherited via Vulkan::Buffer // Inherited via Vulkan::Buffer
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
virtual VkAccessFlags getSourceAccessMask(); virtual VkAccessFlags getSourceAccessMask();
virtual VkAccessFlags getDestAccessMask(); virtual VkAccessFlags getDestAccessMask();
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner);
// Inherited via QueueOwnedResource // Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
}; };
DEFINE_REF(IndexBuffer) DEFINE_REF(IndexBuffer)
@@ -201,14 +215,18 @@ class TextureHandle
{ {
public: public:
TextureHandle(PGraphics graphics, VkImageViewType viewType, TextureHandle(PGraphics graphics, VkImageViewType viewType,
const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE); const TextureCreateInfo& createInfo, Gfx::QueueType& owner, VkImage existingImage = VK_NULL_HANDLE);
virtual ~TextureHandle(); virtual ~TextureHandle();
inline VkImage getImage() const
{
return image;
}
inline VkImageView getView() const inline VkImageView getView() const
{ {
return defaultView; return defaultView;
} }
inline VkImageLayout getLayout() const inline Gfx::SeImageLayout getLayout() const
{ {
return layout; return layout;
} }
@@ -233,10 +251,13 @@ public:
return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
} }
void executeOwnershipBarrier(Gfx::QueueType newOwner); void executeOwnershipBarrier(Gfx::QueueType newOwner);
void changeLayout(VkImageLayout newLayout); void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
void changeLayout(Gfx::SeImageLayout newLayout);
Gfx::QueueType currentOwner;
private: private:
//Updates via reference
Gfx::QueueType& currentOwner;
PGraphics graphics; PGraphics graphics;
PSubAllocation allocation; PSubAllocation allocation;
uint32 sizeX; uint32 sizeX;
@@ -250,21 +271,22 @@ private:
VkImage image; VkImage image;
VkImageView defaultView; VkImageView defaultView;
VkImageAspectFlags aspect; VkImageAspectFlags aspect;
VkImageLayout layout; Gfx::SeImageLayout layout;
friend class TextureBase; friend class TextureBase;
friend class Texture2D; friend class Texture2D;
friend class Graphics;
}; };
class TextureBase class TextureBase
{ {
public: public:
static TextureHandle* cast(Gfx::PTexture texture); static TextureHandle* cast(Gfx::PTexture texture);
void changeLayout(VkImageLayout newLayout);
protected: protected:
TextureHandle* textureHandle; TextureHandle* textureHandle;
friend class Graphics;
}; };
DECLARE_REF(TextureBase)
class Texture2D : public Gfx::Texture2D, public TextureBase class Texture2D : public Gfx::Texture2D, public TextureBase
{ {
public: public:
@@ -286,6 +308,11 @@ public:
{ {
return textureHandle->getNumSamples(); return textureHandle->getNumSamples();
} }
virtual void changeLayout(Gfx::SeImageLayout newLayout) override;
virtual void* getNativeHandle() override
{
return textureHandle;
}
inline VkImage getHandle() const inline VkImage getHandle() const
{ {
return textureHandle->image; return textureHandle->image;
@@ -301,6 +328,8 @@ public:
protected: protected:
// Inherited via QueueOwnedResource // Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner); virtual void executeOwnershipBarrier(Gfx::QueueType newOwner);
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
}; };
DEFINE_REF(Texture2D) DEFINE_REF(Texture2D)
@@ -120,6 +120,7 @@ void Shader::create(const ShaderCreateInfo& createInfo)
char const* diagnostics = spGetDiagnosticOutput(request); char const* diagnostics = spGetDiagnosticOutput(request);
std::cout << "Compile error for shader " << createInfo.name << std::endl; std::cout << "Compile error for shader " << createInfo.name << std::endl;
std::cout << diagnostics << std::endl; std::cout << diagnostics << std::endl;
return;
} }
size_t dataSize = 0; size_t dataSize = 0;
const uint32* data = reinterpret_cast<const uint32*>(spGetEntryPointCode(request, entryPointIndex, &dataSize)); const uint32* data = reinterpret_cast<const uint32*>(spGetEntryPointCode(request, entryPointIndex, &dataSize));
+51 -21
View File
@@ -30,8 +30,8 @@ VkImageAspectFlags getAspectFromFormat(Gfx::SeFormat format)
} }
TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
const TextureCreateInfo& createInfo, VkImage existingImage) const TextureCreateInfo& createInfo, Gfx::QueueType& owner, VkImage existingImage)
: currentOwner(createInfo.resourceData.owner) : currentOwner(owner)
, graphics(graphics) , graphics(graphics)
, sizeX(createInfo.width) , sizeX(createInfo.width)
, sizeY(createInfo.height) , sizeY(createInfo.height)
@@ -43,7 +43,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
, usage(createInfo.usage) , usage(createInfo.usage)
, image(existingImage) , image(existingImage)
, aspect(getAspectFromFormat(createInfo.format)) , aspect(getAspectFromFormat(createInfo.format))
, layout(VK_IMAGE_LAYOUT_UNDEFINED) , layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED)
{ {
if (existingImage == VK_NULL_HANDLE) if (existingImage == VK_NULL_HANDLE)
{ {
@@ -79,18 +79,18 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
break; break;
} }
info.initialLayout = layout; info.initialLayout = cast(layout);
info.mipLevels = mipLevels; info.mipLevels = mipLevels;
info.arrayLayers = arrayCount * layerCount; info.arrayLayers = arrayCount * layerCount;
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
info.samples = (VkSampleCountFlagBits)samples; info.samples = (VkSampleCountFlagBits)samples;
info.tiling = VK_IMAGE_TILING_OPTIMAL; info.tiling = VK_IMAGE_TILING_OPTIMAL;
info.usage = usage; info.usage = usage;
//To upload to the image we need to specify transfer dst // Most of these flags will almost always be used
if(createInfo.resourceData.size > 0) info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
{ info.usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
info.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
}
VK_CHECK(vkCreateImage(graphics->getDevice(), &info, nullptr, &image)); VK_CHECK(vkCreateImage(graphics->getDevice(), &info, nullptr, &image));
VkMemoryDedicatedRequirements memDedicatedRequirements; VkMemoryDedicatedRequirements memDedicatedRequirements;
@@ -112,7 +112,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
const BulkResourceData& resourceData = createInfo.resourceData; const BulkResourceData& resourceData = createInfo.resourceData;
if(resourceData.size > 0) if(resourceData.size > 0)
{ {
changeLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
PStagingBuffer staging = graphics->getStagingManager()->allocateStagingBuffer(resourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); PStagingBuffer staging = graphics->getStagingManager()->allocateStagingBuffer(resourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
void* data = staging->getMappedPointer(); void* data = staging->getMappedPointer();
std::memcpy(data, resourceData.data, resourceData.size); std::memcpy(data, resourceData.data, resourceData.size);
@@ -136,11 +136,15 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
staging->getHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region); staging->getHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
// When loading a texture from a file, we will almost always use it as a texture map for fragment shaders // When loading a texture from a file, we will almost always use it as a texture map for fragment shaders
changeLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
} }
if(usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) else if(usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
{ {
changeLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); changeLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
}
else
{
changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
} }
VkImageViewCreateInfo viewInfo = VkImageViewCreateInfo viewInfo =
@@ -176,17 +180,20 @@ TextureHandle* TextureBase::cast(Gfx::PTexture texture)
return nullptr; return nullptr;
} }
void TextureHandle::changeLayout(VkImageLayout newLayout) void TextureHandle::changeLayout(Gfx::SeImageLayout newLayout)
{ {
VkImageMemoryBarrier barrier = VkImageMemoryBarrier barrier =
init::ImageMemoryBarrier( init::ImageMemoryBarrier(
image, image,
layout, cast(layout),
newLayout); cast(newLayout));
barrier.subresourceRange =
init::ImageSubresourceRange(aspect);
PCommandBufferManager cmdManager = graphics->getQueueCommands(currentOwner); PCommandBufferManager cmdManager = graphics->getQueueCommands(currentOwner);
vkCmdPipelineBarrier(cmdManager->getCommands()->getHandle(), vkCmdPipelineBarrier(cmdManager->getCommands()->getHandle(),
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
0, 0, nullptr, 0, nullptr, 1, &barrier); 0, 0, nullptr, 0, nullptr, 1, &barrier);
cmdManager->submitCommands();
layout = newLayout; layout = newLayout;
} }
@@ -195,8 +202,8 @@ void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner)
VkImageMemoryBarrier imageBarrier = VkImageMemoryBarrier imageBarrier =
init::ImageMemoryBarrier(); init::ImageMemoryBarrier();
imageBarrier.image = image; imageBarrier.image = image;
imageBarrier.oldLayout = layout; imageBarrier.oldLayout = cast(layout);
imageBarrier.newLayout = layout; imageBarrier.newLayout = cast(layout);
imageBarrier.subresourceRange = init::ImageSubresourceRange(aspect); imageBarrier.subresourceRange = init::ImageSubresourceRange(aspect);
PCommandBufferManager sourceManager = graphics->getQueueCommands(currentOwner); PCommandBufferManager sourceManager = graphics->getQueueCommands(currentOwner);
PCommandBufferManager dstManager = nullptr; PCommandBufferManager dstManager = nullptr;
@@ -248,26 +255,49 @@ void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner)
VkCommandBuffer destCmd = dstManager->getCommands()->getHandle(); VkCommandBuffer destCmd = dstManager->getCommands()->getHandle();
vkCmdPipelineBarrier(sourceCmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier); vkCmdPipelineBarrier(sourceCmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
vkCmdPipelineBarrier(destCmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier); vkCmdPipelineBarrier(destCmd, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
currentOwner = newOwner;
sourceManager->submitCommands(); sourceManager->submitCommands();
} }
void TextureBase::changeLayout(VkImageLayout newLayout) void TextureHandle::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{ {
textureHandle->changeLayout(newLayout); VkImageMemoryBarrier imageBarrier =
init::ImageMemoryBarrier(
image,
cast(layout),
cast(layout)
);
imageBarrier.srcAccessMask = srcAccess;
imageBarrier.dstAccessMask = dstAccess;
imageBarrier.subresourceRange = init::ImageSubresourceRange(aspect);
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
vkCmdPipelineBarrier(cmdBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
} }
Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage) Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
: Gfx::Texture2D(graphics->getFamilyMapping(), createInfo.resourceData.owner) : Gfx::Texture2D(graphics->getFamilyMapping(), createInfo.resourceData.owner)
{ {
textureHandle = new TextureHandle(graphics, createInfo.bArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D, textureHandle = new TextureHandle(graphics, createInfo.bArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
createInfo, existingImage); createInfo, currentOwner, existingImage);
} }
Texture2D::~Texture2D() Texture2D::~Texture2D()
{ {
} }
void Texture2D::changeLayout(Gfx::SeImageLayout newLayout)
{
textureHandle->changeLayout(newLayout);
}
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner) void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner)
{ {
textureHandle->executeOwnershipBarrier(newOwner); textureHandle->executeOwnershipBarrier(newOwner);
} }
void Texture2D::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
textureHandle->executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
@@ -162,7 +162,7 @@ void Window::advanceBackBuffer()
imageAcquiredSemaphore = imageAcquired[semaphoreIndex]; imageAcquiredSemaphore = imageAcquired[semaphoreIndex];
currentImageIndex = imageIndex; currentImageIndex = imageIndex;
backBufferImages[currentImageIndex]->changeLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); backBufferImages[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands(); PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands();
graphics->getGraphicsCommands()->getCommands()->addWaitSemaphore(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, imageAcquiredSemaphore); graphics->getGraphicsCommands()->getCommands()->addWaitSemaphore(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, imageAcquiredSemaphore);
graphics->getGraphicsCommands()->submitCommands(); graphics->getGraphicsCommands()->submitCommands();
@@ -193,7 +193,7 @@ void Window::recreateSwapchain(const WindowCreateInfo &windowInfo)
void Window::present() void Window::present()
{ {
backBufferImages[currentImageIndex]->changeLayout(VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); backBufferImages[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_PRESENT_SRC_KHR);
graphics->getGraphicsCommands()->submitCommands(renderFinished[currentImageIndex]); graphics->getGraphicsCommands()->submitCommands(renderFinished[currentImageIndex]);
VkSemaphore renderFinishedHandle = renderFinished[currentImageIndex]->getHandle(); VkSemaphore renderFinishedHandle = renderFinished[currentImageIndex]->getHandle();
VkPresentInfoKHR info; VkPresentInfoKHR info;
@@ -258,7 +258,6 @@ void Window::createSwapchain()
Array<VkImage> swapchainImages(numSwapchainImages); Array<VkImage> swapchainImages(numSwapchainImages);
VK_CHECK(vkGetSwapchainImagesKHR(graphics->getDevice(), swapchain, &numSwapchainImages, swapchainImages.data())); VK_CHECK(vkGetSwapchainImagesKHR(graphics->getDevice(), swapchain, &numSwapchainImages, swapchainImages.data()));
PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands();
TextureCreateInfo backBufferCreateInfo; TextureCreateInfo backBufferCreateInfo;
backBufferCreateInfo.width = sizeX; backBufferCreateInfo.width = sizeX;
@@ -274,10 +273,11 @@ void Window::createSwapchain()
VkClearColorValue clearColor; VkClearColorValue clearColor;
std::memset(&clearColor, 0, sizeof(VkClearColorValue)); std::memset(&clearColor, 0, sizeof(VkClearColorValue));
backBufferImages[i]->changeLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); backBufferImages[i]->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
VkImageSubresourceRange range = init::ImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT); VkImageSubresourceRange range = init::ImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT);
PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands();
vkCmdClearColorImage(cmdBuffer->getHandle(), backBufferImages[i]->getHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range); vkCmdClearColorImage(cmdBuffer->getHandle(), backBufferImages[i]->getHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
backBufferImages[i]->changeLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); backBufferImages[i]->changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
} }
graphics->getGraphicsCommands()->submitCommands(); graphics->getGraphicsCommands()->submitCommands();
currentImageIndex = -1; currentImageIndex = -1;
+1 -1
View File
@@ -32,7 +32,7 @@ void MaterialAsset::endFrame()
void MaterialAsset::updateDescriptorData() void MaterialAsset::updateDescriptorData()
{ {
layout->reset(); layout->reset();
descriptorSet = layout->allocatedDescriptorSet(); descriptorSet = layout->allocateDescriptorSet();
BulkResourceData uniformUpdate; BulkResourceData uniformUpdate;
uniformUpdate.size = uniformDataSize; uniformUpdate.size = uniformDataSize;
uniformUpdate.data = uniformData; uniformUpdate.data = uniformData;
+15
View File
@@ -71,3 +71,18 @@ void SamplerParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, ui
{ {
descriptorSet->updateSampler(binding, data); descriptorSet->updateSampler(binding, data);
} }
CombinedTextureParameter::CombinedTextureParameter(std::string name, uint32 byteOffset, uint32 binding)
: ShaderParameter(name, byteOffset, binding)
{
}
CombinedTextureParameter::~CombinedTextureParameter()
{
}
void CombinedTextureParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst)
{
descriptorSet->updateTexture(binding, data->getTexture(), sampler);
}
+9 -1
View File
@@ -60,5 +60,13 @@ struct SamplerParameter : public ShaderParameter
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override; virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
}; };
DEFINE_REF(SamplerParameter) DEFINE_REF(SamplerParameter)
struct CombinedTextureParameter : public ShaderParameter
{
PTextureAsset data;
Gfx::PSamplerState sampler;
CombinedTextureParameter(std::string name, uint32 byteOffset, uint32 binding);
virtual ~CombinedTextureParameter();
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
};
DEFINE_REF(CombinedTextureParameter)
} // namespace Seele } // namespace Seele
+8
View File
@@ -27,6 +27,14 @@ Scene::Scene(Gfx::PGraphics graphics)
lightEnv.pointLights[i].positionWS = Vector4(frand() * 200-100, frand(), frand() * 200-100, 1); lightEnv.pointLights[i].positionWS = Vector4(frand() * 200-100, frand(), frand() * 200-100, 1);
} }
lightEnv.numPointLights = MAX_POINT_LIGHTS; lightEnv.numPointLights = MAX_POINT_LIGHTS;
BulkResourceData lightInit;
StructuredBufferCreateInfo structuredInfo;
lightInit.size = sizeof(LightEnv);
lightInit.data = (uint8*)&lightEnv;
structuredInfo.resourceData = lightInit;
structuredInfo.bDynamic = false;
lightBuffer = graphics->createStructuredBuffer(structuredInfo);
} }
Scene::~Scene() Scene::~Scene()
+2 -1
View File
@@ -46,13 +46,14 @@ public:
const Array<PPrimitiveComponent>& getPrimitives() const { return primitives; } const Array<PPrimitiveComponent>& getPrimitives() const { return primitives; }
const Array<MeshBatch>& getStaticMeshes() const { return staticMeshes; } const Array<MeshBatch>& getStaticMeshes() const { return staticMeshes; }
const LightEnv& getLightEnvironment() const { return lightEnv; } const Gfx::PStructuredBuffer& getLightBuffer() const { return lightBuffer; }
UPSceneUpdater& getSceneUpdater() { return updater; } UPSceneUpdater& getSceneUpdater() { return updater; }
private: private:
Array<MeshBatch> staticMeshes; Array<MeshBatch> staticMeshes;
Array<PActor> rootActors; Array<PActor> rootActors;
Array<PPrimitiveComponent> primitives; Array<PPrimitiveComponent> primitives;
LightEnv lightEnv; LightEnv lightEnv;
Gfx::PStructuredBuffer lightBuffer;
Gfx::PGraphics graphics; Gfx::PGraphics graphics;
UPSceneUpdater updater; UPSceneUpdater updater;
}; };
+10
View File
@@ -12,7 +12,11 @@ SceneRenderPath::SceneRenderPath(PScene scene, Gfx::PGraphics graphics, Gfx::PVi
{ {
renderGraph = new RenderGraph(); renderGraph = new RenderGraph();
depthPrepass = new DepthPrepass(renderGraph, scene, graphics, target, source); depthPrepass = new DepthPrepass(renderGraph, scene, graphics, target, source);
lightCullingPass = new LightCullingPass(renderGraph, scene, graphics, target, source);
basePass = new BasePass(renderGraph, scene, graphics, target, source); basePass = new BasePass(renderGraph, scene, graphics, target, source);
renderGraph->addRenderPass(depthPrepass);
renderGraph->addRenderPass(lightCullingPass);
renderGraph->addRenderPass(basePass);
renderGraph->setup(); renderGraph->setup();
} }
@@ -33,14 +37,20 @@ void SceneRenderPath::init()
void SceneRenderPath::beginFrame() void SceneRenderPath::beginFrame()
{ {
depthPrepass->beginFrame(); depthPrepass->beginFrame();
lightCullingPass->beginFrame();
basePass->beginFrame();
} }
void SceneRenderPath::render() void SceneRenderPath::render()
{ {
depthPrepass->render(); depthPrepass->render();
lightCullingPass->render();
basePass->render();
} }
void SceneRenderPath::endFrame() void SceneRenderPath::endFrame()
{ {
depthPrepass->endFrame(); depthPrepass->endFrame();
lightCullingPass->endFrame();
basePass->endFrame();
} }
+3 -1
View File
@@ -1,7 +1,8 @@
#pragma once #pragma once
#include "RenderPath.h" #include "RenderPath.h"
#include "Graphics/RenderPass/BasePass.h"
#include "Graphics/RenderPass/DepthPrepass.h" #include "Graphics/RenderPass/DepthPrepass.h"
#include "Graphics/RenderPass/LightCullingPass.h"
#include "Graphics/RenderPass/BasePass.h"
namespace Seele namespace Seele
{ {
@@ -22,6 +23,7 @@ protected:
PScene scene; PScene scene;
PRenderGraph renderGraph; PRenderGraph renderGraph;
PDepthPrepass depthPrepass; PDepthPrepass depthPrepass;
PLightCullingPass lightCullingPass;
PBasePass basePass; PBasePass basePass;
}; };