Lot of synchronization changes

This commit is contained in:
Dynamitos
2024-06-07 14:56:42 +02:00
parent cb21e8a85a
commit bc0d05dbb0
14 changed files with 686 additions and 515 deletions
+60
View File
@@ -0,0 +1,60 @@
import Common;
import Scene;
import VertexData;
import MaterialParameter;
struct PrimitiveAttributes
{
#ifdef VISIBILITY
uint32_t prim : SV_PrimitiveID;
#endif
bool cull: SV_CullPrimitive;
};
[numthreads(MESH_GROUP_SIZE, 1, 1)]
[outputtopology("triangle")]
[shader("mesh")]
void meshMain(
in uint threadID: SV_GroupThreadID,
in uint groupID: SV_GroupID,
in payload MeshPayload meshPayload,
out vertices FragmentParameter vertices[MAX_VERTICES],
out indices uint3 indices[MAX_PRIMITIVES],
out primitives PrimitiveAttributes prim[MAX_PRIMITIVES]
) {
// meshlet number relative to start for this instance
uint meshletNumber = meshPayload.culledMeshlets[groupID];
uint meshletId = meshPayload.cullingOffset + meshletNumber;
InstanceData inst = pScene.instances[meshPayload.instanceId];
MeshletDescription m = pScene.meshletInfos[meshPayload.meshletOffset + meshletNumber];
MeshletCullingInfo cull = pScene.cullingInfos[meshletId];
SetMeshOutputCounts(m.vertexCount, m.primitiveCount);
for(uint i = threadID; i < MAX_PRIMITIVES; i += MESH_GROUP_SIZE)
{
uint p = min(i, m.primitiveCount - 1);
{
uint local_idx0 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 0];
uint local_idx1 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 1];
uint local_idx2 = pScene.primitiveIndices[m.primitiveOffset + (p * 3) + 2];
indices[p] = uint3(local_idx0, local_idx1, local_idx2);
prim[p].cull = false;//!cull.triangleCulled(p);
#ifdef VISIBILITY
prim[p].prim = encodePrimitive(p, meshletId);
#endif
}
}
for(uint i = threadID; i < MAX_VERTICES; i += MESH_GROUP_SIZE)
{
uint v = min(i, m.vertexCount - 1);
{
uint vertexIndex = pScene.vertexIndices[m.vertexOffset + v];
#ifdef POS_ONLY
VertexAttributes attr = pVertexData.getPosition(m.indicesOffset + vertexIndex);
#else
VertexAttributes attr = pVertexData.getAttributes(m.indicesOffset + vertexIndex);
#endif
vertices[v] = attr.getParameter(inst.transformMatrix);
}
}
}
+14 -7
View File
@@ -8,15 +8,22 @@ struct VisibilityCullingData
}; };
ParameterBlock<VisibilityCullingData> pVisibilityParams; ParameterBlock<VisibilityCullingData> pVisibilityParams;
[numthreads(BLOCK_SIZE, BLOCK_SIZE, 1)] [numthreads(BLOCK_SIZE, 1, 1)]
[shader("compute")] [shader("compute")]
void computeMain( void computeMain(
uint3 dispatchThreadID: SV_DispatchThreadID, uint3 dispatchThreadID: SV_DispatchThreadID,
){ ){
int3 texCoords = int3(dispatchThreadID.xy, 0); //int3 texCoords = int3(dispatchThreadID.xy, 0);
uint encoded = pVisibilityParams.visibilityTexture.Load(texCoords).r; //uint encoded = pVisibilityParams.visibilityTexture.Load(texCoords).r;
uint2 decoded = decodePrimitive(encoded); //uint2 decoded = decodePrimitive(encoded);
uint arrIdx = decoded.x / 32; //uint arrIdx = decoded.x / 32;
uint bit = decoded.x % 32; //uint bit = decoded.x % 32;
pVisibilityParams.cullingInfos[decoded.y].visible[arrIdx] |= (1 << bit); pVisibilityParams.cullingInfos[dispatchThreadID.x].visible[0] = 0x0;
pVisibilityParams.cullingInfos[dispatchThreadID.x].visible[1] = 0x0;
pVisibilityParams.cullingInfos[dispatchThreadID.x].visible[2] = 0x0;
pVisibilityParams.cullingInfos[dispatchThreadID.x].visible[3] = 0x0;
pVisibilityParams.cullingInfos[dispatchThreadID.x].visible[4] = 0x0;
pVisibilityParams.cullingInfos[dispatchThreadID.x].visible[5] = 0x0;
pVisibilityParams.cullingInfos[dispatchThreadID.x].visible[6] = 0x0;
pVisibilityParams.cullingInfos[dispatchThreadID.x].visible[7] = 0x0;
} }
+6 -1
View File
@@ -48,7 +48,12 @@ struct MeshletCullingInfo
} }
bool anyVisible() bool anyVisible()
{ {
return (visible[0] + visible[1] + visible[2] + visible[3]) != 0; uint result = 0;
for(uint i = 0; i < MAX_PRIMITIVES / 32; ++i)
{
result |= visible[i];
}
return result != 0;
} }
}; };
+1 -1
View File
@@ -82,7 +82,7 @@ public:
ShaderBuffer(QueueFamilyMapping mapping, uint32 numElements, ShaderBuffer(QueueFamilyMapping mapping, uint32 numElements,
const DataSource &bulkResourceData); const DataSource &bulkResourceData);
virtual ~ShaderBuffer(); virtual ~ShaderBuffer();
virtual void rotateBuffer(uint64 size) = 0; virtual void rotateBuffer(uint64 size, bool preserveContents = false) = 0;
virtual void updateContents(const ShaderBufferCreateInfo &sourceData) = 0; virtual void updateContents(const ShaderBufferCreateInfo &sourceData) = 0;
constexpr uint32 getNumElements() const { return numElements; } constexpr uint32 getNumElements() const { return numElements; }
virtual void *mapRegion(uint64 offset = 0, uint64 size = -1, virtual void *mapRegion(uint64 offset = 0, uint64 size = -1,
+23 -25
View File
@@ -45,7 +45,7 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene)
graphics->getShaderCompiler()->registerRenderPass("BasePass", Gfx::PassConfig { graphics->getShaderCompiler()->registerRenderPass("BasePass", Gfx::PassConfig {
.baseLayout = basePassLayout, .baseLayout = basePassLayout,
.taskFile = "DrawListTask", .taskFile = "DrawListTask",
.mainFile = "MeshletPass", .mainFile = "DrawListMesh",
.fragmentFile = "BasePass", .fragmentFile = "BasePass",
.hasFragmentShader = true, .hasFragmentShader = true,
.useMeshShading = true, .useMeshShading = true,
@@ -194,6 +194,20 @@ void BasePass::render()
graphics->executeCommands(std::move(commands)); graphics->executeCommands(std::move(commands));
graphics->endRenderPass(); graphics->endRenderPass();
// Sync color write with next pass/swapchain present
//colorAttachment.getTexture()->pipelineBarrier(
// Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
// Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
// Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
// Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
//);
// Sync depth with next pass/next frame
//depthAttachment.getTexture()->pipelineBarrier(
// Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
// Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
// Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
// Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
//);
} }
void BasePass::endFrame() void BasePass::endFrame()
@@ -224,34 +238,18 @@ void BasePass::createRenderPass()
{ {
.srcSubpass = ~0U, .srcSubpass = ~0U,
.dstSubpass = 0, .dstSubpass = 0,
.srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
},
{
.srcSubpass = ~0U,
.dstSubpass = 0,
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
}, },
{ {
.srcSubpass = 0, .srcSubpass = 0,
.dstSubpass = ~0U, .dstSubpass = ~0U,
.srcStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
},
{
.srcSubpass = 0,
.dstSubpass = ~0U,
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
}, },
}; };
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport); renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport);
@@ -21,7 +21,7 @@ CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene)
graphics->getShaderCompiler()->registerRenderPass("CachedDepthPass", Gfx::PassConfig{ graphics->getShaderCompiler()->registerRenderPass("CachedDepthPass", Gfx::PassConfig{
.baseLayout = depthPrepassLayout, .baseLayout = depthPrepassLayout,
.taskFile = "DrawListTask", .taskFile = "DrawListTask",
.mainFile = "MeshletPass", .mainFile = "DrawListMesh",
.fragmentFile = "VisibilityPass", .fragmentFile = "VisibilityPass",
.hasFragmentShader = true, .hasFragmentShader = true,
.useMeshShading = true, .useMeshShading = true,
@@ -157,17 +157,17 @@ void CachedDepthPass::render()
graphics->executeCommands(std::move(commands)); graphics->executeCommands(std::move(commands));
graphics->endRenderPass(); graphics->endRenderPass();
// Sync depth read/write with depth pass depth read // Sync depth read/write with depth pass depth read
depthBuffer->pipelineBarrier( //depthBuffer->pipelineBarrier(
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, // Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT); // Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
// sync visibility write with depth pass visibility write // sync visibility write with depth pass visibility write
visibilityBuffer->pipelineBarrier( //visibilityBuffer->pipelineBarrier(
Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); // Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
} }
void CachedDepthPass::endFrame() void CachedDepthPass::endFrame()
@@ -214,30 +214,22 @@ void CachedDepthPass::createRenderPass()
.depthAttachment = depthAttachment, .depthAttachment = depthAttachment,
}; };
Array<Gfx::SubPassDependency> dependency = { Array<Gfx::SubPassDependency> dependency = {
// { {
// .srcSubpass = 0, .srcSubpass = ~0U,
// .dstSubpass = ~0U, .dstSubpass = 0,
// .srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
// .dstStage = Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
// .srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
// .dstAccess = Gfx::SE_ACCESS_SHADER_READ_BIT, .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
// }, },
// { {
// .srcSubpass = 0, .srcSubpass = 0,
// .dstSubpass = ~0U, .dstSubpass = ~0U,
// .srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
// .dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
// .srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
// .dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
// }, },
// {
// .srcSubpass = 0,
// .dstSubpass = ~0U,
// .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
// .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
// .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
// .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
// }
}; };
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport); renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport);
} }
+29 -30
View File
@@ -63,6 +63,20 @@ void DebugPass::render()
} }
graphics->endRenderPass(); graphics->endRenderPass();
gDebugVertices.clear(); gDebugVertices.clear();
// Sync color write with next pass/swapchain present
//colorAttachment.getTexture()->pipelineBarrier(
// Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
// Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
// Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
// Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
//);
// Sync depth with next pass/next frame
//depthAttachment.getTexture()->pipelineBarrier(
// Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
// Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
// Gfx::SE_ACCESS_MEMORY_WRITE_BIT,
// Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT
//);
} }
void DebugPass::endFrame() void DebugPass::endFrame()
@@ -76,16 +90,17 @@ void DebugPass::publishOutputs()
void DebugPass::createRenderPass() void DebugPass::createRenderPass()
{ {
Gfx::RenderTargetAttachment baseColorAttachment = resources->requestRenderTarget("BASEPASS_COLOR"); colorAttachment = resources->requestRenderTarget("BASEPASS_COLOR");
baseColorAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD); colorAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
baseColorAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); colorAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
baseColorAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); colorAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
Gfx::RenderTargetAttachment depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD); depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{ Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
.colorAttachments = {baseColorAttachment}, .colorAttachments = {colorAttachment},
.depthAttachment = depthAttachment, .depthAttachment = depthAttachment,
}; };
@@ -93,34 +108,18 @@ void DebugPass::createRenderPass()
{ {
.srcSubpass = ~0U, .srcSubpass = ~0U,
.dstSubpass = 0, .dstSubpass = 0,
.srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
},
{
.srcSubpass = ~0U,
.dstSubpass = 0,
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
}, },
{ {
.srcSubpass = 0, .srcSubpass = 0,
.dstSubpass = ~0U, .dstSubpass = ~0U,
.srcStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
},
{
.srcSubpass = 0,
.dstSubpass = ~0U,
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
}, },
}; };
renderPass = graphics->createRenderPass(std::move(layout), dependency, viewport); renderPass = graphics->createRenderPass(std::move(layout), dependency, viewport);
@@ -22,6 +22,8 @@ public:
virtual void publishOutputs() override; virtual void publishOutputs() override;
virtual void createRenderPass() override; virtual void createRenderPass() override;
private: private:
Gfx::RenderTargetAttachment colorAttachment;
Gfx::RenderTargetAttachment depthAttachment;
Gfx::OVertexInput vertexInput; Gfx::OVertexInput vertexInput;
Gfx::OVertexBuffer debugVertices; Gfx::OVertexBuffer debugVertices;
Gfx::OVertexShader vertexShader; Gfx::OVertexShader vertexShader;
+23 -54
View File
@@ -21,7 +21,7 @@ DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene)
graphics->getShaderCompiler()->registerRenderPass("DepthPass", Gfx::PassConfig{ graphics->getShaderCompiler()->registerRenderPass("DepthPass", Gfx::PassConfig{
.baseLayout = depthPrepassLayout, .baseLayout = depthPrepassLayout,
.taskFile = "DepthCullingTask", .taskFile = "DepthCullingTask",
.mainFile = "MeshletPass", .mainFile = "DepthCullingMesh",
.fragmentFile = "VisibilityPass", .fragmentFile = "VisibilityPass",
.hasFragmentShader = true, .hasFragmentShader = true,
.useMeshShading = true, .useMeshShading = true,
@@ -163,12 +163,12 @@ void DepthPrepass::render()
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT
); );
// Sync depth read/write with base pass read // Sync depth read/write with base pass read
depthAttachment.getTexture()->pipelineBarrier( //depthAttachment.getTexture()->pipelineBarrier(
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, // Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT // Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
); //);
// Sync visibility write with compute read // Sync visibility write with compute read
visibilityAttachment.getTexture()->pipelineBarrier( visibilityAttachment.getTexture()->pipelineBarrier(
Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
@@ -176,13 +176,6 @@ void DepthPrepass::render()
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT
); );
// Sync culling reads to compute write
cullingBuffer->pipelineBarrier(
Gfx::SE_ACCESS_SHADER_READ_BIT,
Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT,
Gfx::SE_ACCESS_SHADER_WRITE_BIT,
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT
);
} }
void DepthPrepass::endFrame() void DepthPrepass::endFrame()
@@ -211,46 +204,22 @@ void DepthPrepass::createRenderPass()
.depthAttachment = depthAttachment, .depthAttachment = depthAttachment,
}; };
Array<Gfx::SubPassDependency> dependency = { Array<Gfx::SubPassDependency> dependency = {
// { {
// .srcSubpass = ~0U, .srcSubpass = ~0U,
// .dstSubpass = 0, .dstSubpass = 0,
// .srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
// .dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
// .srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
// .dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
// }, },
// { {
// .srcSubpass = ~0U, .srcSubpass = 0,
// .dstSubpass = 0, .dstSubpass = ~0U,
// .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
// .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, .dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
// .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
// .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
// }, },
// {
// .srcSubpass = 0,
// .dstSubpass = ~0U,
// .srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
// .dstStage = Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
// .srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
// .dstAccess = Gfx::SE_ACCESS_SHADER_READ_BIT,
// },
// {
// .srcSubpass = 0,
// .dstSubpass = ~0U,
// .srcStage = Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
// .dstStage = Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
// .srcAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
// .dstAccess = Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
// },
// {
// .srcSubpass = 0,
// .dstSubpass = ~0U,
// .srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
// .dstStage = Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
// .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
// .dstAccess = Gfx::SE_ACCESS_SHADER_READ_BIT,
// }
}; };
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport); renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport);
} }
@@ -16,6 +16,7 @@ VisibilityPass::~VisibilityPass()
void VisibilityPass::beginFrame(const Component::Camera& cam) void VisibilityPass::beginFrame(const Component::Camera& cam)
{ {
RenderPass::beginFrame(cam); RenderPass::beginFrame(cam);
cullingBuffer->rotateBuffer(VertexData::getMeshletCount() * sizeof(VertexData::MeshletCullingInfo), true);
//Array<VertexData::MeshletCullingInfo> cullingData(VertexData::getMeshletCount()); //Array<VertexData::MeshletCullingInfo> cullingData(VertexData::getMeshletCount());
//std::memset(cullingData.data(), 0xffff, cullingData.size() * sizeof(VertexData::MeshletCullingInfo)); //std::memset(cullingData.data(), 0xffff, cullingData.size() * sizeof(VertexData::MeshletCullingInfo));
@@ -36,8 +37,19 @@ void VisibilityPass::beginFrame(const Component::Camera& cam)
void VisibilityPass::render() void VisibilityPass::render()
{ {
cullingBuffer->rotateBuffer(VertexData::getMeshletCount() * sizeof(VertexData::MeshletCullingInfo)); cullingBuffer->pipelineBarrier(
Gfx::SE_ACCESS_SHADER_READ_BIT,
Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT,
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT
);
cullingBuffer->clear(); cullingBuffer->clear();
cullingBuffer->pipelineBarrier(
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
Gfx::SE_ACCESS_SHADER_READ_BIT,
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT
);
visibilityDescriptor->reset(); visibilityDescriptor->reset();
visibilitySet = visibilityDescriptor->allocateDescriptorSet(); visibilitySet = visibilityDescriptor->allocateDescriptorSet();
@@ -48,14 +60,18 @@ void VisibilityPass::render()
Gfx::OComputeCommand command = graphics->createComputeCommand("VisibilityCommand"); Gfx::OComputeCommand command = graphics->createComputeCommand("VisibilityCommand");
command->bindPipeline(visibilityPipeline); command->bindPipeline(visibilityPipeline);
command->bindDescriptor({viewParamsSet, visibilitySet}); command->bindDescriptor({viewParamsSet, visibilitySet});
command->dispatch(threadGroupSize.x, threadGroupSize.y, threadGroupSize.z); command->dispatch(VertexData::getMeshletCount() / BLOCK_SIZE, 1, 1);
//command->dispatch(threadGroupSize.x, threadGroupSize.y, threadGroupSize.z);
Array<Gfx::OComputeCommand> commands; Array<Gfx::OComputeCommand> commands;
commands.add(std::move(command)); commands.add(std::move(command));
graphics->executeCommands(std::move(commands)); graphics->executeCommands(std::move(commands));
cullingBuffer->pipelineBarrier( cullingBuffer->pipelineBarrier(
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT,
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT); Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
Gfx::SE_ACCESS_SHADER_READ_BIT,
Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT | Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT
);
} }
void VisibilityPass::endFrame() void VisibilityPass::endFrame()
+476 -354
View File
@@ -7,17 +7,20 @@ using namespace Seele::Vulkan;
BufferAllocation::BufferAllocation(PGraphics graphics) BufferAllocation::BufferAllocation(PGraphics graphics)
: CommandBoundResource(graphics) {} : CommandBoundResource(graphics) {}
BufferAllocation::~BufferAllocation() { BufferAllocation::~BufferAllocation()
if (buffer != VK_NULL_HANDLE) { {
vmaDestroyBuffer(graphics->getAllocator(), buffer, allocation); if (buffer != VK_NULL_HANDLE)
} {
vmaDestroyBuffer(graphics->getAllocator(), buffer, allocation);
}
} }
struct PendingBuffer { struct PendingBuffer
OBufferAllocation allocation; {
uint64 offset; OBufferAllocation allocation;
Gfx::QueueType prevQueue; uint64 offset;
bool writeOnly; Gfx::QueueType prevQueue;
bool writeOnly;
}; };
static Map<Vulkan::Buffer *, PendingBuffer> pendingBuffers; static Map<Vulkan::Buffer *, PendingBuffer> pendingBuffers;
@@ -25,281 +28,364 @@ static Map<Vulkan::Buffer *, PendingBuffer> pendingBuffers;
Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage,
Gfx::QueueType &queueType, bool dynamic, std::string name) Gfx::QueueType &queueType, bool dynamic, std::string name)
: graphics(graphics), currentBuffer(0), owner(queueType), : graphics(graphics), currentBuffer(0), owner(queueType),
usage(usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT), dynamic(dynamic), usage(usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT), dynamic(dynamic),
name(name) { name(name)
createBuffer(size); {
createBuffer(size);
} }
Buffer::~Buffer() { Buffer::~Buffer()
for (uint32 i = 0; i < buffers.size(); ++i) { {
graphics->getDestructionManager()->queueResourceForDestruction( for (uint32 i = 0; i < buffers.size(); ++i)
std::move(buffers[i])); {
} graphics->getDestructionManager()->queueResourceForDestruction(
std::move(buffers[i]));
}
} }
void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
if (getSize() == 0) {
return; if (getSize() == 0)
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping(); return;
VkBufferMemoryBarrier barrier = { Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, VkBufferMemoryBarrier barrier = {
.pNext = nullptr, .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner), .pNext = nullptr,
.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner), .srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner),
.buffer = getHandle(), .dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner),
.offset = 0, .buffer = getHandle(),
.size = getSize(), .offset = 0,
}; .size = getSize(),
PCommandPool sourcePool = graphics->getQueueCommands(owner); };
PCommandPool dstPool = nullptr; PCommandPool sourcePool = graphics->getQueueCommands(owner);
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; PCommandPool dstPool = nullptr;
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex); VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
if (owner == Gfx::QueueType::TRANSFER) { assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; if (owner == Gfx::QueueType::TRANSFER)
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT; {
} else if (owner == Gfx::QueueType::COMPUTE) { barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; }
} else if (owner == Gfx::QueueType::GRAPHICS) { else if (owner == Gfx::QueueType::COMPUTE)
barrier.srcAccessMask = getSourceAccessMask(); {
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
} srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
if (newOwner == Gfx::QueueType::TRANSFER) { }
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; else if (owner == Gfx::QueueType::GRAPHICS)
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT; {
dstPool = graphics->getTransferCommands(); barrier.srcAccessMask = getSourceAccessMask();
} else if (newOwner == Gfx::QueueType::COMPUTE) { srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; }
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; if (newOwner == Gfx::QueueType::TRANSFER)
dstPool = graphics->getComputeCommands(); {
} else if (newOwner == Gfx::QueueType::GRAPHICS) { barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
barrier.dstAccessMask = getDestAccessMask(); dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; dstPool = graphics->getTransferCommands();
dstPool = graphics->getGraphicsCommands(); }
} else if (newOwner == Gfx::QueueType::COMPUTE)
VkCommandBuffer srcCommand = sourcePool->getCommands()->getHandle(); {
VkCommandBuffer dstCommand = dstPool->getCommands()->getHandle(); barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
vkCmdPipelineBarrier(srcCommand, srcStage, srcStage, 0, 0, nullptr, 1, dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
&barrier, 0, nullptr); dstPool = graphics->getComputeCommands();
vkCmdPipelineBarrier(dstCommand, dstStage, dstStage, 0, 0, nullptr, 1, }
&barrier, 0, nullptr); else if (newOwner == Gfx::QueueType::GRAPHICS)
sourcePool->submitCommands(); {
barrier.dstAccessMask = getDestAccessMask();
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
dstPool = graphics->getGraphicsCommands();
}
VkCommandBuffer srcCommand = sourcePool->getCommands()->getHandle();
VkCommandBuffer dstCommand = dstPool->getCommands()->getHandle();
vkCmdPipelineBarrier(srcCommand, srcStage, srcStage, 0, 0, nullptr, 1,
&barrier, 0, nullptr);
vkCmdPipelineBarrier(dstCommand, dstStage, dstStage, 0, 0, nullptr, 1,
&barrier, 0, nullptr);
sourcePool->submitCommands();
} }
void Buffer::executePipelineBarrier(VkAccessFlags srcAccess, void Buffer::executePipelineBarrier(VkAccessFlags srcAccess,
VkPipelineStageFlags srcStage, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) { VkPipelineStageFlags dstStage)
if (getSize() == 0) {
return; if (getSize() == 0)
PCommand commandBuffer = graphics->getQueueCommands(owner)->getCommands(); return;
VkBufferMemoryBarrier barrier = { PCommand commandBuffer = graphics->getQueueCommands(owner)->getCommands();
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, VkBufferMemoryBarrier barrier = {
.pNext = nullptr, .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.srcAccessMask = srcAccess, .pNext = nullptr,
.dstAccessMask = dstAccess, .srcAccessMask = srcAccess,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstAccessMask = dstAccess,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = getHandle(), .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.offset = 0, .buffer = getHandle(),
.size = getSize(), .offset = 0,
}; .size = getSize(),
vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, };
nullptr, 1, &barrier, 0, nullptr); vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0,
nullptr, 1, &barrier, 0, nullptr);
} }
void *Buffer::map(bool writeOnly) { return mapRegion(0, getSize(), writeOnly); } void *Buffer::map(bool writeOnly) { return mapRegion(0, getSize(), writeOnly); }
void *Buffer::mapRegion(uint64 regionOffset, uint64 regionSize, void *Buffer::mapRegion(uint64 regionOffset, uint64 regionSize,
bool writeOnly) { bool writeOnly)
if (regionSize == 0) {
return nullptr; if (regionSize == 0)
void *data = nullptr; return nullptr;
void *data = nullptr;
PendingBuffer pending; PendingBuffer pending;
pending.allocation = new BufferAllocation(graphics); pending.allocation = new BufferAllocation(graphics);
pending.allocation->size = regionSize; pending.allocation->size = regionSize;
pending.writeOnly = writeOnly; pending.writeOnly = writeOnly;
pending.prevQueue = owner; pending.prevQueue = owner;
pending.offset = regionOffset; pending.offset = regionOffset;
if (writeOnly) { if (writeOnly)
if (buffers[currentBuffer]->properties & {
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { if (buffers[currentBuffer]->properties &
VK_CHECK(vmaMapMemory(graphics->getAllocator(), VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
buffers[currentBuffer]->allocation, &data)); {
} else { VK_CHECK(vmaMapMemory(graphics->getAllocator(),
VkBufferCreateInfo stagingInfo = { buffers[currentBuffer]->allocation, &data));
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, }
.pNext = nullptr, else
.flags = 0, {
.size = regionSize, VkBufferCreateInfo stagingInfo = {
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE, .pNext = nullptr,
}; .flags = 0,
VmaAllocationCreateInfo allocInfo = { .size = regionSize,
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VMA_ALLOCATION_CREATE_MAPPED_BIT, .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.usage = VMA_MEMORY_USAGE_AUTO, };
.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VmaAllocationCreateInfo allocInfo = {
}; .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT |
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &stagingInfo, VMA_ALLOCATION_CREATE_MAPPED_BIT,
&allocInfo, &pending.allocation->buffer, .usage = VMA_MEMORY_USAGE_AUTO,
&pending.allocation->allocation, nullptr)); .requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
vmaMapMemory(graphics->getAllocator(), pending.allocation->allocation, };
&data); VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &stagingInfo,
vmaSetAllocationName(graphics->getAllocator(), &allocInfo, &pending.allocation->buffer,
pending.allocation->allocation, "MappingStaging"); &pending.allocation->allocation, nullptr));
vmaMapMemory(graphics->getAllocator(), pending.allocation->allocation,
&data);
vmaSetAllocationName(graphics->getAllocator(),
pending.allocation->allocation, "MappingStaging");
}
} }
} else { else
assert(false); {
} assert(false);
pendingBuffers[this] = std::move(pending); }
pendingBuffers[this] = std::move(pending);
assert(data); assert(data);
return data; return data;
} }
void Buffer::unmap() { void Buffer::unmap()
auto found = pendingBuffers.find(this); {
if (found != pendingBuffers.end()) { auto found = pendingBuffers.find(this);
PendingBuffer &pending = found->value; if (found != pendingBuffers.end())
if (pending.writeOnly) { {
if (buffers[currentBuffer]->properties & PendingBuffer &pending = found->value;
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { if (pending.writeOnly)
vmaUnmapMemory(graphics->getAllocator(), {
buffers[currentBuffer]->allocation); if (buffers[currentBuffer]->properties &
} else { VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
vmaFlushAllocation(graphics->getAllocator(), {
pending.allocation->allocation, 0, VK_WHOLE_SIZE); vmaUnmapMemory(graphics->getAllocator(),
vmaUnmapMemory(graphics->getAllocator(), buffers[currentBuffer]->allocation);
pending.allocation->allocation); }
PCommand command = graphics->getQueueCommands(owner)->getCommands(); else
command->bindResource(PBufferAllocation(pending.allocation)); {
VkCommandBuffer cmdHandle = command->getHandle(); vmaFlushAllocation(graphics->getAllocator(),
pending.allocation->allocation, 0, VK_WHOLE_SIZE);
vmaUnmapMemory(graphics->getAllocator(),
pending.allocation->allocation);
PCommand command = graphics->getQueueCommands(owner)->getCommands();
command->bindResource(PBufferAllocation(pending.allocation));
VkCommandBuffer cmdHandle = command->getHandle();
VkBufferCopy region = { VkBufferCopy region = {
.srcOffset = 0, .srcOffset = 0,
.dstOffset = pending.offset, .dstOffset = pending.offset,
.size = pending.allocation->size, .size = pending.allocation->size,
}; };
VkBufferMemoryBarrier barrier = { VkBufferMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr, .pNext = nullptr,
.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT, .srcAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[currentBuffer]->buffer, .buffer = buffers[currentBuffer]->buffer,
.offset = 0, .offset = 0,
.size = buffers[currentBuffer]->size, .size = buffers[currentBuffer]->size,
}; };
vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1,
&barrier, 0, nullptr); &barrier, 0, nullptr);
vkCmdCopyBuffer(cmdHandle, pending.allocation->buffer, vkCmdCopyBuffer(cmdHandle, pending.allocation->buffer,
buffers[currentBuffer]->buffer, 1, &region); buffers[currentBuffer]->buffer, 1, &region);
barrier = { barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr, .pNext = nullptr,
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT, .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[currentBuffer]->buffer, .buffer = buffers[currentBuffer]->buffer,
.offset = 0, .offset = 0,
.size = buffers[currentBuffer]->size, .size = buffers[currentBuffer]->size,
}; };
vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_TRANSFER_BIT, vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr,
1, &barrier, 0, nullptr); 1, &barrier, 0, nullptr);
graphics->getDestructionManager()->queueResourceForDestruction( graphics->getDestructionManager()->queueResourceForDestruction(
std::move(pending.allocation)); std::move(pending.allocation));
} }
}
pendingBuffers.erase(this);
} }
pendingBuffers.erase(this);
}
} }
void Buffer::rotateBuffer(uint64 size) { void Buffer::rotateBuffer(uint64 size, bool preserveContents)
{
assert(dynamic); assert(dynamic);
size = std::max(getSize(), size); size = std::max(getSize(), size);
for (size_t i = 0; i < buffers.size(); ++i) { for (size_t i = 0; i < buffers.size(); ++i)
if (buffers[i]->isCurrentlyBound()) { {
continue; if (buffers[i]->isCurrentlyBound())
{
continue;
}
if (buffers[i]->size < size)
{
vmaDestroyBuffer(graphics->getAllocator(), buffers[i]->buffer,
buffers[i]->allocation);
VkBufferCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.size = size,
.usage = usage,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
VmaAllocationCreateInfo allocInfo = {
.flags =
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT |
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
};
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &info, &allocInfo,
&buffers[i]->buffer, &buffers[i]->allocation,
&buffers[i]->info));
vmaGetAllocationMemoryProperties(graphics->getAllocator(),
buffers[i]->allocation,
&buffers[i]->properties);
if (!name.empty())
{
VkDebugUtilsObjectNameInfoEXT nameInfo = {
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.pNext = nullptr,
.objectType = VK_OBJECT_TYPE_BUFFER,
.objectHandle = (uint64)buffers[i]->buffer,
.pObjectName = this->name.c_str()};
graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo);
}
buffers[i]->size = size;
}
if (preserveContents)
{
copyBuffer(currentBuffer, i);
}
currentBuffer = i;
return;
} }
if (buffers[i]->size < size) { createBuffer(size);
vmaDestroyBuffer(graphics->getAllocator(), buffers[i]->buffer, if (preserveContents)
buffers[i]->allocation); {
VkBufferCreateInfo info = { copyBuffer(currentBuffer, buffers.size() - 1);
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.size = size,
.usage = usage,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
VmaAllocationCreateInfo allocInfo = {
.flags =
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT |
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
};
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &info, &allocInfo,
&buffers[i]->buffer, &buffers[i]->allocation,
&buffers[i]->info));
vmaGetAllocationMemoryProperties(graphics->getAllocator(),
buffers[i]->allocation,
&buffers[i]->properties);
if (!name.empty()) {
VkDebugUtilsObjectNameInfoEXT nameInfo = {
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.pNext = nullptr,
.objectType = VK_OBJECT_TYPE_BUFFER,
.objectHandle = (uint64)buffers[i]->buffer,
.pObjectName = this->name.c_str()};
graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo);
}
buffers[i]->size = size;
} }
currentBuffer = i; currentBuffer = buffers.size() - 1;
return;
}
createBuffer(size);
currentBuffer = buffers.size() - 1;
} }
void Buffer::createBuffer(uint64 size) { void Buffer::createBuffer(uint64 size)
VkBufferCreateInfo info = { {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, VkBufferCreateInfo info = {
.pNext = nullptr, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.size = size, .pNext = nullptr,
.usage = usage, .size = size,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE, .usage = usage,
}; .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
VmaAllocationCreateInfo allocInfo = { };
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VmaAllocationCreateInfo allocInfo = {
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT |
.usage = VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
}; .usage = VMA_MEMORY_USAGE_AUTO,
buffers.add(new BufferAllocation(graphics)); };
if (size > 0) { buffers.add(new BufferAllocation(graphics));
VK_CHECK(vmaCreateBuffer( if (size > 0)
graphics->getAllocator(), &info, &allocInfo, &buffers.back()->buffer, {
&buffers.back()->allocation, &buffers.back()->info)); VK_CHECK(vmaCreateBuffer(
buffers.back()->size = size; graphics->getAllocator(), &info, &allocInfo, &buffers.back()->buffer,
vmaGetAllocationMemoryProperties(graphics->getAllocator(), &buffers.back()->allocation, &buffers.back()->info));
buffers.back()->allocation, buffers.back()->size = size;
&buffers.back()->properties); vmaGetAllocationMemoryProperties(graphics->getAllocator(),
if (!name.empty()) { buffers.back()->allocation,
VkDebugUtilsObjectNameInfoEXT nameInfo = { &buffers.back()->properties);
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, if (!name.empty())
.pNext = nullptr, {
.objectType = VK_OBJECT_TYPE_BUFFER, VkDebugUtilsObjectNameInfoEXT nameInfo = {
.objectHandle = (uint64)buffers.back()->buffer, .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.pObjectName = this->name.c_str()}; .pNext = nullptr,
graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo); .objectType = VK_OBJECT_TYPE_BUFFER,
.objectHandle = (uint64)buffers.back()->buffer,
.pObjectName = this->name.c_str()};
graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo);
}
} }
} }
void Buffer::copyBuffer(uint64 src, uint64 dst)
{
if (src == dst)
{
return;
}
PCommand command = graphics->getQueueCommands(owner)->getCommands();
VkBufferMemoryBarrier srcBarrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[src]->buffer,
.offset = 0,
.size = buffers[src]->size,
};
vkCmdPipelineBarrier(command->getHandle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &srcBarrier, 0, nullptr);
VkBufferCopy region = {
.srcOffset = 0,
.dstOffset = 0,
.size = buffers[src]->size
};
vkCmdCopyBuffer(command->getHandle(), buffers[src]->buffer, buffers[dst]->buffer, 1, &region);
VkBufferMemoryBarrier dstBarrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[dst]->buffer,
.offset = 0,
.size = buffers[dst]->size,
};
vkCmdPipelineBarrier(command->getHandle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 1, &dstBarrier, 0, nullptr);
} }
UniformBuffer::UniformBuffer(PGraphics graphics, UniformBuffer::UniformBuffer(PGraphics graphics,
@@ -307,20 +393,23 @@ UniformBuffer::UniformBuffer(PGraphics graphics,
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.sourceData), : Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.sourceData),
Vulkan::Buffer(graphics, createInfo.sourceData.size, Vulkan::Buffer(graphics, createInfo.sourceData.size,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner,
createInfo.dynamic, createInfo.name) { createInfo.dynamic, createInfo.name)
if (getSize() > 0 && createInfo.sourceData.data != nullptr) { {
void *data = map(); if (getSize() > 0 && createInfo.sourceData.data != nullptr)
std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size); {
unmap(); void *data = map();
} std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size);
unmap();
}
} }
UniformBuffer::~UniformBuffer() {} UniformBuffer::~UniformBuffer() {}
void UniformBuffer::updateContents(const DataSource &sourceData) { void UniformBuffer::updateContents(const DataSource &sourceData)
void *data = map(); {
std::memcpy(data, sourceData.data, sourceData.size); void *data = map();
unmap(); std::memcpy(data, sourceData.data, sourceData.size);
unmap();
} }
void UniformBuffer::rotateBuffer(uint64 size) void UniformBuffer::rotateBuffer(uint64 size)
@@ -328,28 +417,33 @@ void UniformBuffer::rotateBuffer(uint64 size)
Vulkan::Buffer::rotateBuffer(size); Vulkan::Buffer::rotateBuffer(size);
} }
void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
Gfx::QueueOwnedResource::transferOwnership(newOwner); {
Gfx::QueueOwnedResource::transferOwnership(newOwner);
} }
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
Vulkan::Buffer::executeOwnershipBarrier(newOwner); {
Vulkan::Buffer::executeOwnershipBarrier(newOwner);
} }
void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess, void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess,
VkPipelineStageFlags srcStage, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) { VkPipelineStageFlags dstStage)
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, {
dstStage); Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess,
dstStage);
} }
VkAccessFlags UniformBuffer::getSourceAccessMask() { VkAccessFlags UniformBuffer::getSourceAccessMask()
return VK_ACCESS_MEMORY_WRITE_BIT; {
return VK_ACCESS_MEMORY_WRITE_BIT;
} }
VkAccessFlags UniformBuffer::getDestAccessMask() { VkAccessFlags UniformBuffer::getDestAccessMask()
return VK_ACCESS_UNIFORM_READ_BIT; {
return VK_ACCESS_UNIFORM_READ_BIT;
} }
ShaderBuffer::ShaderBuffer(PGraphics graphics, ShaderBuffer::ShaderBuffer(PGraphics graphics,
@@ -358,33 +452,39 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics,
sourceData.sourceData), sourceData.sourceData),
Vulkan::Buffer(graphics, sourceData.sourceData.size, Vulkan::Buffer(graphics, sourceData.sourceData.size,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner,
sourceData.dynamic, sourceData.name) { sourceData.dynamic, sourceData.name)
if (getSize() > 0 && sourceData.sourceData.data != nullptr) { {
void *data = map(); if (getSize() > 0 && sourceData.sourceData.data != nullptr)
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size); {
unmap(); void *data = map();
} std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
unmap();
}
} }
ShaderBuffer::~ShaderBuffer() {} ShaderBuffer::~ShaderBuffer() {}
void ShaderBuffer::updateContents(const ShaderBufferCreateInfo &createInfo) { void ShaderBuffer::updateContents(const ShaderBufferCreateInfo &createInfo)
if (createInfo.sourceData.data == nullptr) { {
return; if (createInfo.sourceData.data == nullptr)
} {
// We always want to update, as the contents could be different on the GPU return;
void *data = map(); }
std::memcpy((char*)data + createInfo.sourceData.offset, createInfo.sourceData.data, createInfo.sourceData.size); // We always want to update, as the contents could be different on the GPU
unmap(); void *data = map();
std::memcpy((char *)data + createInfo.sourceData.offset, createInfo.sourceData.data, createInfo.sourceData.size);
unmap();
} }
void Seele::Vulkan::ShaderBuffer::rotateBuffer(uint64 size) { void Seele::Vulkan::ShaderBuffer::rotateBuffer(uint64 size, bool preserveContents)
assert(dynamic); {
Vulkan::Buffer::rotateBuffer(size); assert(dynamic);
Vulkan::Buffer::rotateBuffer(size, preserveContents);
} }
void *ShaderBuffer::mapRegion(uint64 offset, uint64 size, bool writeOnly) { void *ShaderBuffer::mapRegion(uint64 offset, uint64 size, bool writeOnly)
return Vulkan::Buffer::mapRegion(offset, size, writeOnly); {
return Vulkan::Buffer::mapRegion(offset, size, writeOnly);
} }
void ShaderBuffer::unmap() { Vulkan::Buffer::unmap(); } void ShaderBuffer::unmap() { Vulkan::Buffer::unmap(); }
@@ -394,28 +494,33 @@ void ShaderBuffer::clear()
vkCmdFillBuffer(graphics->getQueueCommands(owner)->getCommands()->getHandle(), Vulkan::Buffer::getHandle(), 0, VK_WHOLE_SIZE, 0); vkCmdFillBuffer(graphics->getQueueCommands(owner)->getCommands()->getHandle(), Vulkan::Buffer::getHandle(), 0, VK_WHOLE_SIZE, 0);
} }
void ShaderBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { void ShaderBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
Gfx::QueueOwnedResource::transferOwnership(newOwner); {
Gfx::QueueOwnedResource::transferOwnership(newOwner);
} }
void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
Vulkan::Buffer::executeOwnershipBarrier(newOwner); {
Vulkan::Buffer::executeOwnershipBarrier(newOwner);
} }
void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess, void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess,
VkPipelineStageFlags srcStage, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) { VkPipelineStageFlags dstStage)
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, {
dstStage); Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess,
dstStage);
} }
VkAccessFlags ShaderBuffer::getSourceAccessMask() { VkAccessFlags ShaderBuffer::getSourceAccessMask()
return VK_ACCESS_MEMORY_WRITE_BIT; {
return VK_ACCESS_MEMORY_WRITE_BIT;
} }
VkAccessFlags ShaderBuffer::getDestAccessMask() { VkAccessFlags ShaderBuffer::getDestAccessMask()
return VK_ACCESS_MEMORY_READ_BIT; {
return VK_ACCESS_MEMORY_READ_BIT;
} }
VertexBuffer::VertexBuffer(PGraphics graphics, VertexBuffer::VertexBuffer(PGraphics graphics,
@@ -424,51 +529,60 @@ VertexBuffer::VertexBuffer(PGraphics graphics,
sourceData.vertexSize, sourceData.sourceData.owner), sourceData.vertexSize, sourceData.sourceData.owner),
Vulkan::Buffer(graphics, sourceData.sourceData.size, Vulkan::Buffer(graphics, sourceData.sourceData.size,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, currentOwner, false, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, currentOwner, false,
sourceData.name) { sourceData.name)
if (sourceData.sourceData.data != nullptr) { {
void *data = map(); if (sourceData.sourceData.data != nullptr)
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size); {
unmap(); void *data = map();
} std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
unmap();
}
} }
VertexBuffer::~VertexBuffer() {} VertexBuffer::~VertexBuffer() {}
void VertexBuffer::updateRegion(DataSource update) { void VertexBuffer::updateRegion(DataSource update)
void *data = mapRegion(update.offset, update.size); {
std::memcpy(data, update.data, update.size); void *data = mapRegion(update.offset, update.size);
unmap(); std::memcpy(data, update.data, update.size);
unmap();
} }
void VertexBuffer::download(Array<uint8> &buffer) { void VertexBuffer::download(Array<uint8> &buffer)
void *data = map(false); {
buffer.resize(getSize()); void *data = map(false);
std::memcpy(buffer.data(), data, getSize()); buffer.resize(getSize());
unmap(); std::memcpy(buffer.data(), data, getSize());
unmap();
} }
void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
Gfx::QueueOwnedResource::transferOwnership(newOwner); {
Gfx::QueueOwnedResource::transferOwnership(newOwner);
} }
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
Vulkan::Buffer::executeOwnershipBarrier(newOwner); {
Vulkan::Buffer::executeOwnershipBarrier(newOwner);
} }
void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess,
VkPipelineStageFlags srcStage, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) { VkPipelineStageFlags dstStage)
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, {
dstStage); Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess,
dstStage);
} }
VkAccessFlags VertexBuffer::getSourceAccessMask() { VkAccessFlags VertexBuffer::getSourceAccessMask()
return VK_ACCESS_MEMORY_WRITE_BIT; {
return VK_ACCESS_MEMORY_WRITE_BIT;
} }
VkAccessFlags VertexBuffer::getDestAccessMask() { VkAccessFlags VertexBuffer::getDestAccessMask()
return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; {
return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
} }
IndexBuffer::IndexBuffer(PGraphics graphics, IndexBuffer::IndexBuffer(PGraphics graphics,
@@ -477,43 +591,51 @@ IndexBuffer::IndexBuffer(PGraphics graphics,
sourceData.indexType, sourceData.sourceData.owner), sourceData.indexType, sourceData.sourceData.owner),
Vulkan::Buffer(graphics, sourceData.sourceData.size, Vulkan::Buffer(graphics, sourceData.sourceData.size,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT, currentOwner, false, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, currentOwner, false,
sourceData.name) { sourceData.name)
if (sourceData.sourceData.data != nullptr) { {
void *data = map(); if (sourceData.sourceData.data != nullptr)
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size); {
unmap(); void *data = map();
} std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
unmap();
}
} }
IndexBuffer::~IndexBuffer() {} IndexBuffer::~IndexBuffer() {}
void IndexBuffer::download(Array<uint8> &buffer) { void IndexBuffer::download(Array<uint8> &buffer)
void *data = map(false); {
buffer.resize(getSize()); void *data = map(false);
std::memcpy(buffer.data(), data, getSize()); buffer.resize(getSize());
unmap(); std::memcpy(buffer.data(), data, getSize());
unmap();
} }
void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
Gfx::QueueOwnedResource::transferOwnership(newOwner); {
Gfx::QueueOwnedResource::transferOwnership(newOwner);
} }
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
Vulkan::Buffer::executeOwnershipBarrier(newOwner); {
Vulkan::Buffer::executeOwnershipBarrier(newOwner);
} }
void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess,
VkPipelineStageFlags srcStage, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) { VkPipelineStageFlags dstStage)
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, {
dstStage); Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess,
dstStage);
} }
VkAccessFlags IndexBuffer::getSourceAccessMask() { VkAccessFlags IndexBuffer::getSourceAccessMask()
return VK_ACCESS_MEMORY_WRITE_BIT; {
return VK_ACCESS_MEMORY_WRITE_BIT;
} }
VkAccessFlags IndexBuffer::getDestAccessMask() { VkAccessFlags IndexBuffer::getDestAccessMask()
return VK_ACCESS_INDEX_READ_BIT; {
return VK_ACCESS_INDEX_READ_BIT;
} }
+3 -2
View File
@@ -39,8 +39,9 @@ protected:
VkBufferUsageFlags usage; VkBufferUsageFlags usage;
bool dynamic; bool dynamic;
std::string name; std::string name;
void rotateBuffer(uint64 size); void rotateBuffer(uint64 size, bool preserveContents = false);
void createBuffer(uint64 size); void createBuffer(uint64 size);
void copyBuffer(uint64 src, uint64 dest);
void executeOwnershipBarrier(Gfx::QueueType newOwner); void executeOwnershipBarrier(Gfx::QueueType newOwner);
void executePipelineBarrier(VkAccessFlags srcAccess, void executePipelineBarrier(VkAccessFlags srcAccess,
@@ -129,7 +130,7 @@ public:
virtual ~ShaderBuffer(); virtual ~ShaderBuffer();
virtual void virtual void
updateContents(const ShaderBufferCreateInfo &createInfo) override; updateContents(const ShaderBufferCreateInfo &createInfo) override;
virtual void rotateBuffer(uint64 size) override; virtual void rotateBuffer(uint64 size, bool preserveContents = false) override;
virtual void *mapRegion(uint64 offset, uint64 size, bool writeOnly) override; virtual void *mapRegion(uint64 offset, uint64 size, bool writeOnly) override;
virtual void unmap() override; virtual void unmap() override;
+2 -2
View File
@@ -147,12 +147,12 @@ void Command::checkFence()
{ {
command->reset(); command->reset();
} }
executingComputes.clear(); pool->cacheCommands(std::move(executingComputes));
for(auto& command : executingRenders) for(auto& command : executingRenders)
{ {
command->reset(); command->reset();
} }
executingRenders.clear(); pool->cacheCommands(std::move(executingRenders));
for(auto& descriptor : boundResources) for(auto& descriptor : boundResources)
{ {
descriptor->unbind(); descriptor->unbind();