Lots of shader changes, basic primitive writing
This commit is contained in:
@@ -9,21 +9,21 @@ extern bool useViewCulling;
|
||||
CachedDepthPass::CachedDepthPass(Gfx::PGraphics graphics, PScene scene)
|
||||
: RenderPass(graphics, scene)
|
||||
{
|
||||
depthPrepassLayout = graphics->createPipelineLayout("CachedDepthLayout");
|
||||
depthPrepassLayout->addDescriptorLayout(viewParamsLayout);
|
||||
depthPrepassLayout->addPushConstants(Gfx::SePushConstantRange{
|
||||
.stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT,
|
||||
.offset = 0,
|
||||
.size = sizeof(VertexData::DrawCallOffsets),
|
||||
});
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "CachedDepthPass", "MeshletPass", false, false, "", true, true, "DrawListTask");
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "CachedDepthPass", "LegacyPass");
|
||||
}
|
||||
depthPrepassLayout = graphics->createPipelineLayout("CachedDepthLayout");
|
||||
depthPrepassLayout->addDescriptorLayout(viewParamsLayout);
|
||||
depthPrepassLayout->addPushConstants(Gfx::SePushConstantRange{
|
||||
.stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT,
|
||||
.offset = 0,
|
||||
.size = sizeof(VertexData::DrawCallOffsets),
|
||||
});
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "CachedDepthPass", "VisibilityMeshletPass", false, true, "VisibilityPass", true, true, "DrawListTask");
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "CachedDepthPass", "LegacyPass");
|
||||
}
|
||||
}
|
||||
|
||||
CachedDepthPass::~CachedDepthPass()
|
||||
@@ -32,117 +32,130 @@ CachedDepthPass::~CachedDepthPass()
|
||||
|
||||
void CachedDepthPass::beginFrame(const Component::Camera &cam)
|
||||
{
|
||||
RenderPass::beginFrame(cam);
|
||||
RenderPass::beginFrame(cam);
|
||||
}
|
||||
|
||||
void CachedDepthPass::render()
|
||||
{
|
||||
graphics->beginRenderPass(renderPass);
|
||||
Array<Gfx::ORenderCommand> commands;
|
||||
graphics->beginRenderPass(renderPass);
|
||||
Array<Gfx::ORenderCommand> commands;
|
||||
|
||||
Gfx::ShaderPermutation permutation;
|
||||
permutation.setPositionOnly(usePositionOnly);
|
||||
permutation.setViewCulling(useViewCulling);
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
permutation.setTaskFile("DrawListTask");
|
||||
permutation.setMeshFile("MeshletPass");
|
||||
}
|
||||
else
|
||||
{
|
||||
permutation.setVertexFile("LegacyPass");
|
||||
}
|
||||
for (VertexData *vertexData : VertexData::getList())
|
||||
{
|
||||
permutation.setVertexData(vertexData->getTypeName());
|
||||
|
||||
// Create Pipeline(VertexData)
|
||||
// Descriptors:
|
||||
// ViewData => global, static
|
||||
// VertexData => per meshtype
|
||||
// SceneData => per meshtype
|
||||
Gfx::PermutationId id(permutation);
|
||||
|
||||
Gfx::ORenderCommand command = graphics->createRenderCommand("DepthRender");
|
||||
command->setViewport(viewport);
|
||||
|
||||
const Gfx::ShaderCollection *collection = graphics->getShaderCompiler()->findShaders(id);
|
||||
assert(collection != nullptr);
|
||||
Gfx::ShaderPermutation permutation;
|
||||
permutation.setPositionOnly(usePositionOnly);
|
||||
permutation.setViewCulling(useViewCulling);
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||
.taskShader = collection->taskShader,
|
||||
.meshShader = collection->meshShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.multisampleState = {
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState = {
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend = {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
permutation.setTaskFile("DrawListTask");
|
||||
permutation.setMeshFile("VisibilityMeshletPass");
|
||||
}
|
||||
else
|
||||
{
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
||||
.vertexShader = collection->vertexShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.multisampleState = {
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState = {
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend = {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
permutation.setVertexFile("LegacyPass");
|
||||
}
|
||||
command->bindDescriptor(vertexData->getVertexDataSet());
|
||||
command->bindDescriptor(viewParamsSet);
|
||||
command->bindDescriptor(vertexData->getInstanceDataSet());
|
||||
uint32 offset = 0;
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &offset);
|
||||
if (graphics->supportMeshShading())
|
||||
permutation.setFragmentFile("VisibilityPass");
|
||||
for (VertexData *vertexData : VertexData::getList())
|
||||
{
|
||||
command->drawMesh(vertexData->getNumInstances(), 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto &materials = vertexData->getMaterialData();
|
||||
for (const auto &materialData : materials)
|
||||
{
|
||||
// material not used for any active meshes, skip
|
||||
if (materialData.instances.size() == 0)
|
||||
continue;
|
||||
for (const auto &drawCall : materialData.instances)
|
||||
permutation.setVertexData(vertexData->getTypeName());
|
||||
|
||||
// Create Pipeline(VertexData)
|
||||
// Descriptors:
|
||||
// ViewData => global, static
|
||||
// VertexData => per meshtype
|
||||
// SceneData => per meshtype
|
||||
Gfx::PermutationId id(permutation);
|
||||
|
||||
Gfx::ORenderCommand command = graphics->createRenderCommand("DepthRender");
|
||||
command->setViewport(viewport);
|
||||
|
||||
const Gfx::ShaderCollection *collection = graphics->getShaderCompiler()->findShaders(id);
|
||||
assert(collection != nullptr);
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
||||
uint32 inst = drawCall.offsets.instanceOffset;
|
||||
for (const auto &meshData : drawCall.instanceMeshData)
|
||||
{
|
||||
// all meshlets of a mesh share the same indices offset
|
||||
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset), inst++);
|
||||
}
|
||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||
.taskShader = collection->taskShader,
|
||||
.meshShader = collection->meshShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.multisampleState = {
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState = {
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend = {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
||||
.vertexShader = collection->vertexShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.multisampleState = {
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState = {
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend = {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
}
|
||||
command->bindDescriptor(vertexData->getVertexDataSet());
|
||||
command->bindDescriptor(viewParamsSet);
|
||||
command->bindDescriptor(vertexData->getInstanceDataSet());
|
||||
uint32 offset = 0;
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &offset);
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
command->drawMesh(vertexData->getNumInstances(), 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto &materials = vertexData->getMaterialData();
|
||||
for (const auto &materialData : materials)
|
||||
{
|
||||
// material not used for any active meshes, skip
|
||||
if (materialData.instances.size() == 0)
|
||||
continue;
|
||||
for (const auto &drawCall : materialData.instances)
|
||||
{
|
||||
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
||||
uint32 inst = drawCall.offsets.instanceOffset;
|
||||
for (const auto &meshData : drawCall.instanceMeshData)
|
||||
{
|
||||
// all meshlets of a mesh share the same indices offset
|
||||
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset), inst++);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
commands.add(std::move(command));
|
||||
}
|
||||
commands.add(std::move(command));
|
||||
}
|
||||
|
||||
graphics->executeCommands(std::move(commands));
|
||||
graphics->endRenderPass();
|
||||
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);
|
||||
// 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);
|
||||
}
|
||||
|
||||
void CachedDepthPass::endFrame()
|
||||
@@ -151,72 +164,66 @@ void CachedDepthPass::endFrame()
|
||||
|
||||
void CachedDepthPass::publishOutputs()
|
||||
{
|
||||
// If we render to a part of an image, the depth buffer itself must
|
||||
// still match the size of the whole image or their coordinate systems go out of sync
|
||||
TextureCreateInfo depthBufferInfo = {
|
||||
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
||||
.width = viewport->getOwner()->getFramebufferWidth(),
|
||||
.height = viewport->getOwner()->getFramebufferHeight(),
|
||||
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
||||
};
|
||||
depthBuffer = graphics->createTexture2D(depthBufferInfo);
|
||||
depthAttachment =
|
||||
Gfx::RenderTargetAttachment(depthBuffer,
|
||||
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
resources->registerRenderPassOutput("DEPTHPREPASS_DEPTH", depthAttachment);
|
||||
// If we render to a part of an image, the depth buffer itself must
|
||||
// still match the size of the whole image or their coordinate systems go out of sync
|
||||
TextureCreateInfo depthBufferInfo = {
|
||||
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
||||
.width = viewport->getOwner()->getFramebufferWidth(),
|
||||
.height = viewport->getOwner()->getFramebufferHeight(),
|
||||
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
||||
};
|
||||
depthBuffer = graphics->createTexture2D(depthBufferInfo);
|
||||
depthAttachment =
|
||||
Gfx::RenderTargetAttachment(depthBuffer,
|
||||
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
resources->registerRenderPassOutput("DEPTHPREPASS_DEPTH", depthAttachment);
|
||||
|
||||
TextureCreateInfo visibilityInfo = {
|
||||
.format = Gfx::SE_FORMAT_R32G32_UINT,
|
||||
.width = viewport->getOwner()->getFramebufferWidth(),
|
||||
.height = viewport->getOwner()->getFramebufferHeight(),
|
||||
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
};
|
||||
visibilityBuffer = graphics->createTexture2D(visibilityInfo);
|
||||
visibilityAttachment =
|
||||
Gfx::RenderTargetAttachment(visibilityBuffer,
|
||||
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
resources->registerRenderPassOutput("VISIBILITY", visibilityAttachment);
|
||||
TextureCreateInfo visibilityInfo = {
|
||||
.format = Gfx::SE_FORMAT_R32_UINT,
|
||||
.width = viewport->getOwner()->getFramebufferWidth(),
|
||||
.height = viewport->getOwner()->getFramebufferHeight(),
|
||||
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
|
||||
};
|
||||
visibilityBuffer = graphics->createTexture2D(visibilityInfo);
|
||||
visibilityAttachment =
|
||||
Gfx::RenderTargetAttachment(visibilityBuffer,
|
||||
Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
resources->registerRenderPassOutput("VISIBILITY", visibilityAttachment);
|
||||
}
|
||||
|
||||
void CachedDepthPass::createRenderPass()
|
||||
{
|
||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||
.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 = 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,
|
||||
}};
|
||||
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport);
|
||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||
.colorAttachments = {visibilityAttachment},
|
||||
.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,
|
||||
// }
|
||||
};
|
||||
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport);
|
||||
}
|
||||
|
||||
@@ -9,21 +9,21 @@ extern bool useViewCulling;
|
||||
DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene)
|
||||
: RenderPass(graphics, scene)
|
||||
{
|
||||
depthPrepassLayout = graphics->createPipelineLayout("DepthPrepassLayout");
|
||||
depthPrepassLayout->addDescriptorLayout(viewParamsLayout);
|
||||
depthPrepassLayout->addPushConstants(Gfx::SePushConstantRange{
|
||||
.stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT,
|
||||
.offset = 0,
|
||||
.size = sizeof(VertexData::DrawCallOffsets),
|
||||
});
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "MeshletPass", false, false, "", true, true, "ViewCullingTask");
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "LegacyPass");
|
||||
}
|
||||
depthPrepassLayout = graphics->createPipelineLayout("DepthPrepassLayout");
|
||||
depthPrepassLayout->addDescriptorLayout(viewParamsLayout);
|
||||
depthPrepassLayout->addPushConstants(Gfx::SePushConstantRange{
|
||||
.stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT,
|
||||
.offset = 0,
|
||||
.size = sizeof(VertexData::DrawCallOffsets),
|
||||
});
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "VisibilityMeshletPass", false, true, "VisibilityPass", true, true, "DepthCullingTask");
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "LegacyPass");
|
||||
}
|
||||
}
|
||||
|
||||
DepthPrepass::~DepthPrepass()
|
||||
@@ -32,116 +32,138 @@ DepthPrepass::~DepthPrepass()
|
||||
|
||||
void DepthPrepass::beginFrame(const Component::Camera &cam)
|
||||
{
|
||||
RenderPass::beginFrame(cam);
|
||||
RenderPass::beginFrame(cam);
|
||||
}
|
||||
|
||||
void DepthPrepass::render()
|
||||
{
|
||||
graphics->beginRenderPass(renderPass);
|
||||
Array<Gfx::ORenderCommand> commands;
|
||||
graphics->beginRenderPass(renderPass);
|
||||
Array<Gfx::ORenderCommand> commands;
|
||||
|
||||
Gfx::ShaderPermutation permutation;
|
||||
permutation.setPositionOnly(usePositionOnly);
|
||||
permutation.setViewCulling(useViewCulling);
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
permutation.setTaskFile("ViewCullingTask");
|
||||
permutation.setMeshFile("MeshletPass");
|
||||
}
|
||||
else
|
||||
{
|
||||
permutation.setVertexFile("LegacyPass");
|
||||
}
|
||||
for (VertexData *vertexData : VertexData::getList())
|
||||
{
|
||||
permutation.setVertexData(vertexData->getTypeName());
|
||||
// Create Pipeline(VertexData)
|
||||
// Descriptors:
|
||||
// ViewData => global, static
|
||||
// VertexData => per meshtype
|
||||
// SceneData => per meshtype
|
||||
Gfx::PermutationId id(permutation);
|
||||
|
||||
Gfx::ORenderCommand command = graphics->createRenderCommand("DepthRender");
|
||||
command->setViewport(viewport);
|
||||
|
||||
const Gfx::ShaderCollection *collection = graphics->getShaderCompiler()->findShaders(id);
|
||||
assert(collection != nullptr);
|
||||
Gfx::ShaderPermutation permutation;
|
||||
permutation.setPositionOnly(usePositionOnly);
|
||||
permutation.setViewCulling(useViewCulling);
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||
.taskShader = collection->taskShader,
|
||||
.meshShader = collection->meshShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.multisampleState = {
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState = {
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend = {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
permutation.setTaskFile("DepthCullingTask");
|
||||
permutation.setMeshFile("VisibilityMeshletPass");
|
||||
}
|
||||
else
|
||||
{
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
||||
.vertexShader = collection->vertexShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.multisampleState = {
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState = {
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend = {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
permutation.setVertexFile("LegacyPass");
|
||||
}
|
||||
command->bindDescriptor(vertexData->getVertexDataSet());
|
||||
command->bindDescriptor(viewParamsSet);
|
||||
command->bindDescriptor(vertexData->getInstanceDataSet());
|
||||
uint32 offset = 0;
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &offset);
|
||||
if (graphics->supportMeshShading())
|
||||
permutation.setFragmentFile("VisibilityPass");
|
||||
for (VertexData *vertexData : VertexData::getList())
|
||||
{
|
||||
command->drawMesh(vertexData->getNumInstances(), 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto &materials = vertexData->getMaterialData();
|
||||
for (const auto &materialData : materials)
|
||||
{
|
||||
for (const auto &drawCall : materialData.instances)
|
||||
permutation.setVertexData(vertexData->getTypeName());
|
||||
// Create Pipeline(VertexData)
|
||||
// Descriptors:
|
||||
// ViewData => global, static
|
||||
// VertexData => per meshtype
|
||||
// SceneData => per meshtype
|
||||
Gfx::PermutationId id(permutation);
|
||||
|
||||
Gfx::ORenderCommand command = graphics->createRenderCommand("DepthRender");
|
||||
command->setViewport(viewport);
|
||||
|
||||
const Gfx::ShaderCollection *collection = graphics->getShaderCompiler()->findShaders(id);
|
||||
assert(collection != nullptr);
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
// material not used for any active meshes, skip
|
||||
if (materialData.instances.size() == 0)
|
||||
continue;
|
||||
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
||||
uint32 inst = drawCall.offsets.instanceOffset;
|
||||
for (const auto &meshData : drawCall.instanceMeshData)
|
||||
{
|
||||
// all meshlets of a mesh share the same indices offset
|
||||
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset), inst++);
|
||||
}
|
||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||
.taskShader = collection->taskShader,
|
||||
.meshShader = collection->meshShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.multisampleState = {
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState = {
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend = {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
||||
.vertexShader = collection->vertexShader,
|
||||
.fragmentShader = collection->fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = collection->pipelineLayout,
|
||||
.multisampleState = {
|
||||
.samples = viewport->getSamples(),
|
||||
},
|
||||
.depthStencilState = {
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend = {
|
||||
.attachmentCount = 1,
|
||||
},
|
||||
};
|
||||
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
command->bindPipeline(pipeline);
|
||||
}
|
||||
command->bindDescriptor(vertexData->getVertexDataSet());
|
||||
command->bindDescriptor(viewParamsSet);
|
||||
command->bindDescriptor(vertexData->getInstanceDataSet());
|
||||
uint32 offset = 0;
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &offset);
|
||||
if (graphics->supportMeshShading())
|
||||
{
|
||||
command->drawMesh(vertexData->getNumInstances(), 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto &materials = vertexData->getMaterialData();
|
||||
for (const auto &materialData : materials)
|
||||
{
|
||||
for (const auto &drawCall : materialData.instances)
|
||||
{
|
||||
// material not used for any active meshes, skip
|
||||
if (materialData.instances.size() == 0)
|
||||
continue;
|
||||
command->bindIndexBuffer(vertexData->getIndexBuffer());
|
||||
uint32 inst = drawCall.offsets.instanceOffset;
|
||||
for (const auto &meshData : drawCall.instanceMeshData)
|
||||
{
|
||||
// all meshlets of a mesh share the same indices offset
|
||||
command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, vertexData->getIndicesOffset(meshData.meshletOffset), inst++);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
commands.add(std::move(command));
|
||||
}
|
||||
commands.add(std::move(command));
|
||||
}
|
||||
|
||||
graphics->executeCommands(std::move(commands));
|
||||
graphics->endRenderPass();
|
||||
graphics->executeCommands(std::move(commands));
|
||||
graphics->endRenderPass();
|
||||
// Sync depth read/write with compute 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_SHADER_READ_BIT,
|
||||
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
|
||||
);
|
||||
// Sync visibility write with compute read
|
||||
visibilityAttachment.getTexture()->pipelineBarrier(
|
||||
Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT
|
||||
);
|
||||
}
|
||||
|
||||
void DepthPrepass::endFrame()
|
||||
@@ -154,59 +176,60 @@ void DepthPrepass::publishOutputs()
|
||||
|
||||
void DepthPrepass::createRenderPass()
|
||||
{
|
||||
auto depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
|
||||
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
|
||||
depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
|
||||
auto visibilityAttachment = resources->requestRenderTarget("VISIBILITY");
|
||||
visibilityAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
visibilityAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
visibilityAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
|
||||
depthAttachment = resources->requestRenderTarget("DEPTHPREPASS_DEPTH");
|
||||
depthAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
depthAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL);
|
||||
depthAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
|
||||
visibilityAttachment = resources->requestRenderTarget("VISIBILITY");
|
||||
visibilityAttachment.setInitialLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
visibilityAttachment.setFinalLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
visibilityAttachment.setLoadOp(Gfx::SE_ATTACHMENT_LOAD_OP_LOAD);
|
||||
|
||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||
.colorAttachments = {visibilityAttachment},
|
||||
.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,
|
||||
}};
|
||||
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport);
|
||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||
.colorAttachments = {visibilityAttachment},
|
||||
.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,
|
||||
// }
|
||||
};
|
||||
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ public:
|
||||
virtual void createRenderPass() override;
|
||||
private:
|
||||
Gfx::RenderTargetAttachment depthAttachment;
|
||||
Gfx::RenderTargetAttachment visibilityAttachment;
|
||||
Gfx::OPipelineLayout depthPrepassLayout;
|
||||
};
|
||||
DEFINE_REF(DepthPrepass)
|
||||
|
||||
@@ -130,7 +130,7 @@ void VertexData::createDescriptors()
|
||||
}
|
||||
}
|
||||
Array<MeshletCullingInfo> cullingData(numMeshlets);
|
||||
std::memset(cullingData.data(), 0xff, cullingData.size());
|
||||
std::memset(cullingData.data(), 0xffff, cullingData.size() * sizeof(MeshletCullingInfo));
|
||||
cullingOffsetBuffer->rotateBuffer(cullingOffsets.size() * sizeof(uint32));
|
||||
cullingOffsetBuffer->updateContents(ShaderBufferCreateInfo{
|
||||
.sourceData = {
|
||||
@@ -144,18 +144,19 @@ void VertexData::createDescriptors()
|
||||
Gfx::SE_ACCESS_MEMORY_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||
|
||||
cullingBuffer->rotateBuffer(numMeshlets * sizeof(MeshletCullingInfo));
|
||||
cullingBuffer->rotateBuffer(cullingData.size() * sizeof(MeshletCullingInfo));
|
||||
cullingBuffer->updateContents(ShaderBufferCreateInfo{
|
||||
.sourceData = {
|
||||
.size = numMeshlets * sizeof(MeshletCullingInfo),
|
||||
.size = cullingData.size() * sizeof(MeshletCullingInfo),
|
||||
.data = (uint8 *)cullingData.data(),
|
||||
},
|
||||
.numElements = numMeshlets});
|
||||
.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->updateContents(ShaderBufferCreateInfo{
|
||||
.sourceData = {
|
||||
|
||||
@@ -47,6 +47,7 @@ void Queue::submitCommandBuffer(PCommand command, const Array<VkSemaphore>& sign
|
||||
};
|
||||
|
||||
VK_CHECK(vkQueueSubmit(queue, 1, &submitInfo, command->fence->getHandle()));
|
||||
command->fence->submit();
|
||||
command->state = Command::State::Submit;
|
||||
command->waitFlags.clear();
|
||||
command->waitSemaphores.clear();
|
||||
|
||||
@@ -20,38 +20,40 @@ Semaphore::Semaphore(PGraphics graphics)
|
||||
|
||||
Semaphore::~Semaphore()
|
||||
{
|
||||
//graphics->getDestructionManager()->queueSemaphore(graphics->getGraphicsCommands()->getCommands(), handle);
|
||||
// graphics->getDestructionManager()->queueSemaphore(graphics->getGraphicsCommands()->getCommands(), handle);
|
||||
}
|
||||
|
||||
|
||||
Fence::Fence(PGraphics graphics)
|
||||
: graphics(graphics)
|
||||
, signaled(false)
|
||||
: graphics(graphics), status(Status::Ready)
|
||||
{
|
||||
VkFenceCreateInfo info = {
|
||||
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0
|
||||
};
|
||||
.flags = 0};
|
||||
VK_CHECK(vkCreateFence(graphics->getDevice(), &info, nullptr, &fence));
|
||||
}
|
||||
|
||||
Fence::~Fence()
|
||||
{
|
||||
vkWaitForFences(graphics->getDevice(), 1, &fence, true, 100000);
|
||||
vkWaitForFences(graphics->getDevice(), 1, &fence, true, 10000000);
|
||||
vkDestroyFence(graphics->getDevice(), fence, nullptr);
|
||||
}
|
||||
|
||||
void Fence::submit()
|
||||
{
|
||||
status = Status::InUse;
|
||||
}
|
||||
|
||||
bool Fence::isSignaled()
|
||||
{
|
||||
if (signaled)
|
||||
if (status == Status::Signalled)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
VkResult r = vkGetFenceStatus(graphics->getDevice(), fence);
|
||||
if (r == VK_SUCCESS)
|
||||
{
|
||||
signaled = true;
|
||||
status = Status::Signalled;
|
||||
return true;
|
||||
}
|
||||
if (r == VK_NOT_READY)
|
||||
@@ -67,11 +69,14 @@ bool Fence::isSignaled()
|
||||
|
||||
void Fence::reset()
|
||||
{
|
||||
if (signaled)
|
||||
while (status == Status::InUse)
|
||||
{
|
||||
wait(1000000);
|
||||
}
|
||||
if (status == Status::Signalled)
|
||||
{
|
||||
VK_CHECK(vkResetFences(graphics->getDevice(), 1, &fence));
|
||||
//std::cout << vkGetFenceStatus(graphics->getDevice(), fence) << std::endl;
|
||||
signaled = false;
|
||||
status = Status::Ready;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +86,7 @@ void Fence::wait(uint64 timeout)
|
||||
VkResult r = vkWaitForFences(graphics->getDevice(), 1, fences, true, timeout);
|
||||
if (r == VK_SUCCESS)
|
||||
{
|
||||
signaled = true;
|
||||
status = Status::Signalled;
|
||||
}
|
||||
else if (r == VK_TIMEOUT)
|
||||
{
|
||||
@@ -111,7 +116,7 @@ void DestructionManager::notifyCommandComplete()
|
||||
{
|
||||
for (size_t i = 0; i < resources.size(); ++i)
|
||||
{
|
||||
if(!resources[i]->isCurrentlyBound())
|
||||
if (!resources[i]->isCurrentlyBound())
|
||||
{
|
||||
resources.removeAt(i, false);
|
||||
i--;
|
||||
@@ -131,9 +136,9 @@ SamplerHandle::~SamplerHandle()
|
||||
}
|
||||
|
||||
Sampler::Sampler(PGraphics graphics, VkSamplerCreateInfo createInfo)
|
||||
: graphics(graphics)
|
||||
, handle(new SamplerHandle(graphics, createInfo))
|
||||
{}
|
||||
: graphics(graphics), handle(new SamplerHandle(graphics, createInfo))
|
||||
{
|
||||
}
|
||||
|
||||
Sampler::~Sampler()
|
||||
{
|
||||
|
||||
@@ -32,6 +32,7 @@ class Fence
|
||||
public:
|
||||
Fence(PGraphics graphics);
|
||||
~Fence();
|
||||
void submit();
|
||||
bool isSignaled();
|
||||
void reset();
|
||||
constexpr VkFence getHandle() const
|
||||
@@ -46,7 +47,13 @@ public:
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
bool signaled;
|
||||
enum class Status
|
||||
{
|
||||
Ready,
|
||||
InUse,
|
||||
Signalled,
|
||||
};
|
||||
Status status;
|
||||
VkFence fence;
|
||||
};
|
||||
DEFINE_REF(Fence)
|
||||
|
||||
@@ -114,9 +114,9 @@ void Window::pollInput()
|
||||
|
||||
void Window::beginFrame()
|
||||
{
|
||||
imageAvailableFences[currentSemaphoreIndex]->wait(10000000000);
|
||||
imageAvailableFences[currentSemaphoreIndex]->reset();
|
||||
vkAcquireNextImageKHR(graphics->getDevice(), swapchain, std::numeric_limits<uint64>::max(), imageAvailableSemaphores[currentSemaphoreIndex]->getHandle(), imageAvailableFences[currentSemaphoreIndex]->getHandle(), ¤tImageIndex);
|
||||
imageAvailableFences[currentSemaphoreIndex]->submit();
|
||||
graphics->getGraphicsCommands()->getCommands()->waitForSemaphore(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, imageAvailableSemaphores[currentSemaphoreIndex]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user