Lot of synchronization changes
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,15 +8,22 @@ struct VisibilityCullingData
|
||||
};
|
||||
ParameterBlock<VisibilityCullingData> 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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<Gfx::SubPassDependency> 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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<Gfx::SubPassDependency> 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);
|
||||
}
|
||||
|
||||
@@ -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<VertexData::MeshletCullingInfo> 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<Gfx::OComputeCommand> 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()
|
||||
|
||||
@@ -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<Vulkan::Buffer *, PendingBuffer> pendingBuffers;
|
||||
@@ -25,281 +28,364 @@ static Map<Vulkan::Buffer *, PendingBuffer> 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<uint8> &buffer) {
|
||||
void *data = map(false);
|
||||
buffer.resize(getSize());
|
||||
std::memcpy(buffer.data(), data, getSize());
|
||||
unmap();
|
||||
void VertexBuffer::download(Array<uint8> &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<uint8> &buffer) {
|
||||
void *data = map(false);
|
||||
buffer.resize(getSize());
|
||||
std::memcpy(buffer.data(), data, getSize());
|
||||
unmap();
|
||||
void IndexBuffer::download(Array<uint8> &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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user