Lots of shader changes, basic primitive writing

This commit is contained in:
Dynamitos
2024-05-30 21:24:21 +02:00
parent f278afad66
commit 953c90f2de
18 changed files with 599 additions and 464 deletions
+180 -173
View File
@@ -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);
}
+186 -163
View File
@@ -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)
+5 -4
View File
@@ -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 = {
+1
View File
@@ -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();
+22 -17
View File
@@ -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()
{
+8 -1
View File
@@ -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)
+1 -1
View File
@@ -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(), &currentImageIndex);
imageAvailableFences[currentSemaphoreIndex]->submit();
graphics->getGraphicsCommands()->getCommands()->waitForSemaphore(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, imageAvailableSemaphores[currentSemaphoreIndex]);
}