Working on visibility pass
This commit is contained in:
@@ -3,17 +3,18 @@ import Scene;
|
|||||||
|
|
||||||
groupshared MeshPayload p;
|
groupshared MeshPayload p;
|
||||||
groupshared uint head;
|
groupshared uint head;
|
||||||
|
groupshared MeshData mesh;
|
||||||
|
|
||||||
[numthreads(TASK_GROUP_SIZE, 1, 1)]
|
[numthreads(TASK_GROUP_SIZE, 1, 1)]
|
||||||
[shader("amplification")]
|
[shader("amplification")]
|
||||||
void taskMain(
|
void taskMain(
|
||||||
uint threadID: SV_GroupIndex,
|
uint threadID: SV_GroupThreadID,
|
||||||
uint groupID: SV_GroupID, )
|
uint groupID: SV_GroupID, )
|
||||||
{
|
{
|
||||||
MeshData mesh = pScene.meshData[pOffsets.instanceOffset + groupID];
|
|
||||||
if (threadID == 0)
|
if (threadID == 0)
|
||||||
{
|
{
|
||||||
head = 0;
|
head = 0;
|
||||||
|
mesh = pScene.meshData[pOffsets.instanceOffset + groupID];
|
||||||
p.instanceId = pOffsets.instanceOffset + groupID;
|
p.instanceId = pOffsets.instanceOffset + groupID;
|
||||||
p.meshletOffset = mesh.meshletOffset;
|
p.meshletOffset = mesh.meshletOffset;
|
||||||
p.cullingOffset = pScene.cullingOffsets[p.instanceId];
|
p.cullingOffset = pScene.cullingOffsets[p.instanceId];
|
||||||
@@ -24,8 +25,8 @@ void taskMain(
|
|||||||
uint m = p.meshletOffset + i;
|
uint m = p.meshletOffset + i;
|
||||||
uint cull = p.cullingOffset + i;
|
uint cull = p.cullingOffset + i;
|
||||||
MeshletDescription meshlet = pScene.meshletInfos[m];
|
MeshletDescription meshlet = pScene.meshletInfos[m];
|
||||||
MeshletCullingInfo culling = pScene.culledMeshlets[cull];
|
MeshletCullingInfo culling = pScene.cullingInfos[cull];
|
||||||
if(false)
|
//if(!culling.anyVisible())
|
||||||
{
|
{
|
||||||
uint index;
|
uint index;
|
||||||
InterlockedAdd(head, 1, index);
|
InterlockedAdd(head, 1, index);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ groupshared MeshData mesh;
|
|||||||
[numthreads(TASK_GROUP_SIZE, 1, 1)]
|
[numthreads(TASK_GROUP_SIZE, 1, 1)]
|
||||||
[shader("amplification")]
|
[shader("amplification")]
|
||||||
void taskMain(
|
void taskMain(
|
||||||
uint threadID: SV_GroupIndex,
|
uint threadID: SV_GroupThreadID,
|
||||||
uint groupID: SV_GroupID, )
|
uint groupID: SV_GroupID, )
|
||||||
{
|
{
|
||||||
if (threadID == 0)
|
if (threadID == 0)
|
||||||
@@ -25,7 +25,7 @@ void taskMain(
|
|||||||
uint m = p.meshletOffset + i;
|
uint m = p.meshletOffset + i;
|
||||||
uint cull = p.cullingOffset + i;
|
uint cull = p.cullingOffset + i;
|
||||||
MeshletDescription meshlet = pScene.meshletInfos[m];
|
MeshletDescription meshlet = pScene.meshletInfos[m];
|
||||||
MeshletCullingInfo culling = pScene.culledMeshlets[cull];
|
MeshletCullingInfo culling = pScene.cullingInfos[cull];
|
||||||
if(culling.anyVisible())
|
if(culling.anyVisible())
|
||||||
{
|
{
|
||||||
uint index;
|
uint index;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ struct PrimitiveAttributes
|
|||||||
[outputtopology("triangle")]
|
[outputtopology("triangle")]
|
||||||
[shader("mesh")]
|
[shader("mesh")]
|
||||||
void meshMain(
|
void meshMain(
|
||||||
in uint threadID: SV_GroupIndex,
|
in uint threadID: SV_GroupThreadID,
|
||||||
in uint groupID: SV_GroupID,
|
in uint groupID: SV_GroupID,
|
||||||
in payload MeshPayload meshPayload,
|
in payload MeshPayload meshPayload,
|
||||||
out vertices FragmentParameter vertices[MAX_VERTICES],
|
out vertices FragmentParameter vertices[MAX_VERTICES],
|
||||||
@@ -27,7 +27,7 @@ void meshMain(
|
|||||||
uint meshletId = meshPayload.cullingOffset + meshletNumber;
|
uint meshletId = meshPayload.cullingOffset + meshletNumber;
|
||||||
InstanceData inst = pScene.instances[meshPayload.instanceId];
|
InstanceData inst = pScene.instances[meshPayload.instanceId];
|
||||||
MeshletDescription m = pScene.meshletInfos[meshPayload.meshletOffset + meshletNumber];
|
MeshletDescription m = pScene.meshletInfos[meshPayload.meshletOffset + meshletNumber];
|
||||||
MeshletCullingInfo cull = pScene.culledMeshlets[meshletId];
|
MeshletCullingInfo cull = pScene.cullingInfos[meshletId];
|
||||||
SetMeshOutputCounts(m.vertexCount, m.primitiveCount);
|
SetMeshOutputCounts(m.vertexCount, m.primitiveCount);
|
||||||
|
|
||||||
for(uint i = threadID; i < MAX_PRIMITIVES; i += MESH_GROUP_SIZE)
|
for(uint i = threadID; i < MAX_PRIMITIVES; i += MESH_GROUP_SIZE)
|
||||||
|
|||||||
@@ -8,35 +8,15 @@ struct VisibilityCullingData
|
|||||||
};
|
};
|
||||||
ParameterBlock<VisibilityCullingData> pVisibilityParams;
|
ParameterBlock<VisibilityCullingData> pVisibilityParams;
|
||||||
|
|
||||||
groupshared MeshletCullingInfo cullInfo;
|
[numthreads(BLOCK_SIZE, BLOCK_SIZE, 1)]
|
||||||
|
|
||||||
[numthreads(BLOCK_SIZE, 1, 1)]
|
|
||||||
[shader("compute")]
|
[shader("compute")]
|
||||||
void computeMain(
|
void computeMain(
|
||||||
uint threadID: SV_GroupIndex,
|
uint3 dispatchThreadID: SV_DispatchThreadID,
|
||||||
uint groupID: SV_GroupID,
|
|
||||||
){
|
){
|
||||||
if (threadID < MAX_PRIMITIVES / 32)
|
int3 texCoords = int3(dispatchThreadID.xy, 0);
|
||||||
{
|
|
||||||
cullInfo.visible[threadID] = 0;
|
|
||||||
}
|
|
||||||
GroupMemoryBarrierWithGroupSync();
|
|
||||||
for (uint y = 0; y < pViewParams.screenDimensions.y; y++)
|
|
||||||
{
|
|
||||||
for (uint x = threadID; x < pViewParams.screenDimensions.x; x += BLOCK_SIZE)
|
|
||||||
{
|
|
||||||
int3 texCoords = int3(x, y, 0);
|
|
||||||
uint encoded = pVisibilityParams.visibilityTexture.Load(texCoords).r;
|
uint encoded = pVisibilityParams.visibilityTexture.Load(texCoords).r;
|
||||||
uint2 decoded = decodePrimitive(encoded);
|
uint2 decoded = decodePrimitive(encoded);
|
||||||
uint base = decoded.y == groupID ? 1 : 0;
|
|
||||||
uint arrIdx = decoded.x / 32;
|
uint arrIdx = decoded.x / 32;
|
||||||
uint bit = decoded.x % 32;
|
uint bit = decoded.x % 32;
|
||||||
cullInfo.visible[arrIdx] |= (base << bit);
|
pVisibilityParams.cullingInfos[decoded.y].visible[arrIdx] |= (1 << bit);
|
||||||
}
|
|
||||||
}
|
|
||||||
GroupMemoryBarrierWithGroupSync();
|
|
||||||
if (threadID < MAX_PRIMITIVES / 32)
|
|
||||||
{
|
|
||||||
pVisibilityParams.cullingInfos[groupID].visible[threadID] = cullInfo.visible[threadID];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -66,10 +66,10 @@ struct Scene
|
|||||||
StructuredBuffer<MeshletDescription> meshletInfos;
|
StructuredBuffer<MeshletDescription> meshletInfos;
|
||||||
StructuredBuffer<uint8_t> primitiveIndices;
|
StructuredBuffer<uint8_t> primitiveIndices;
|
||||||
StructuredBuffer<uint32_t> vertexIndices;
|
StructuredBuffer<uint32_t> vertexIndices;
|
||||||
StructuredBuffer<MeshletCullingInfo> culledMeshlets;
|
|
||||||
StructuredBuffer<uint32_t> cullingOffsets;
|
StructuredBuffer<uint32_t> cullingOffsets;
|
||||||
|
StructuredBuffer<MeshletCullingInfo> cullingInfos;
|
||||||
};
|
};
|
||||||
layout(set = 2)
|
layout(set=2)
|
||||||
ParameterBlock<Scene> pScene;
|
ParameterBlock<Scene> pScene;
|
||||||
|
|
||||||
uint32_t encodePrimitive(uint32_t primitiveId, uint32_t meshletId)
|
uint32_t encodePrimitive(uint32_t primitiveId, uint32_t meshletId)
|
||||||
|
|||||||
@@ -89,6 +89,8 @@ public:
|
|||||||
bool writeOnly = true) = 0;
|
bool writeOnly = true) = 0;
|
||||||
virtual void unmap() = 0;
|
virtual void unmap() = 0;
|
||||||
|
|
||||||
|
virtual void clear() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Inherited via QueueOwnedResource
|
// Inherited via QueueOwnedResource
|
||||||
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
|
||||||
|
|||||||
@@ -85,19 +85,6 @@ void BasePass::beginFrame(const Component::Camera& cam)
|
|||||||
|
|
||||||
void BasePass::render()
|
void BasePass::render()
|
||||||
{
|
{
|
||||||
oLightIndexList->pipelineBarrier(
|
|
||||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
|
||||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
|
||||||
tLightIndexList->pipelineBarrier(
|
|
||||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
|
||||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
|
||||||
oLightGrid->pipelineBarrier(
|
|
||||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
|
||||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
|
||||||
tLightGrid->pipelineBarrier(
|
|
||||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
|
||||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
|
||||||
|
|
||||||
opaqueCulling->updateBuffer(0, oLightIndexList);
|
opaqueCulling->updateBuffer(0, oLightIndexList);
|
||||||
opaqueCulling->updateTexture(1, oLightGrid);
|
opaqueCulling->updateTexture(1, oLightGrid);
|
||||||
transparentCulling->updateBuffer(0, tLightIndexList);
|
transparentCulling->updateBuffer(0, tLightIndexList);
|
||||||
@@ -112,6 +99,8 @@ void BasePass::render()
|
|||||||
permutation.setViewCulling(useViewCulling);
|
permutation.setViewCulling(useViewCulling);
|
||||||
for (VertexData* vertexData : VertexData::getList())
|
for (VertexData* vertexData : VertexData::getList())
|
||||||
{
|
{
|
||||||
|
vertexData->getInstanceDataSet()->updateBuffer(6, cullingBuffer);
|
||||||
|
vertexData->getInstanceDataSet()->writeChanges();
|
||||||
permutation.setVertexData(vertexData->getTypeName());
|
permutation.setVertexData(vertexData->getTypeName());
|
||||||
const auto& materials = vertexData->getMaterialData();
|
const auto& materials = vertexData->getMaterialData();
|
||||||
for (const auto& materialData : materials)
|
for (const auto& materialData : materials)
|
||||||
@@ -176,11 +165,11 @@ void BasePass::render()
|
|||||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||||
command->bindPipeline(pipeline);
|
command->bindPipeline(pipeline);
|
||||||
}
|
}
|
||||||
command->bindDescriptor(vertexData->getVertexDataSet());
|
|
||||||
command->bindDescriptor(viewParamsSet);
|
command->bindDescriptor(viewParamsSet);
|
||||||
|
command->bindDescriptor(vertexData->getVertexDataSet());
|
||||||
|
command->bindDescriptor(vertexData->getInstanceDataSet());
|
||||||
command->bindDescriptor(scene->getLightEnvironment()->getDescriptorSet());
|
command->bindDescriptor(scene->getLightEnvironment()->getDescriptorSet());
|
||||||
command->bindDescriptor(opaqueCulling);
|
command->bindDescriptor(opaqueCulling);
|
||||||
command->bindDescriptor(vertexData->getInstanceDataSet());
|
|
||||||
for (const auto& drawCall : materialData.instances)
|
for (const auto& drawCall : materialData.instances)
|
||||||
{
|
{
|
||||||
command->bindDescriptor(drawCall.materialInstance->getDescriptorSet());
|
command->bindDescriptor(drawCall.materialInstance->getDescriptorSet());
|
||||||
@@ -221,6 +210,8 @@ void BasePass::publishOutputs()
|
|||||||
|
|
||||||
void BasePass::createRenderPass()
|
void BasePass::createRenderPass()
|
||||||
{
|
{
|
||||||
|
cullingBuffer = resources->requestBuffer("CULLINGBUFFER");
|
||||||
|
|
||||||
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
|
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
|
||||||
depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
|
depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
|
||||||
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
|
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ private:
|
|||||||
PCameraActor source;
|
PCameraActor source;
|
||||||
Gfx::OPipelineLayout basePassLayout;
|
Gfx::OPipelineLayout basePassLayout;
|
||||||
Gfx::ODescriptorLayout lightCullingLayout;
|
Gfx::ODescriptorLayout lightCullingLayout;
|
||||||
|
|
||||||
|
Gfx::PShaderBuffer cullingBuffer;
|
||||||
};
|
};
|
||||||
DEFINE_REF(BasePass)
|
DEFINE_REF(BasePass)
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ void CachedDepthPass::render()
|
|||||||
for (VertexData *vertexData : VertexData::getList())
|
for (VertexData *vertexData : VertexData::getList())
|
||||||
{
|
{
|
||||||
permutation.setVertexData(vertexData->getTypeName());
|
permutation.setVertexData(vertexData->getTypeName());
|
||||||
|
vertexData->getInstanceDataSet()->updateBuffer(6, cullingBuffer);
|
||||||
|
vertexData->getInstanceDataSet()->writeChanges();
|
||||||
|
|
||||||
// Create Pipeline(VertexData)
|
// Create Pipeline(VertexData)
|
||||||
// Descriptors:
|
// Descriptors:
|
||||||
@@ -120,8 +122,8 @@ void CachedDepthPass::render()
|
|||||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||||
command->bindPipeline(pipeline);
|
command->bindPipeline(pipeline);
|
||||||
}
|
}
|
||||||
command->bindDescriptor(vertexData->getVertexDataSet());
|
|
||||||
command->bindDescriptor(viewParamsSet);
|
command->bindDescriptor(viewParamsSet);
|
||||||
|
command->bindDescriptor(vertexData->getVertexDataSet());
|
||||||
command->bindDescriptor(vertexData->getInstanceDataSet());
|
command->bindDescriptor(vertexData->getInstanceDataSet());
|
||||||
uint32 offset = 0;
|
uint32 offset = 0;
|
||||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &offset);
|
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &offset);
|
||||||
@@ -205,6 +207,8 @@ void CachedDepthPass::publishOutputs()
|
|||||||
|
|
||||||
void CachedDepthPass::createRenderPass()
|
void CachedDepthPass::createRenderPass()
|
||||||
{
|
{
|
||||||
|
cullingBuffer = resources->requestBuffer("CULLINGBUFFER");
|
||||||
|
|
||||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||||
.colorAttachments = {visibilityAttachment},
|
.colorAttachments = {visibilityAttachment},
|
||||||
.depthAttachment = depthAttachment,
|
.depthAttachment = depthAttachment,
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ private:
|
|||||||
Gfx::OTexture2D depthBuffer;
|
Gfx::OTexture2D depthBuffer;
|
||||||
Gfx::OTexture2D visibilityBuffer;
|
Gfx::OTexture2D visibilityBuffer;
|
||||||
Gfx::OPipelineLayout depthPrepassLayout;
|
Gfx::OPipelineLayout depthPrepassLayout;
|
||||||
|
|
||||||
|
Gfx::PShaderBuffer cullingBuffer;
|
||||||
};
|
};
|
||||||
DEFINE_REF(CachedDepthPass)
|
DEFINE_REF(CachedDepthPass)
|
||||||
}
|
}
|
||||||
@@ -66,6 +66,8 @@ void DepthPrepass::render()
|
|||||||
for (VertexData *vertexData : VertexData::getList())
|
for (VertexData *vertexData : VertexData::getList())
|
||||||
{
|
{
|
||||||
permutation.setVertexData(vertexData->getTypeName());
|
permutation.setVertexData(vertexData->getTypeName());
|
||||||
|
vertexData->getInstanceDataSet()->updateBuffer(6, cullingBuffer);
|
||||||
|
vertexData->getInstanceDataSet()->writeChanges();
|
||||||
// Create Pipeline(VertexData)
|
// Create Pipeline(VertexData)
|
||||||
// Descriptors:
|
// Descriptors:
|
||||||
// ViewData => global, static
|
// ViewData => global, static
|
||||||
@@ -119,14 +121,14 @@ void DepthPrepass::render()
|
|||||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||||
command->bindPipeline(pipeline);
|
command->bindPipeline(pipeline);
|
||||||
}
|
}
|
||||||
command->bindDescriptor(vertexData->getVertexDataSet());
|
|
||||||
command->bindDescriptor(viewParamsSet);
|
command->bindDescriptor(viewParamsSet);
|
||||||
|
command->bindDescriptor(vertexData->getVertexDataSet());
|
||||||
command->bindDescriptor(vertexData->getInstanceDataSet());
|
command->bindDescriptor(vertexData->getInstanceDataSet());
|
||||||
uint32 offset = 0;
|
uint32 offset = 0;
|
||||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &offset);
|
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &offset);
|
||||||
if (graphics->supportMeshShading())
|
if (graphics->supportMeshShading())
|
||||||
{
|
{
|
||||||
//command->drawMesh(vertexData->getNumInstances(), 1, 1);
|
command->drawMesh(vertexData->getNumInstances(), 1, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -174,6 +176,13 @@ void DepthPrepass::render()
|
|||||||
Gfx::SE_ACCESS_SHADER_READ_BIT,
|
Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT
|
||||||
);
|
);
|
||||||
|
// Sync culling reads to compute write
|
||||||
|
cullingBuffer->pipelineBarrier(
|
||||||
|
Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
|
Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT,
|
||||||
|
Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||||
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepthPrepass::endFrame()
|
void DepthPrepass::endFrame()
|
||||||
@@ -186,13 +195,15 @@ void DepthPrepass::publishOutputs()
|
|||||||
|
|
||||||
void DepthPrepass::createRenderPass()
|
void DepthPrepass::createRenderPass()
|
||||||
{
|
{
|
||||||
|
cullingBuffer = resources->requestBuffer("CULLINGBUFFER");
|
||||||
|
|
||||||
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
|
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
|
||||||
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||||
depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
|
depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
|
||||||
depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
|
depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
|
||||||
visibilityAttachment = resources->requestRenderTarget("VISIBILITY");
|
visibilityAttachment = resources->requestRenderTarget("VISIBILITY");
|
||||||
visibilityAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
visibilityAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||||
visibilityAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
visibilityAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
visibilityAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
|
visibilityAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
|
||||||
|
|
||||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ private:
|
|||||||
Gfx::RenderTargetAttachment depthAttachment;
|
Gfx::RenderTargetAttachment depthAttachment;
|
||||||
Gfx::RenderTargetAttachment visibilityAttachment;
|
Gfx::RenderTargetAttachment visibilityAttachment;
|
||||||
Gfx::OPipelineLayout depthPrepassLayout;
|
Gfx::OPipelineLayout depthPrepassLayout;
|
||||||
|
|
||||||
|
Gfx::PShaderBuffer cullingBuffer;
|
||||||
};
|
};
|
||||||
DEFINE_REF(DepthPrepass)
|
DEFINE_REF(DepthPrepass)
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
|
|||||||
@@ -81,6 +81,19 @@ void LightCullingPass::render()
|
|||||||
commands.add(std::move(computeCommand));
|
commands.add(std::move(computeCommand));
|
||||||
//std::cout << "Execute" << std::endl;
|
//std::cout << "Execute" << std::endl;
|
||||||
graphics->executeCommands(std::move(commands));
|
graphics->executeCommands(std::move(commands));
|
||||||
|
|
||||||
|
oLightIndexList->pipelineBarrier(
|
||||||
|
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
|
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
|
tLightIndexList->pipelineBarrier(
|
||||||
|
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
|
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
|
oLightGrid->pipelineBarrier(
|
||||||
|
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
|
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
|
tLightGrid->pipelineBarrier(
|
||||||
|
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
|
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightCullingPass::endFrame()
|
void LightCullingPass::endFrame()
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "VisibilityPass.h"
|
#include "VisibilityPass.h"
|
||||||
|
#include "Graphics/Shader.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
@@ -15,15 +16,46 @@ VisibilityPass::~VisibilityPass()
|
|||||||
void VisibilityPass::beginFrame(const Component::Camera& cam)
|
void VisibilityPass::beginFrame(const Component::Camera& cam)
|
||||||
{
|
{
|
||||||
RenderPass::beginFrame(cam);
|
RenderPass::beginFrame(cam);
|
||||||
visibilityDescriptor->reset();
|
|
||||||
visibilitySet = visibilityDescriptor->allocateDescriptorSet();
|
//Array<VertexData::MeshletCullingInfo> cullingData(VertexData::getMeshletCount());
|
||||||
visibilitySet->updateTexture(0, visibilityAttachment->getTexture());
|
//std::memset(cullingData.data(), 0xffff, cullingData.size() * sizeof(VertexData::MeshletCullingInfo));
|
||||||
visibliitySet->updateBuffer(StaticMeshVertexData::getInstance()->get)
|
|
||||||
|
//cullingBuffer->updateContents(ShaderBufferCreateInfo{
|
||||||
|
// .sourceData = {
|
||||||
|
// .size = VertexData::getMeshletCount() * sizeof(VertexData::MeshletCullingInfo),
|
||||||
|
// .data = (uint8 *)cullingData.data(),
|
||||||
|
// },
|
||||||
|
// .numElements = VertexData::getMeshletCount()});
|
||||||
|
//cullingBuffer->pipelineBarrier(
|
||||||
|
// Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
|
// Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
// Gfx::SE_ACCESS_MEMORY_WRITE_BIT,
|
||||||
|
// Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisibilityPass::render()
|
void VisibilityPass::render()
|
||||||
{
|
{
|
||||||
|
cullingBuffer->rotateBuffer(VertexData::getMeshletCount() * sizeof(VertexData::MeshletCullingInfo));
|
||||||
|
cullingBuffer->clear();
|
||||||
|
|
||||||
|
visibilityDescriptor->reset();
|
||||||
|
visibilitySet = visibilityDescriptor->allocateDescriptorSet();
|
||||||
|
visibilitySet->updateTexture(0, visibilityAttachment.getTexture());
|
||||||
|
visibilitySet->updateBuffer(1, cullingBuffer);
|
||||||
|
visibilitySet->writeChanges();
|
||||||
|
|
||||||
|
Gfx::OComputeCommand command = graphics->createComputeCommand("VisibilityCommand");
|
||||||
|
command->bindPipeline(visibilityPipeline);
|
||||||
|
command->bindDescriptor({viewParamsSet, visibilitySet});
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisibilityPass::endFrame()
|
void VisibilityPass::endFrame()
|
||||||
@@ -33,7 +65,10 @@ void VisibilityPass::endFrame()
|
|||||||
|
|
||||||
void VisibilityPass::publishOutputs()
|
void VisibilityPass::publishOutputs()
|
||||||
{
|
{
|
||||||
visibilityDescriptor = graphcis->createDescriptorLayout("pVisibilityParams");
|
uint32_t viewportWidth = viewport->getWidth();
|
||||||
|
uint32_t viewportHeight = viewport->getHeight();
|
||||||
|
threadGroupSize = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1));
|
||||||
|
visibilityDescriptor = graphics->createDescriptorLayout("pVisibilityParams");
|
||||||
visibilityDescriptor->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, });
|
visibilityDescriptor->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, });
|
||||||
visibilityDescriptor->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT, });
|
visibilityDescriptor->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT, });
|
||||||
visibilityDescriptor->create();
|
visibilityDescriptor->create();
|
||||||
@@ -55,6 +90,9 @@ void VisibilityPass::publishOutputs()
|
|||||||
pipelineInfo.computeShader = visibilityShader;
|
pipelineInfo.computeShader = visibilityShader;
|
||||||
pipelineInfo.pipelineLayout = std::move(visibilityLayout);
|
pipelineInfo.pipelineLayout = std::move(visibilityLayout);
|
||||||
visibilityPipeline = graphics->createComputePipeline(std::move(pipelineInfo));
|
visibilityPipeline = graphics->createComputePipeline(std::move(pipelineInfo));
|
||||||
|
|
||||||
|
cullingBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{.dynamic = true, .name = "CullingBuffer"});
|
||||||
|
resources->registerBufferOutput("CULLINGBUFFER", cullingBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisibilityPass::createRenderPass()
|
void VisibilityPass::createRenderPass()
|
||||||
|
|||||||
@@ -15,16 +15,18 @@ public:
|
|||||||
virtual void endFrame() override;
|
virtual void endFrame() override;
|
||||||
virtual void publishOutputs() override;
|
virtual void publishOutputs() override;
|
||||||
virtual void createRenderPass() override;
|
virtual void createRenderPass() override;
|
||||||
uint64 allocate
|
|
||||||
private:
|
private:
|
||||||
|
static constexpr uint32 BLOCK_SIZE = 32;
|
||||||
Gfx::RenderTargetAttachment visibilityAttachment;
|
Gfx::RenderTargetAttachment visibilityAttachment;
|
||||||
Gfx::PDescriptorSet visibilitySet;
|
Gfx::PDescriptorSet visibilitySet;
|
||||||
Gfx::ODescriptorLayout visibilityDescriptor;
|
Gfx::ODescriptorLayout visibilityDescriptor;
|
||||||
Gfx::OPipelineLayout visibilityLayout;
|
Gfx::OPipelineLayout visibilityLayout;
|
||||||
|
Gfx::OComputeShader visibilityShader;
|
||||||
Gfx::PComputePipeline visibilityPipeline;
|
Gfx::PComputePipeline visibilityPipeline;
|
||||||
|
|
||||||
// Holds culling information for every meshlet for each instance
|
// Holds culling information for every meshlet for each instance
|
||||||
Gfx::OShaderBuffer cullingBuffer;
|
Gfx::OShaderBuffer cullingBuffer;
|
||||||
|
glm::uvec3 threadGroupSize;
|
||||||
};
|
};
|
||||||
DEFINE_REF(VisibilityPass)
|
DEFINE_REF(VisibilityPass)
|
||||||
}
|
}
|
||||||
@@ -36,12 +36,13 @@ void ShaderCompiler::registerVertexData(VertexData *vd)
|
|||||||
|
|
||||||
void ShaderCompiler::registerRenderPass(std::string name, PassConfig config)
|
void ShaderCompiler::registerRenderPass(std::string name, PassConfig config)
|
||||||
{
|
{
|
||||||
passes[name] = config;
|
passes[name] = std::move(config);
|
||||||
compile();
|
compile();
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderPermutation ShaderCompiler::getTemplate(std::string name)
|
ShaderPermutation ShaderCompiler::getTemplate(std::string name)
|
||||||
{
|
{
|
||||||
|
std::scoped_lock lock(shadersLock);
|
||||||
ShaderPermutation permutation;
|
ShaderPermutation permutation;
|
||||||
PassConfig &pass = passes[name];
|
PassConfig &pass = passes[name];
|
||||||
if (pass.useMeshShading)
|
if (pass.useMeshShading)
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
constexpr static uint64 NUM_DEFAULT_ELEMENTS = 1024 * 1024;
|
constexpr static uint64 NUM_DEFAULT_ELEMENTS = 1024 * 1024;
|
||||||
|
Map<VertexData::MeshMapping, VertexData::CullingMapping> VertexData::instanceIdMap;
|
||||||
|
uint64 VertexData::instanceCount = 0;
|
||||||
|
uint64 VertexData::meshletCount = 0;
|
||||||
|
|
||||||
void VertexData::resetMeshData()
|
void VertexData::resetMeshData()
|
||||||
{
|
{
|
||||||
@@ -35,7 +38,7 @@ void VertexData::resetMeshData()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexData::updateMesh(PMesh mesh, Component::Transform &transform)
|
void VertexData::updateMesh(entt::entity id, uint32 meshIndex, PMesh mesh, Component::Transform &transform)
|
||||||
{
|
{
|
||||||
std::unique_lock l(materialDataLock);
|
std::unique_lock l(materialDataLock);
|
||||||
PMaterialInstance referencedInstance = mesh->referencedMaterial->getHandle();
|
PMaterialInstance referencedInstance = mesh->referencedMaterial->getHandle();
|
||||||
@@ -59,7 +62,9 @@ void VertexData::updateMesh(PMesh mesh, Component::Transform &transform)
|
|||||||
.inverseTransformMatrix = glm::inverse(transformMatrix),
|
.inverseTransformMatrix = glm::inverse(transformMatrix),
|
||||||
});
|
});
|
||||||
const auto &data = meshData[mesh->id];
|
const auto &data = meshData[mesh->id];
|
||||||
|
auto [instanceId, meshletOffset] = getCullingMapping(id, meshIndex, data.numMeshlets);
|
||||||
matInstanceData.instanceMeshData.add(data);
|
matInstanceData.instanceMeshData.add(data);
|
||||||
|
matInstanceData.cullingOffsets.add(meshletOffset);
|
||||||
referencedInstance->updateDescriptor();
|
referencedInstance->updateDescriptor();
|
||||||
for (size_t i = 0; i < 0; ++i)
|
for (size_t i = 0; i < 0; ++i)
|
||||||
{
|
{
|
||||||
@@ -120,7 +125,7 @@ void VertexData::createDescriptors()
|
|||||||
// instance.numMeshlets = 0;
|
// instance.numMeshlets = 0;
|
||||||
for (size_t i = 0; i < instance.instanceData.size(); ++i)
|
for (size_t i = 0; i < instance.instanceData.size(); ++i)
|
||||||
{
|
{
|
||||||
cullingOffsets.add(numMeshlets);
|
cullingOffsets.add(instance.cullingOffsets[i]);
|
||||||
instanceData.add(instance.instanceData[i]);
|
instanceData.add(instance.instanceData[i]);
|
||||||
instanceMeshData.add(instance.instanceMeshData[i]);
|
instanceMeshData.add(instance.instanceMeshData[i]);
|
||||||
// instance.numMeshlets += instance.instanceMeshData[i].numMeshlets;
|
// instance.numMeshlets += instance.instanceMeshData[i].numMeshlets;
|
||||||
@@ -129,8 +134,6 @@ void VertexData::createDescriptors()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Array<MeshletCullingInfo> cullingData(numMeshlets);
|
|
||||||
std::memset(cullingData.data(), 0xffff, cullingData.size() * sizeof(MeshletCullingInfo));
|
|
||||||
cullingOffsetBuffer->rotateBuffer(cullingOffsets.size() * sizeof(uint32));
|
cullingOffsetBuffer->rotateBuffer(cullingOffsets.size() * sizeof(uint32));
|
||||||
cullingOffsetBuffer->updateContents(ShaderBufferCreateInfo{
|
cullingOffsetBuffer->updateContents(ShaderBufferCreateInfo{
|
||||||
.sourceData = {
|
.sourceData = {
|
||||||
@@ -144,19 +147,6 @@ void VertexData::createDescriptors()
|
|||||||
Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
||||||
Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||||
|
|
||||||
cullingBuffer->rotateBuffer(cullingData.size() * sizeof(MeshletCullingInfo));
|
|
||||||
cullingBuffer->updateContents(ShaderBufferCreateInfo{
|
|
||||||
.sourceData = {
|
|
||||||
.size = cullingData.size() * sizeof(MeshletCullingInfo),
|
|
||||||
.data = (uint8 *)cullingData.data(),
|
|
||||||
},
|
|
||||||
.numElements = cullingData.size()});
|
|
||||||
cullingBuffer->pipelineBarrier(
|
|
||||||
Gfx::SE_ACCESS_TRANSFER_WRITE_BIT,
|
|
||||||
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
|
||||||
Gfx::SE_ACCESS_MEMORY_WRITE_BIT,
|
|
||||||
Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
|
||||||
|
|
||||||
instanceBuffer->rotateBuffer(instanceData.size() * sizeof(InstanceData));
|
instanceBuffer->rotateBuffer(instanceData.size() * sizeof(InstanceData));
|
||||||
instanceBuffer->updateContents(ShaderBufferCreateInfo{
|
instanceBuffer->updateContents(ShaderBufferCreateInfo{
|
||||||
.sourceData = {
|
.sourceData = {
|
||||||
@@ -189,10 +179,7 @@ void VertexData::createDescriptors()
|
|||||||
descriptorSet->updateBuffer(2, meshletBuffer);
|
descriptorSet->updateBuffer(2, meshletBuffer);
|
||||||
descriptorSet->updateBuffer(3, primitiveIndicesBuffer);
|
descriptorSet->updateBuffer(3, primitiveIndicesBuffer);
|
||||||
descriptorSet->updateBuffer(4, vertexIndicesBuffer);
|
descriptorSet->updateBuffer(4, vertexIndicesBuffer);
|
||||||
descriptorSet->updateBuffer(5, cullingBuffer);
|
descriptorSet->updateBuffer(5, cullingOffsetBuffer);
|
||||||
descriptorSet->updateBuffer(6, cullingOffsetBuffer);
|
|
||||||
|
|
||||||
descriptorSet->writeChanges();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet> loadedMeshlets)
|
void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet> loadedMeshlets)
|
||||||
@@ -339,19 +326,17 @@ void VertexData::init(Gfx::PGraphics _graphics)
|
|||||||
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||||
// vertexIndices
|
// vertexIndices
|
||||||
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||||
// cullingList
|
|
||||||
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
|
||||||
// cullingOffset
|
// cullingOffset
|
||||||
|
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||||
|
// cullingInfos
|
||||||
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 6, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 6, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER});
|
||||||
|
|
||||||
|
instanceDataLayout->create();
|
||||||
|
|
||||||
cullingOffsetBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
cullingOffsetBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
.dynamic = true,
|
.dynamic = true,
|
||||||
.name = "MeshletOffset",
|
.name = "MeshletOffset",
|
||||||
});
|
});
|
||||||
cullingBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
|
||||||
.dynamic = true,
|
|
||||||
.name = "MeshletCulling",
|
|
||||||
});
|
|
||||||
instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
.dynamic = true,
|
.dynamic = true,
|
||||||
.name = "InstanceBuffer",
|
.name = "InstanceBuffer",
|
||||||
@@ -360,7 +345,6 @@ void VertexData::init(Gfx::PGraphics _graphics)
|
|||||||
.dynamic = true,
|
.dynamic = true,
|
||||||
.name = "MeshDataBuffer",
|
.name = "MeshDataBuffer",
|
||||||
});
|
});
|
||||||
instanceDataLayout->create();
|
|
||||||
resizeBuffers();
|
resizeBuffers();
|
||||||
graphics->getShaderCompiler()->registerVertexData(this);
|
graphics->getShaderCompiler()->registerVertexData(this);
|
||||||
}
|
}
|
||||||
@@ -378,6 +362,17 @@ void VertexData::destroy()
|
|||||||
materialData.clear();
|
materialData.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VertexData::CullingMapping VertexData::getCullingMapping(entt::entity id, uint32 meshIndex, uint32 numMeshlets)
|
||||||
|
{
|
||||||
|
MeshMapping key = MeshMapping{.id = id, .meshId = meshIndex};
|
||||||
|
if (!instanceIdMap.contains(key))
|
||||||
|
{
|
||||||
|
instanceIdMap[key] = CullingMapping{.instanceId = instanceCount++, .cullingOffset = uint32(meshletCount)};
|
||||||
|
meshletCount += numMeshlets;
|
||||||
|
}
|
||||||
|
return instanceIdMap[key];
|
||||||
|
}
|
||||||
|
|
||||||
VertexData::VertexData()
|
VertexData::VertexData()
|
||||||
: idCounter(0), head(0), verticesAllocated(0), dirty(false)
|
: idCounter(0), head(0), verticesAllocated(0), dirty(false)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "Graphics/Descriptor.h"
|
#include "Graphics/Descriptor.h"
|
||||||
#include "Graphics/Buffer.h"
|
#include "Graphics/Buffer.h"
|
||||||
#include "Meshlet.h"
|
#include "Meshlet.h"
|
||||||
|
#include <entt/entt.hpp>
|
||||||
|
|
||||||
constexpr uint64 MAX_TEXCOORDS = 8;
|
constexpr uint64 MAX_TEXCOORDS = 8;
|
||||||
|
|
||||||
@@ -56,6 +57,7 @@ namespace Seele
|
|||||||
DrawCallOffsets offsets;
|
DrawCallOffsets offsets;
|
||||||
Array<InstanceData> instanceData;
|
Array<InstanceData> instanceData;
|
||||||
Array<MeshData> instanceMeshData;
|
Array<MeshData> instanceMeshData;
|
||||||
|
Array<uint32> cullingOffsets;
|
||||||
};
|
};
|
||||||
struct MaterialData
|
struct MaterialData
|
||||||
{
|
{
|
||||||
@@ -63,7 +65,7 @@ namespace Seele
|
|||||||
Array<BatchedDrawCall> instances;
|
Array<BatchedDrawCall> instances;
|
||||||
};
|
};
|
||||||
void resetMeshData();
|
void resetMeshData();
|
||||||
void updateMesh(PMesh mesh, Component::Transform &transform);
|
void updateMesh(entt::entity id, uint32 meshIndex, PMesh mesh, Component::Transform &transform);
|
||||||
void createDescriptors();
|
void createDescriptors();
|
||||||
void loadMesh(MeshId id, Array<uint32> indices, Array<Meshlet> meshlets);
|
void loadMesh(MeshId id, Array<uint32> indices, Array<Meshlet> meshlets);
|
||||||
MeshId allocateVertexData(uint64 numVertices);
|
MeshId allocateVertexData(uint64 numVertices);
|
||||||
@@ -87,6 +89,15 @@ namespace Seele
|
|||||||
virtual void init(Gfx::PGraphics graphics);
|
virtual void init(Gfx::PGraphics graphics);
|
||||||
virtual void destroy();
|
virtual void destroy();
|
||||||
|
|
||||||
|
struct CullingMapping
|
||||||
|
{
|
||||||
|
uint64 instanceId;
|
||||||
|
uint32 cullingOffset;
|
||||||
|
};
|
||||||
|
static CullingMapping getCullingMapping(entt::entity id, uint32 meshIndex, uint32 numMeshlets);
|
||||||
|
static uint64 getInstanceCount() { return instanceCount; }
|
||||||
|
static uint64 getMeshletCount() { return meshletCount; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void resizeBuffers() = 0;
|
virtual void resizeBuffers() = 0;
|
||||||
virtual void updateBuffers() = 0;
|
virtual void updateBuffers() = 0;
|
||||||
@@ -111,6 +122,17 @@ namespace Seele
|
|||||||
Array<uint8> primitiveIndices;
|
Array<uint8> primitiveIndices;
|
||||||
Array<uint32> vertexIndices;
|
Array<uint32> vertexIndices;
|
||||||
Array<uint32> indices;
|
Array<uint32> indices;
|
||||||
|
|
||||||
|
struct MeshMapping
|
||||||
|
{
|
||||||
|
entt::entity id;
|
||||||
|
uint32 meshId;
|
||||||
|
auto operator<=>(const MeshMapping& other) const = default;
|
||||||
|
};
|
||||||
|
static Map<MeshMapping, CullingMapping> instanceIdMap;
|
||||||
|
static uint64 instanceCount;
|
||||||
|
static uint64 meshletCount;
|
||||||
|
|
||||||
Gfx::PGraphics graphics;
|
Gfx::PGraphics graphics;
|
||||||
Gfx::ODescriptorLayout instanceDataLayout;
|
Gfx::ODescriptorLayout instanceDataLayout;
|
||||||
// for mesh shading
|
// for mesh shading
|
||||||
|
|||||||
@@ -389,6 +389,11 @@ void *ShaderBuffer::mapRegion(uint64 offset, uint64 size, bool writeOnly) {
|
|||||||
|
|
||||||
void ShaderBuffer::unmap() { Vulkan::Buffer::unmap(); }
|
void ShaderBuffer::unmap() { Vulkan::Buffer::unmap(); }
|
||||||
|
|
||||||
|
void ShaderBuffer::clear()
|
||||||
|
{
|
||||||
|
vkCmdFillBuffer(graphics->getQueueCommands(owner)->getCommands()->getHandle(), Vulkan::Buffer::getHandle(), 0, VK_WHOLE_SIZE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void ShaderBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) {
|
void ShaderBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) {
|
||||||
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
Gfx::QueueOwnedResource::transferOwnership(newOwner);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,6 +133,8 @@ public:
|
|||||||
virtual void *mapRegion(uint64 offset, uint64 size, bool writeOnly) override;
|
virtual void *mapRegion(uint64 offset, uint64 size, bool writeOnly) override;
|
||||||
virtual void unmap() override;
|
virtual void unmap() override;
|
||||||
|
|
||||||
|
virtual void clear() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Inherited via Vulkan::Buffer
|
// Inherited via Vulkan::Buffer
|
||||||
virtual VkAccessFlags getSourceAccessMask() override;
|
virtual VkAccessFlags getSourceAccessMask() override;
|
||||||
|
|||||||
@@ -27,10 +27,11 @@ public:
|
|||||||
void setupView(Dependencies<Deps...>)
|
void setupView(Dependencies<Deps...>)
|
||||||
{
|
{
|
||||||
//List<std::function<void()>> work;
|
//List<std::function<void()>> work;
|
||||||
registry.view<Components..., Deps...>().each([&](Components&... comp, Deps&... deps){
|
registry.view<Components..., Deps...>().each([&](entt::entity id, Components&... comp, Deps&... deps){
|
||||||
//work.add([&]() {
|
//work.add([&]() {
|
||||||
(accessComponent(deps), ...);
|
(accessComponent(deps), ...);
|
||||||
update(comp...);
|
update(comp...);
|
||||||
|
update(id, comp...);
|
||||||
//});
|
//});
|
||||||
});
|
});
|
||||||
//getThreadPool().runAndWait(std::move(work));
|
//getThreadPool().runAndWait(std::move(work));
|
||||||
@@ -41,7 +42,8 @@ public:
|
|||||||
setupView((getDependencies<Components>() | ...));
|
setupView((getDependencies<Components>() | ...));
|
||||||
}
|
}
|
||||||
virtual void update() override {}
|
virtual void update() override {}
|
||||||
virtual void update(Components&... components) = 0;
|
virtual void update(Components&... components) {}
|
||||||
|
virtual void update(entt::entity id, Components&... components) {}
|
||||||
};
|
};
|
||||||
} // namespace System
|
} // namespace System
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ MeshUpdater::~MeshUpdater()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshUpdater::update(Component::Transform& transform, Component::Mesh& comp)
|
void MeshUpdater::update(entt::entity id, Component::Transform& transform, Component::Mesh& comp)
|
||||||
{
|
{
|
||||||
for (auto& mesh : comp.asset->meshes)
|
for (uint32 i = 0; i < comp.asset->meshes.size(); ++i)
|
||||||
{
|
{
|
||||||
mesh->vertexData->updateMesh(mesh, transform);
|
comp.asset->meshes[i]->vertexData->updateMesh(id, i, comp.asset->meshes[i], transform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class MeshUpdater : public ComponentSystem<Component::Transform, Component::Mesh
|
|||||||
public:
|
public:
|
||||||
MeshUpdater(PScene scene);
|
MeshUpdater(PScene scene);
|
||||||
virtual ~MeshUpdater();
|
virtual ~MeshUpdater();
|
||||||
virtual void update(Component::Transform& transform, Component::Mesh& mesh) override;
|
virtual void update(entt::entity id, Component::Transform& transform, Component::Mesh& mesh) override;
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
} // namespace System
|
} // namespace System
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "System/CameraUpdater.h"
|
#include "System/CameraUpdater.h"
|
||||||
#include "Graphics/RenderPass/CachedDepthPass.h"
|
#include "Graphics/RenderPass/CachedDepthPass.h"
|
||||||
#include "Graphics/RenderPass/DepthPrepass.h"
|
#include "Graphics/RenderPass/DepthPrepass.h"
|
||||||
|
#include "Graphics/RenderPass/VisibilityPass.h"
|
||||||
#include "Graphics/RenderPass/LightCullingPass.h"
|
#include "Graphics/RenderPass/LightCullingPass.h"
|
||||||
#include "Graphics/RenderPass/BasePass.h"
|
#include "Graphics/RenderPass/BasePass.h"
|
||||||
#include "Graphics/RenderPass/SkyboxRenderPass.h"
|
#include "Graphics/RenderPass/SkyboxRenderPass.h"
|
||||||
@@ -28,6 +29,7 @@ GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate
|
|||||||
reloadGame();
|
reloadGame();
|
||||||
renderGraph.addPass(new CachedDepthPass(graphics, scene));
|
renderGraph.addPass(new CachedDepthPass(graphics, scene));
|
||||||
renderGraph.addPass(new DepthPrepass(graphics, scene));
|
renderGraph.addPass(new DepthPrepass(graphics, scene));
|
||||||
|
renderGraph.addPass(new VisibilityPass(graphics, scene));
|
||||||
renderGraph.addPass(new LightCullingPass(graphics, scene));
|
renderGraph.addPass(new LightCullingPass(graphics, scene));
|
||||||
renderGraph.addPass(new BasePass(graphics, scene));
|
renderGraph.addPass(new BasePass(graphics, scene));
|
||||||
renderGraph.addPass(new DebugPass(graphics, scene));
|
renderGraph.addPass(new DebugPass(graphics, scene));
|
||||||
|
|||||||
Reference in New Issue
Block a user