diff --git a/res/shaders/DepthCullingMesh.slang b/res/shaders/DepthCullingMesh.slang new file mode 100644 index 0000000..841c1ef --- /dev/null +++ b/res/shaders/DepthCullingMesh.slang @@ -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); + } + } +} \ No newline at end of file diff --git a/res/shaders/MeshletPass.slang b/res/shaders/DrawListMesh.slang similarity index 100% rename from res/shaders/MeshletPass.slang rename to res/shaders/DrawListMesh.slang diff --git a/res/shaders/VisibilityCompute.slang b/res/shaders/VisibilityCompute.slang index 6011c88..9824335 100644 --- a/res/shaders/VisibilityCompute.slang +++ b/res/shaders/VisibilityCompute.slang @@ -8,15 +8,22 @@ struct VisibilityCullingData }; ParameterBlock pVisibilityParams; -[numthreads(BLOCK_SIZE, BLOCK_SIZE, 1)] +[numthreads(BLOCK_SIZE, 1, 1)] [shader("compute")] void computeMain( uint3 dispatchThreadID: SV_DispatchThreadID, ){ - int3 texCoords = int3(dispatchThreadID.xy, 0); - uint encoded = pVisibilityParams.visibilityTexture.Load(texCoords).r; - uint2 decoded = decodePrimitive(encoded); - uint arrIdx = decoded.x / 32; - uint bit = decoded.x % 32; - pVisibilityParams.cullingInfos[decoded.y].visible[arrIdx] |= (1 << bit); + //int3 texCoords = int3(dispatchThreadID.xy, 0); + //uint encoded = pVisibilityParams.visibilityTexture.Load(texCoords).r; + //uint2 decoded = decodePrimitive(encoded); + //uint arrIdx = decoded.x / 32; + //uint bit = decoded.x % 32; + 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; } \ No newline at end of file diff --git a/res/shaders/lib/Scene.slang b/res/shaders/lib/Scene.slang index 22cc2de..918ba1c 100644 --- a/res/shaders/lib/Scene.slang +++ b/res/shaders/lib/Scene.slang @@ -48,7 +48,12 @@ struct MeshletCullingInfo } 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; } }; diff --git a/src/Engine/Graphics/Buffer.h b/src/Engine/Graphics/Buffer.h index 4350883..001ed9a 100644 --- a/src/Engine/Graphics/Buffer.h +++ b/src/Engine/Graphics/Buffer.h @@ -82,7 +82,7 @@ public: ShaderBuffer(QueueFamilyMapping mapping, uint32 numElements, const DataSource &bulkResourceData); virtual ~ShaderBuffer(); - virtual void rotateBuffer(uint64 size) = 0; + virtual void rotateBuffer(uint64 size, bool preserveContents = false) = 0; virtual void updateContents(const ShaderBufferCreateInfo &sourceData) = 0; constexpr uint32 getNumElements() const { return numElements; } virtual void *mapRegion(uint64 offset = 0, uint64 size = -1, diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 7df987f..2a72b81 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -45,7 +45,7 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) graphics->getShaderCompiler()->registerRenderPass("BasePass", Gfx::PassConfig { .baseLayout = basePassLayout, .taskFile = "DrawListTask", - .mainFile = "MeshletPass", + .mainFile = "DrawListMesh", .fragmentFile = "BasePass", .hasFragmentShader = true, .useMeshShading = true, @@ -194,6 +194,20 @@ void BasePass::render() graphics->executeCommands(std::move(commands)); 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() @@ -224,34 +238,18 @@ void BasePass::createRenderPass() { .srcSubpass = ~0U, .dstSubpass = 0, - .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_WRITE_BIT, - .dstAccess = 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, + .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 | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_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 | 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_EARLY_FRAGMENT_TESTS_BIT, - .dstStage = Gfx::SE_PIPELINE_STAGE_LATE_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_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, + .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 | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_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 | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, }, }; renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport); diff --git a/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp b/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp index 1887082..d1cd368 100644 --- a/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp +++ b/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp @@ -21,7 +21,7 @@ CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene) graphics->getShaderCompiler()->registerRenderPass("CachedDepthPass", Gfx::PassConfig{ .baseLayout = depthPrepassLayout, .taskFile = "DrawListTask", - .mainFile = "MeshletPass", + .mainFile = "DrawListMesh", .fragmentFile = "VisibilityPass", .hasFragmentShader = true, .useMeshShading = true, @@ -157,17 +157,17 @@ void CachedDepthPass::render() graphics->executeCommands(std::move(commands)); graphics->endRenderPass(); // Sync depth read/write with depth pass depth read - depthBuffer->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); + //depthBuffer->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); // sync visibility write with depth pass visibility write - visibilityBuffer->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); + //visibilityBuffer->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); } void CachedDepthPass::endFrame() @@ -214,30 +214,22 @@ void CachedDepthPass::createRenderPass() .depthAttachment = depthAttachment, }; Array dependency = { - // { - // .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_COLOR_ATTACHMENT_OUTPUT_BIT, - // .srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - // .dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - // } + { + .srcSubpass = ~0U, + .dstSubpass = 0, + .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 | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_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 | 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 | 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_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 | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + }, }; renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport); } diff --git a/src/Engine/Graphics/RenderPass/DebugPass.cpp b/src/Engine/Graphics/RenderPass/DebugPass.cpp index 919e4df..b930b41 100644 --- a/src/Engine/Graphics/RenderPass/DebugPass.cpp +++ b/src/Engine/Graphics/RenderPass/DebugPass.cpp @@ -63,6 +63,20 @@ void DebugPass::render() } graphics->endRenderPass(); 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() @@ -76,16 +90,17 @@ void DebugPass::publishOutputs() void DebugPass::createRenderPass() { - Gfx::RenderTargetAttachment baseColorAttachment = resources->requestRenderTarget("BASEPASS_COLOR"); - baseColorAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD); - baseColorAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - baseColorAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); - Gfx::RenderTargetAttachment depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH"); + colorAttachment = resources->requestRenderTarget("BASEPASS_COLOR"); + colorAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD); + colorAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + colorAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + + depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH"); depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD); depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{ - .colorAttachments = {baseColorAttachment}, + .colorAttachments = {colorAttachment}, .depthAttachment = depthAttachment, }; @@ -93,34 +108,18 @@ void DebugPass::createRenderPass() { .srcSubpass = ~0U, .dstSubpass = 0, - .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_WRITE_BIT, - .dstAccess = 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, + .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 | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_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 | 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_EARLY_FRAGMENT_TESTS_BIT, - .dstStage = Gfx::SE_PIPELINE_STAGE_LATE_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_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, + .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 | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_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 | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, }, }; renderPass = graphics->createRenderPass(std::move(layout), dependency, viewport); diff --git a/src/Engine/Graphics/RenderPass/DebugPass.h b/src/Engine/Graphics/RenderPass/DebugPass.h index 9cf11e8..aa0d726 100644 --- a/src/Engine/Graphics/RenderPass/DebugPass.h +++ b/src/Engine/Graphics/RenderPass/DebugPass.h @@ -22,6 +22,8 @@ public: virtual void publishOutputs() override; virtual void createRenderPass() override; private: + Gfx::RenderTargetAttachment colorAttachment; + Gfx::RenderTargetAttachment depthAttachment; Gfx::OVertexInput vertexInput; Gfx::OVertexBuffer debugVertices; Gfx::OVertexShader vertexShader; diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp index 69344ce..fb857bc 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp @@ -21,7 +21,7 @@ DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene) graphics->getShaderCompiler()->registerRenderPass("DepthPass", Gfx::PassConfig{ .baseLayout = depthPrepassLayout, .taskFile = "DepthCullingTask", - .mainFile = "MeshletPass", + .mainFile = "DepthCullingMesh", .fragmentFile = "VisibilityPass", .hasFragmentShader = true, .useMeshShading = true, @@ -163,12 +163,12 @@ void DepthPrepass::render() Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT ); // Sync depth read/write with base pass read - 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 - ); + //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 + //); // Sync visibility write with compute read visibilityAttachment.getTexture()->pipelineBarrier( Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, @@ -176,13 +176,6 @@ void DepthPrepass::render() Gfx::SE_ACCESS_SHADER_READ_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() @@ -211,46 +204,22 @@ void DepthPrepass::createRenderPass() .depthAttachment = depthAttachment, }; Array dependency = { - // { - // .srcSubpass = ~0U, - // .dstSubpass = 0, - // .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_WRITE_BIT, - // .dstAccess = 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, - // .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, - // } + { + .srcSubpass = ~0U, + .dstSubpass = 0, + .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 | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_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 | 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 | 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_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 | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + }, }; renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport); } diff --git a/src/Engine/Graphics/RenderPass/VisibilityPass.cpp b/src/Engine/Graphics/RenderPass/VisibilityPass.cpp index df9f872..61070be 100644 --- a/src/Engine/Graphics/RenderPass/VisibilityPass.cpp +++ b/src/Engine/Graphics/RenderPass/VisibilityPass.cpp @@ -16,6 +16,7 @@ VisibilityPass::~VisibilityPass() void VisibilityPass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); + cullingBuffer->rotateBuffer(VertexData::getMeshletCount() * sizeof(VertexData::MeshletCullingInfo), true); //Array cullingData(VertexData::getMeshletCount()); //std::memset(cullingData.data(), 0xffff, cullingData.size() * sizeof(VertexData::MeshletCullingInfo)); @@ -36,8 +37,19 @@ void VisibilityPass::beginFrame(const Component::Camera& cam) 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->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(); visibilitySet = visibilityDescriptor->allocateDescriptorSet(); @@ -48,14 +60,18 @@ void VisibilityPass::render() Gfx::OComputeCommand command = graphics->createComputeCommand("VisibilityCommand"); command->bindPipeline(visibilityPipeline); 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 commands; commands.add(std::move(command)); graphics->executeCommands(std::move(commands)); cullingBuffer->pipelineBarrier( - Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT); + Gfx::SE_ACCESS_SHADER_WRITE_BIT, + 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() diff --git a/src/Engine/Graphics/Vulkan/Buffer.cpp b/src/Engine/Graphics/Vulkan/Buffer.cpp index 522ef20..bd83e0a 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.cpp +++ b/src/Engine/Graphics/Vulkan/Buffer.cpp @@ -7,17 +7,20 @@ using namespace Seele::Vulkan; BufferAllocation::BufferAllocation(PGraphics graphics) : CommandBoundResource(graphics) {} -BufferAllocation::~BufferAllocation() { - if (buffer != VK_NULL_HANDLE) { - vmaDestroyBuffer(graphics->getAllocator(), buffer, allocation); - } +BufferAllocation::~BufferAllocation() +{ + if (buffer != VK_NULL_HANDLE) + { + vmaDestroyBuffer(graphics->getAllocator(), buffer, allocation); + } } -struct PendingBuffer { - OBufferAllocation allocation; - uint64 offset; - Gfx::QueueType prevQueue; - bool writeOnly; +struct PendingBuffer +{ + OBufferAllocation allocation; + uint64 offset; + Gfx::QueueType prevQueue; + bool writeOnly; }; static Map pendingBuffers; @@ -25,281 +28,364 @@ static Map pendingBuffers; Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType &queueType, bool dynamic, std::string name) : graphics(graphics), currentBuffer(0), owner(queueType), - usage(usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT), dynamic(dynamic), - name(name) { - createBuffer(size); + usage(usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT), dynamic(dynamic), + name(name) +{ + createBuffer(size); } -Buffer::~Buffer() { - for (uint32 i = 0; i < buffers.size(); ++i) { - graphics->getDestructionManager()->queueResourceForDestruction( - std::move(buffers[i])); - } +Buffer::~Buffer() +{ + for (uint32 i = 0; i < buffers.size(); ++i) + { + graphics->getDestructionManager()->queueResourceForDestruction( + std::move(buffers[i])); + } } -void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { - if (getSize() == 0) - return; - Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping(); - VkBufferMemoryBarrier barrier = { - .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, - .pNext = nullptr, - .srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner), - .dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner), - .buffer = getHandle(), - .offset = 0, - .size = getSize(), - }; - PCommandPool sourcePool = graphics->getQueueCommands(owner); - PCommandPool dstPool = nullptr; - VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; - VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; - assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex); - if (owner == Gfx::QueueType::TRANSFER) { - barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT; - } else if (owner == Gfx::QueueType::COMPUTE) { - barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; - srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - } else if (owner == Gfx::QueueType::GRAPHICS) { - barrier.srcAccessMask = getSourceAccessMask(); - srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; - } - if (newOwner == Gfx::QueueType::TRANSFER) { - barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT; - dstPool = graphics->getTransferCommands(); - } else if (newOwner == Gfx::QueueType::COMPUTE) { - barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; - dstPool = graphics->getComputeCommands(); - } else if (newOwner == Gfx::QueueType::GRAPHICS) { - 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::executeOwnershipBarrier(Gfx::QueueType newOwner) +{ + if (getSize() == 0) + return; + Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping(); + VkBufferMemoryBarrier barrier = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .pNext = nullptr, + .srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner), + .dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner), + .buffer = getHandle(), + .offset = 0, + .size = getSize(), + }; + PCommandPool sourcePool = graphics->getQueueCommands(owner); + PCommandPool dstPool = nullptr; + VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; + VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; + assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex); + if (owner == Gfx::QueueType::TRANSFER) + { + barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT; + } + else if (owner == Gfx::QueueType::COMPUTE) + { + barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + } + else if (owner == Gfx::QueueType::GRAPHICS) + { + barrier.srcAccessMask = getSourceAccessMask(); + srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; + } + if (newOwner == Gfx::QueueType::TRANSFER) + { + barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; + dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT; + dstPool = graphics->getTransferCommands(); + } + else if (newOwner == Gfx::QueueType::COMPUTE) + { + barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; + dstPool = graphics->getComputeCommands(); + } + else if (newOwner == Gfx::QueueType::GRAPHICS) + { + 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, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, - VkPipelineStageFlags dstStage) { - if (getSize() == 0) - return; - PCommand commandBuffer = graphics->getQueueCommands(owner)->getCommands(); - VkBufferMemoryBarrier barrier = { - .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = srcAccess, - .dstAccessMask = dstAccess, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .buffer = getHandle(), - .offset = 0, - .size = getSize(), - }; - vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, - nullptr, 1, &barrier, 0, nullptr); + VkPipelineStageFlags dstStage) +{ + if (getSize() == 0) + return; + PCommand commandBuffer = graphics->getQueueCommands(owner)->getCommands(); + VkBufferMemoryBarrier barrier = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = srcAccess, + .dstAccessMask = dstAccess, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .buffer = getHandle(), + .offset = 0, + .size = getSize(), + }; + vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, + nullptr, 1, &barrier, 0, nullptr); } void *Buffer::map(bool writeOnly) { return mapRegion(0, getSize(), writeOnly); } void *Buffer::mapRegion(uint64 regionOffset, uint64 regionSize, - bool writeOnly) { - if (regionSize == 0) - return nullptr; - void *data = nullptr; + bool writeOnly) +{ + if (regionSize == 0) + return nullptr; + void *data = nullptr; - PendingBuffer pending; - pending.allocation = new BufferAllocation(graphics); - pending.allocation->size = regionSize; - pending.writeOnly = writeOnly; - pending.prevQueue = owner; - pending.offset = regionOffset; - if (writeOnly) { - if (buffers[currentBuffer]->properties & - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { - VK_CHECK(vmaMapMemory(graphics->getAllocator(), - buffers[currentBuffer]->allocation, &data)); - } else { - VkBufferCreateInfo stagingInfo = { - .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .size = regionSize, - .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - .sharingMode = VK_SHARING_MODE_EXCLUSIVE, - }; - VmaAllocationCreateInfo allocInfo = { - .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | - VMA_ALLOCATION_CREATE_MAPPED_BIT, - .usage = VMA_MEMORY_USAGE_AUTO, - .requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, - }; - VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &stagingInfo, - &allocInfo, &pending.allocation->buffer, - &pending.allocation->allocation, nullptr)); - vmaMapMemory(graphics->getAllocator(), pending.allocation->allocation, - &data); - vmaSetAllocationName(graphics->getAllocator(), - pending.allocation->allocation, "MappingStaging"); + PendingBuffer pending; + pending.allocation = new BufferAllocation(graphics); + pending.allocation->size = regionSize; + pending.writeOnly = writeOnly; + pending.prevQueue = owner; + pending.offset = regionOffset; + if (writeOnly) + { + if (buffers[currentBuffer]->properties & + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) + { + VK_CHECK(vmaMapMemory(graphics->getAllocator(), + buffers[currentBuffer]->allocation, &data)); + } + else + { + VkBufferCreateInfo stagingInfo = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .size = regionSize, + .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + }; + VmaAllocationCreateInfo allocInfo = { + .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | + VMA_ALLOCATION_CREATE_MAPPED_BIT, + .usage = VMA_MEMORY_USAGE_AUTO, + .requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + }; + VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &stagingInfo, + &allocInfo, &pending.allocation->buffer, + &pending.allocation->allocation, nullptr)); + vmaMapMemory(graphics->getAllocator(), pending.allocation->allocation, + &data); + vmaSetAllocationName(graphics->getAllocator(), + pending.allocation->allocation, "MappingStaging"); + } } - } else { - assert(false); - } - pendingBuffers[this] = std::move(pending); + else + { + assert(false); + } + pendingBuffers[this] = std::move(pending); - assert(data); - return data; + assert(data); + return data; } -void Buffer::unmap() { - auto found = pendingBuffers.find(this); - if (found != pendingBuffers.end()) { - PendingBuffer &pending = found->value; - if (pending.writeOnly) { - if (buffers[currentBuffer]->properties & - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { - vmaUnmapMemory(graphics->getAllocator(), - buffers[currentBuffer]->allocation); - } else { - 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(); +void Buffer::unmap() +{ + auto found = pendingBuffers.find(this); + if (found != pendingBuffers.end()) + { + PendingBuffer &pending = found->value; + if (pending.writeOnly) + { + if (buffers[currentBuffer]->properties & + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) + { + vmaUnmapMemory(graphics->getAllocator(), + buffers[currentBuffer]->allocation); + } + else + { + 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 = { - .srcOffset = 0, - .dstOffset = pending.offset, - .size = pending.allocation->size, - }; - VkBufferMemoryBarrier barrier = { - .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = VK_ACCESS_MEMORY_READ_BIT, - .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .buffer = buffers[currentBuffer]->buffer, - .offset = 0, - .size = buffers[currentBuffer]->size, - }; - vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, - &barrier, 0, nullptr); - vkCmdCopyBuffer(cmdHandle, pending.allocation->buffer, - buffers[currentBuffer]->buffer, 1, ®ion); - barrier = { - .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[currentBuffer]->buffer, - .offset = 0, - .size = buffers[currentBuffer]->size, - }; - vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, - 1, &barrier, 0, nullptr); - graphics->getDestructionManager()->queueResourceForDestruction( - std::move(pending.allocation)); - } + VkBufferCopy region = { + .srcOffset = 0, + .dstOffset = pending.offset, + .size = pending.allocation->size, + }; + VkBufferMemoryBarrier barrier = { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = VK_ACCESS_MEMORY_READ_BIT, + .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .buffer = buffers[currentBuffer]->buffer, + .offset = 0, + .size = buffers[currentBuffer]->size, + }; + vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, + &barrier, 0, nullptr); + vkCmdCopyBuffer(cmdHandle, pending.allocation->buffer, + buffers[currentBuffer]->buffer, 1, ®ion); + barrier = { + .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[currentBuffer]->buffer, + .offset = 0, + .size = buffers[currentBuffer]->size, + }; + vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, + 1, &barrier, 0, nullptr); + graphics->getDestructionManager()->queueResourceForDestruction( + std::move(pending.allocation)); + } + } + pendingBuffers.erase(this); } - pendingBuffers.erase(this); - } } -void Buffer::rotateBuffer(uint64 size) { +void Buffer::rotateBuffer(uint64 size, bool preserveContents) +{ assert(dynamic); - size = std::max(getSize(), size); - for (size_t i = 0; i < buffers.size(); ++i) { - if (buffers[i]->isCurrentlyBound()) { - continue; + size = std::max(getSize(), size); + for (size_t i = 0; i < buffers.size(); ++i) + { + 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) { - 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; + createBuffer(size); + if (preserveContents) + { + copyBuffer(currentBuffer, buffers.size() - 1); } - currentBuffer = i; - return; - } - createBuffer(size); - currentBuffer = buffers.size() - 1; + currentBuffer = buffers.size() - 1; } -void Buffer::createBuffer(uint64 size) { - 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, - }; - buffers.add(new BufferAllocation(graphics)); - if (size > 0) { - VK_CHECK(vmaCreateBuffer( - graphics->getAllocator(), &info, &allocInfo, &buffers.back()->buffer, - &buffers.back()->allocation, &buffers.back()->info)); - buffers.back()->size = size; - vmaGetAllocationMemoryProperties(graphics->getAllocator(), - buffers.back()->allocation, - &buffers.back()->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.back()->buffer, - .pObjectName = this->name.c_str()}; - graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo); +void Buffer::createBuffer(uint64 size) +{ + 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, + }; + buffers.add(new BufferAllocation(graphics)); + if (size > 0) + { + VK_CHECK(vmaCreateBuffer( + graphics->getAllocator(), &info, &allocInfo, &buffers.back()->buffer, + &buffers.back()->allocation, &buffers.back()->info)); + buffers.back()->size = size; + vmaGetAllocationMemoryProperties(graphics->getAllocator(), + buffers.back()->allocation, + &buffers.back()->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.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, ®ion); + 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, @@ -307,20 +393,23 @@ UniformBuffer::UniformBuffer(PGraphics graphics, : Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.sourceData), Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, - createInfo.dynamic, createInfo.name) { - if (getSize() > 0 && createInfo.sourceData.data != nullptr) { - void *data = map(); - std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size); - unmap(); - } + createInfo.dynamic, createInfo.name) +{ + if (getSize() > 0 && createInfo.sourceData.data != nullptr) + { + void *data = map(); + std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size); + unmap(); + } } UniformBuffer::~UniformBuffer() {} -void UniformBuffer::updateContents(const DataSource &sourceData) { - void *data = map(); - std::memcpy(data, sourceData.data, sourceData.size); - unmap(); +void UniformBuffer::updateContents(const DataSource &sourceData) +{ + void *data = map(); + std::memcpy(data, sourceData.data, sourceData.size); + unmap(); } void UniformBuffer::rotateBuffer(uint64 size) @@ -328,28 +417,33 @@ void UniformBuffer::rotateBuffer(uint64 size) Vulkan::Buffer::rotateBuffer(size); } -void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { - Gfx::QueueOwnedResource::transferOwnership(newOwner); +void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) +{ + Gfx::QueueOwnedResource::transferOwnership(newOwner); } -void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { - Vulkan::Buffer::executeOwnershipBarrier(newOwner); +void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) +{ + Vulkan::Buffer::executeOwnershipBarrier(newOwner); } void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, - VkPipelineStageFlags dstStage) { - Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, - dstStage); + VkPipelineStageFlags dstStage) +{ + Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, + dstStage); } -VkAccessFlags UniformBuffer::getSourceAccessMask() { - return VK_ACCESS_MEMORY_WRITE_BIT; +VkAccessFlags UniformBuffer::getSourceAccessMask() +{ + return VK_ACCESS_MEMORY_WRITE_BIT; } -VkAccessFlags UniformBuffer::getDestAccessMask() { - return VK_ACCESS_UNIFORM_READ_BIT; +VkAccessFlags UniformBuffer::getDestAccessMask() +{ + return VK_ACCESS_UNIFORM_READ_BIT; } ShaderBuffer::ShaderBuffer(PGraphics graphics, @@ -358,33 +452,39 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, sourceData.sourceData), Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, - sourceData.dynamic, sourceData.name) { - if (getSize() > 0 && sourceData.sourceData.data != nullptr) { - void *data = map(); - std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size); - unmap(); - } + sourceData.dynamic, sourceData.name) +{ + if (getSize() > 0 && sourceData.sourceData.data != nullptr) + { + void *data = map(); + std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size); + unmap(); + } } ShaderBuffer::~ShaderBuffer() {} -void ShaderBuffer::updateContents(const ShaderBufferCreateInfo &createInfo) { - if (createInfo.sourceData.data == nullptr) { - return; - } - // We always want to update, as the contents could be different on the GPU - void *data = map(); - std::memcpy((char*)data + createInfo.sourceData.offset, createInfo.sourceData.data, createInfo.sourceData.size); - unmap(); +void ShaderBuffer::updateContents(const ShaderBufferCreateInfo &createInfo) +{ + if (createInfo.sourceData.data == nullptr) + { + return; + } + // We always want to update, as the contents could be different on the GPU + void *data = map(); + std::memcpy((char *)data + createInfo.sourceData.offset, createInfo.sourceData.data, createInfo.sourceData.size); + unmap(); } -void Seele::Vulkan::ShaderBuffer::rotateBuffer(uint64 size) { - assert(dynamic); - Vulkan::Buffer::rotateBuffer(size); +void Seele::Vulkan::ShaderBuffer::rotateBuffer(uint64 size, bool preserveContents) +{ + assert(dynamic); + Vulkan::Buffer::rotateBuffer(size, preserveContents); } -void *ShaderBuffer::mapRegion(uint64 offset, uint64 size, bool writeOnly) { - return Vulkan::Buffer::mapRegion(offset, size, writeOnly); +void *ShaderBuffer::mapRegion(uint64 offset, uint64 size, bool writeOnly) +{ + return Vulkan::Buffer::mapRegion(offset, size, writeOnly); } 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); } -void ShaderBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { - Gfx::QueueOwnedResource::transferOwnership(newOwner); +void ShaderBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) +{ + Gfx::QueueOwnedResource::transferOwnership(newOwner); } -void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { - Vulkan::Buffer::executeOwnershipBarrier(newOwner); +void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) +{ + Vulkan::Buffer::executeOwnershipBarrier(newOwner); } void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, - VkPipelineStageFlags dstStage) { - Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, - dstStage); + VkPipelineStageFlags dstStage) +{ + Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, + dstStage); } -VkAccessFlags ShaderBuffer::getSourceAccessMask() { - return VK_ACCESS_MEMORY_WRITE_BIT; +VkAccessFlags ShaderBuffer::getSourceAccessMask() +{ + return VK_ACCESS_MEMORY_WRITE_BIT; } -VkAccessFlags ShaderBuffer::getDestAccessMask() { - return VK_ACCESS_MEMORY_READ_BIT; +VkAccessFlags ShaderBuffer::getDestAccessMask() +{ + return VK_ACCESS_MEMORY_READ_BIT; } VertexBuffer::VertexBuffer(PGraphics graphics, @@ -424,51 +529,60 @@ VertexBuffer::VertexBuffer(PGraphics graphics, sourceData.vertexSize, sourceData.sourceData.owner), Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, currentOwner, false, - sourceData.name) { - if (sourceData.sourceData.data != nullptr) { - void *data = map(); - std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size); - unmap(); - } + sourceData.name) +{ + if (sourceData.sourceData.data != nullptr) + { + void *data = map(); + std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size); + unmap(); + } } VertexBuffer::~VertexBuffer() {} -void VertexBuffer::updateRegion(DataSource update) { - void *data = mapRegion(update.offset, update.size); - std::memcpy(data, update.data, update.size); - unmap(); +void VertexBuffer::updateRegion(DataSource update) +{ + void *data = mapRegion(update.offset, update.size); + std::memcpy(data, update.data, update.size); + unmap(); } -void VertexBuffer::download(Array &buffer) { - void *data = map(false); - buffer.resize(getSize()); - std::memcpy(buffer.data(), data, getSize()); - unmap(); +void VertexBuffer::download(Array &buffer) +{ + void *data = map(false); + buffer.resize(getSize()); + std::memcpy(buffer.data(), data, getSize()); + unmap(); } -void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { - Gfx::QueueOwnedResource::transferOwnership(newOwner); +void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) +{ + Gfx::QueueOwnedResource::transferOwnership(newOwner); } -void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { - Vulkan::Buffer::executeOwnershipBarrier(newOwner); +void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) +{ + Vulkan::Buffer::executeOwnershipBarrier(newOwner); } void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, - VkPipelineStageFlags dstStage) { - Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, - dstStage); + VkPipelineStageFlags dstStage) +{ + Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, + dstStage); } -VkAccessFlags VertexBuffer::getSourceAccessMask() { - return VK_ACCESS_MEMORY_WRITE_BIT; +VkAccessFlags VertexBuffer::getSourceAccessMask() +{ + return VK_ACCESS_MEMORY_WRITE_BIT; } -VkAccessFlags VertexBuffer::getDestAccessMask() { - return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; +VkAccessFlags VertexBuffer::getDestAccessMask() +{ + return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; } IndexBuffer::IndexBuffer(PGraphics graphics, @@ -477,43 +591,51 @@ IndexBuffer::IndexBuffer(PGraphics graphics, sourceData.indexType, sourceData.sourceData.owner), Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, currentOwner, false, - sourceData.name) { - if (sourceData.sourceData.data != nullptr) { - void *data = map(); - std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size); - unmap(); - } + sourceData.name) +{ + if (sourceData.sourceData.data != nullptr) + { + void *data = map(); + std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size); + unmap(); + } } IndexBuffer::~IndexBuffer() {} -void IndexBuffer::download(Array &buffer) { - void *data = map(false); - buffer.resize(getSize()); - std::memcpy(buffer.data(), data, getSize()); - unmap(); +void IndexBuffer::download(Array &buffer) +{ + void *data = map(false); + buffer.resize(getSize()); + std::memcpy(buffer.data(), data, getSize()); + unmap(); } -void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { - Gfx::QueueOwnedResource::transferOwnership(newOwner); +void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) +{ + Gfx::QueueOwnedResource::transferOwnership(newOwner); } -void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { - Vulkan::Buffer::executeOwnershipBarrier(newOwner); +void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) +{ + Vulkan::Buffer::executeOwnershipBarrier(newOwner); } void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, - VkPipelineStageFlags dstStage) { - Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, - dstStage); + VkPipelineStageFlags dstStage) +{ + Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, + dstStage); } -VkAccessFlags IndexBuffer::getSourceAccessMask() { - return VK_ACCESS_MEMORY_WRITE_BIT; +VkAccessFlags IndexBuffer::getSourceAccessMask() +{ + return VK_ACCESS_MEMORY_WRITE_BIT; } -VkAccessFlags IndexBuffer::getDestAccessMask() { - return VK_ACCESS_INDEX_READ_BIT; +VkAccessFlags IndexBuffer::getDestAccessMask() +{ + return VK_ACCESS_INDEX_READ_BIT; } \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/Buffer.h b/src/Engine/Graphics/Vulkan/Buffer.h index 11eda84..d3fc91d 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.h +++ b/src/Engine/Graphics/Vulkan/Buffer.h @@ -39,8 +39,9 @@ protected: VkBufferUsageFlags usage; bool dynamic; std::string name; - void rotateBuffer(uint64 size); + void rotateBuffer(uint64 size, bool preserveContents = false); void createBuffer(uint64 size); + void copyBuffer(uint64 src, uint64 dest); void executeOwnershipBarrier(Gfx::QueueType newOwner); void executePipelineBarrier(VkAccessFlags srcAccess, @@ -129,7 +130,7 @@ public: virtual ~ShaderBuffer(); virtual void 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 unmap() override; diff --git a/src/Engine/Graphics/Vulkan/Command.cpp b/src/Engine/Graphics/Vulkan/Command.cpp index f9884a5..8739928 100644 --- a/src/Engine/Graphics/Vulkan/Command.cpp +++ b/src/Engine/Graphics/Vulkan/Command.cpp @@ -147,12 +147,12 @@ void Command::checkFence() { command->reset(); } - executingComputes.clear(); + pool->cacheCommands(std::move(executingComputes)); for(auto& command : executingRenders) { command->reset(); } - executingRenders.clear(); + pool->cacheCommands(std::move(executingRenders)); for(auto& descriptor : boundResources) { descriptor->unbind();