Adding view culling to non-depth culling variant

This commit is contained in:
Dynamitos
2024-06-25 11:21:56 +02:00
parent c352555b0b
commit 00bb6b3a96
10 changed files with 144 additions and 175 deletions
+5 -6
View File
@@ -404,19 +404,19 @@ void findMeshRoots(aiNode* node, List<aiNode*>& meshNodes) {
void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialInstanceAsset>& materials, Array<OMesh>& globalMeshes,
Component::Collider& collider) {
//List<std::function<void()>> work;
List<std::function<void()>> work;
for (int32 meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex) {
aiMesh* mesh = scene->mMeshes[meshIndex];
if (!(mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE))
continue;
globalMeshes.add(nullptr);
globalMeshes[meshIndex] = new Mesh();
StaticMeshVertexData* vertexData = StaticMeshVertexData::getInstance();
MeshId id = vertexData->allocateVertexData(mesh->mNumVertices);
uint64 offset = vertexData->getMeshOffset(id);
collider.boundingbox.adjust(Vector(mesh->mAABB.mMin.x, mesh->mAABB.mMin.y, mesh->mAABB.mMin.z));
collider.boundingbox.adjust(Vector(mesh->mAABB.mMax.x, mesh->mAABB.mMax.y, mesh->mAABB.mMax.z));
//work.add([&]() {
work.add([=, &globalMeshes]() {
// assume static mesh for now
Array<Vector4> positions(mesh->mNumVertices);
StaticArray<Array<Vector2>, MAX_TEXCOORDS> texCoords;
@@ -475,16 +475,15 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialIns
// collider.physicsMesh.addCollider(positions, indices, Matrix4(1.0f));
globalMeshes[meshIndex] = new Mesh();
globalMeshes[meshIndex]->vertexData = vertexData;
globalMeshes[meshIndex]->id = id;
globalMeshes[meshIndex]->referencedMaterial = materials[mesh->mMaterialIndex];
globalMeshes[meshIndex]->meshlets = std::move(meshlets);
globalMeshes[meshIndex]->indices = std::move(indices);
globalMeshes[meshIndex]->vertexCount = mesh->mNumVertices;
//});
});
}
//getThreadPool().runAndWait(std::move(work));
getThreadPool().runAndWait(std::move(work));
}
Matrix4 convertMatrix(aiMatrix4x4 matrix) {
@@ -143,10 +143,6 @@ void BasePass::render() {
{
.cullMode = Gfx::SeCullModeFlags(twoSided ? Gfx::SE_CULL_MODE_NONE : Gfx::SE_CULL_MODE_BACK_BIT),
},
.depthStencilState =
{
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL,
},
.colorBlend =
{
.attachmentCount = 1,
@@ -168,10 +164,6 @@ void BasePass::render() {
{
.cullMode = Gfx::SeCullModeFlags(twoSided ? Gfx::SE_CULL_MODE_NONE : Gfx::SE_CULL_MODE_BACK_BIT),
},
.depthStencilState =
{
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL,
},
.colorBlend =
{
.attachmentCount = 1,
@@ -81,10 +81,6 @@ void CachedDepthPass::render() {
{
.samples = viewport->getSamples(),
},
.depthStencilState =
{
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
},
.colorBlend =
{
.attachmentCount = 1,
@@ -102,10 +98,6 @@ void CachedDepthPass::render() {
{
.samples = viewport->getSamples(),
},
.depthStencilState =
{
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
},
.colorBlend =
{
.attachmentCount = 1,
@@ -118,101 +118,90 @@ void DepthCullingPass::render() {
query->beginQuery();
graphics->beginRenderPass(renderPass);
if (useDepthCulling) {
Array<Gfx::ORenderCommand> commands;
Array<Gfx::ORenderCommand> commands;
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("DepthPass");
permutation.setPositionOnly(usePositionOnly);
permutation.setDepthCulling(useDepthCulling);
for (VertexData* vertexData : VertexData::getList()) {
permutation.setVertexData(vertexData->getTypeName());
vertexData->getInstanceDataSet()->updateBuffer(6, cullingBuffer);
vertexData->getInstanceDataSet()->writeChanges();
// Create Pipeline(VertexData)
// Descriptors:
// ViewData => global, static
// VertexData => per meshtype
// SceneData => per meshtype
Gfx::PermutationId id(permutation);
Gfx::ShaderPermutation permutation = graphics->getShaderCompiler()->getTemplate("DepthPass");
permutation.setPositionOnly(usePositionOnly);
permutation.setDepthCulling(useDepthCulling);
for (VertexData* vertexData : VertexData::getList()) {
permutation.setVertexData(vertexData->getTypeName());
vertexData->getInstanceDataSet()->updateBuffer(6, cullingBuffer);
vertexData->getInstanceDataSet()->writeChanges();
// 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);
Gfx::ORenderCommand command = graphics->createRenderCommand("DepthRender");
command->setViewport(viewport);
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
assert(collection != nullptr);
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);
} 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({viewParamsSet, vertexData->getVertexDataSet(), vertexData->getInstanceDataSet(), set});
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++);
}
const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id);
assert(collection != nullptr);
if (graphics->supportMeshShading()) {
Gfx::MeshPipelineCreateInfo pipelineInfo = {
.taskShader = collection->taskShader,
.meshShader = collection->meshShader,
.fragmentShader = collection->fragmentShader,
.renderPass = renderPass,
.pipelineLayout = collection->pipelineLayout,
.multisampleState =
{
.samples = viewport->getSamples(),
},
.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(),
},
.colorBlend =
{
.attachmentCount = 1,
},
};
Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
command->bindPipeline(pipeline);
}
command->bindDescriptor({viewParamsSet, vertexData->getVertexDataSet(), vertexData->getInstanceDataSet(), set});
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));
}
graphics->executeCommands(std::move(commands));
commands.add(std::move(command));
}
graphics->executeCommands(std::move(commands));
graphics->endRenderPass();
query->endQuery();
// Sync depth read/write with compute read
@@ -9,16 +9,6 @@
namespace Seele {
class StaticMeshVertexData : public VertexData {
public:
struct StaticMatInstance {
PMaterialInstance instance;
Array<uint32> meshletIds;
Gfx::OShaderBuffer culledMeshletBuffer;
// Gfx::OShaderBuffer indirectDrawBuffer;
};
struct StaticMatData {
PMaterial material;
Array<StaticMatInstance> staticInstance;
};
StaticMeshVertexData();
virtual ~StaticMeshVertexData();
static StaticMeshVertexData* getInstance();
@@ -37,12 +27,10 @@ class StaticMeshVertexData : public VertexData {
virtual Gfx::PDescriptorSet getVertexDataSet() override;
virtual std::string getTypeName() const override { return "StaticMeshVertexData"; }
virtual Gfx::PShaderBuffer getPositionBuffer() const override { return positions; }
constexpr const Array<StaticMatData>& getStaticMeshes() const { return staticData; }
private:
virtual void resizeBuffers() override;
virtual void updateBuffers() override;
Array<StaticMatData> staticData;
Gfx::OShaderBuffer positions;
Array<Vector4> positionData;
+32 -24
View File
@@ -184,10 +184,14 @@ Buffer::~Buffer() {
}
void Buffer::updateContents(uint64 regionOffset, uint64 regionSize, void* buffer) {
if (buffers.size() == 0)
return;
getAlloc()->updateContents(regionOffset, regionSize, buffer);
}
void Buffer::readContents(uint64 regionOffset, uint64 regionSize, void* buffer) {
if (buffers.size() == 0)
return;
getAlloc()->readContents(regionOffset, regionSize, buffer);
}
@@ -218,29 +222,27 @@ void Buffer::rotateBuffer(uint64 size, bool preserveContents) {
}
void Buffer::createBuffer(uint64 size, uint32 destIndex) {
if (size > 0) {
uint32 family = graphics->getFamilyMapping().getQueueTypeFamilyIndex(initialOwner);
VkBufferCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = size,
.usage = usage,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 1,
.pQueueFamilyIndices = &family,
};
VmaAllocationCreateInfo allocInfo = {
.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
};
buffers[destIndex] = new BufferAllocation(graphics, name, info, allocInfo, initialOwner);
if (createCleared)
{
PCommand command = graphics->getQueueCommands(initialOwner)->getCommands();
vkCmdFillBuffer(command->getHandle(), buffers[destIndex]->buffer, 0, VK_WHOLE_SIZE, clearValue);
pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
}
uint32 family = graphics->getFamilyMapping().getQueueTypeFamilyIndex(initialOwner);
VkBufferCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = size,
.usage = usage,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 1,
.pQueueFamilyIndices = &family,
};
VmaAllocationCreateInfo allocInfo = {
.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
};
buffers[destIndex] = new BufferAllocation(graphics, name, info, allocInfo, initialOwner);
if (createCleared)
{
PCommand command = graphics->getQueueCommands(initialOwner)->getCommands();
vkCmdFillBuffer(command->getHandle(), buffers[destIndex]->buffer, 0, VK_WHOLE_SIZE, clearValue);
pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
}
}
@@ -283,10 +285,16 @@ void Buffer::copyBuffer(uint64 src, uint64 dst) {
&dstBarrier, 0, nullptr);
}
void Buffer::transferOwnership(Gfx::QueueType newOwner) { getAlloc()->transferOwnership(newOwner); }
void Buffer::transferOwnership(Gfx::QueueType newOwner) {
if (buffers.size() == 0)
return;
getAlloc()->transferOwnership(newOwner);
}
void Buffer::pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
if (buffers.size() == 0)
return;
getAlloc()->pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}