Finally fixing it for real for real
This commit is contained in:
@@ -5,6 +5,7 @@ namespace Seele {
|
||||
namespace Component {
|
||||
struct Mesh {
|
||||
PMeshAsset asset;
|
||||
Array<uint32> meshletOffsets;
|
||||
bool isStatic = true;
|
||||
};
|
||||
} // namespace Component
|
||||
|
||||
@@ -6,10 +6,6 @@ using namespace Seele;
|
||||
|
||||
DepthCullingPass::DepthCullingPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {
|
||||
depthAttachmentLayout = graphics->createDescriptorLayout("pDepthAttachment");
|
||||
//depthAttachmentLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
// .binding = 0,
|
||||
// .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
//});
|
||||
depthAttachmentLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
@@ -20,16 +16,6 @@ DepthCullingPass::DepthCullingPass(Gfx::PGraphics graphics, PScene scene) : Rend
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.shaderStages = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_COMPUTE_BIT,
|
||||
});
|
||||
//depthAttachmentLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
// .binding = 3,
|
||||
// .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
// .shaderStages = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_COMPUTE_BIT,
|
||||
//});
|
||||
//depthAttachmentLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
// .binding = 4,
|
||||
// .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
// .shaderStages = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_COMPUTE_BIT,
|
||||
//});
|
||||
depthAttachmentLayout->create();
|
||||
|
||||
depthCullingLayout = graphics->createPipelineLayout("DepthPrepassLayout");
|
||||
@@ -94,33 +80,34 @@ void DepthCullingPass::render() {
|
||||
set->writeChanges();
|
||||
|
||||
timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "MipBegin");
|
||||
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("InitialReduce");
|
||||
computeCommand->bindPipeline(depthInitialReduce);
|
||||
// First we generate a pixel value per thread, while using a whole threadgroup
|
||||
// for a single one would be a waste
|
||||
Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("MipGen");
|
||||
computeCommand->bindPipeline(depthSourceCopy);
|
||||
computeCommand->bindDescriptor({viewParamsSet, set});
|
||||
UVector2 reduceDimensions = UVector2(viewport->getOwner()->getFramebufferWidth() + BLOCK_SIZE - 1,
|
||||
viewport->getOwner()->getFramebufferHeight() + BLOCK_SIZE - 1) /
|
||||
uint32(BLOCK_SIZE);
|
||||
computeCommand->dispatch(reduceDimensions.x, reduceDimensions.y, 1);
|
||||
computeCommand->dispatch((viewport->getWidth() + BLOCK_SIZE - 1) / BLOCK_SIZE, (viewport->getHeight() + BLOCK_SIZE - 1) / BLOCK_SIZE,
|
||||
1);
|
||||
graphics->executeCommands(std::move(computeCommand));
|
||||
|
||||
for (uint32 i = 0; i < mipOffsets.size() - 1; ++i) {
|
||||
for (uint32 i = 0; i < mipOffsets.size() - 1; ++i)
|
||||
{
|
||||
depthMipBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
Gfx::OComputeCommand mipCommand = graphics->createComputeCommand(fmt::format("MipGenLevel{0}", i));
|
||||
mipCommand->bindPipeline(depthMipGen);
|
||||
mipCommand->bindDescriptor({viewParamsSet, set});
|
||||
MipParam params = {
|
||||
.srcMipOffset = mipOffsets[i],
|
||||
.dstMipOffset = mipOffsets[i + 1],
|
||||
.srcMipDim = mipDims[i],
|
||||
.dstMipDim = mipDims[i + 1],
|
||||
MipParam param = {
|
||||
.sourceOffset = mipOffsets[i],
|
||||
.destOffset = mipOffsets[i + 1],
|
||||
.sourceDim = mipDims[i],
|
||||
.destDim = mipDims[i + 1],
|
||||
};
|
||||
mipCommand->pushConstants(Gfx::SE_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(MipParam), ¶ms);
|
||||
UVector2 threadGroups = (reduceDimensions + 1u) / 2u;
|
||||
mipCommand->dispatch(threadGroups.x, threadGroups.y, 1);
|
||||
graphics->executeCommands(std::move(mipCommand));
|
||||
Gfx::OComputeCommand reduceCommand = graphics->createComputeCommand("ReduceCommand");
|
||||
reduceCommand->bindPipeline(depthReduceLevel);
|
||||
reduceCommand->bindDescriptor({viewParamsSet, set});
|
||||
reduceCommand->pushConstants(Gfx::SE_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(MipParam), ¶m);
|
||||
auto dispatchDim = (mipDims[i + 1] + uint32(BLOCK_SIZE) - 1u) / uint32(BLOCK_SIZE);
|
||||
reduceCommand->dispatch(dispatchDim.x, dispatchDim.y, 1);
|
||||
graphics->executeCommands(std::move(reduceCommand));
|
||||
}
|
||||
|
||||
depthMipBuffer->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);
|
||||
|
||||
@@ -256,22 +243,21 @@ void DepthCullingPass::publishOutputs() {
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "DepthMipCompute",
|
||||
.modules = {"DepthMipGen"},
|
||||
.entryPoints = {{"initialReduce", "DepthMipGen"}, {"reduceLevel", "DepthMipGen"}},
|
||||
.entryPoints = {{"sourceCopy", "DepthMipGen"}, {"reduceLevel", "DepthMipGen"}},
|
||||
.rootSignature = depthComputeLayout,
|
||||
});
|
||||
depthInitialReduceShader = graphics->createComputeShader({0});
|
||||
depthSourceCopyShader = graphics->createComputeShader({0});
|
||||
depthComputeLayout->create();
|
||||
|
||||
Gfx::ComputePipelineCreateInfo pipelineCreateInfo = {
|
||||
.computeShader = depthInitialReduceShader,
|
||||
.computeShader = depthSourceCopyShader,
|
||||
.pipelineLayout = depthComputeLayout,
|
||||
};
|
||||
depthInitialReduce = graphics->createComputePipeline(pipelineCreateInfo);
|
||||
depthMipGenShader = graphics->createComputeShader({1});
|
||||
depthSourceCopy = graphics->createComputePipeline(pipelineCreateInfo);
|
||||
|
||||
pipelineCreateInfo.computeShader = depthMipGenShader;
|
||||
|
||||
depthMipGen = graphics->createComputePipeline(pipelineCreateInfo);
|
||||
depthReduceLevelShader = graphics->createComputeShader({1});
|
||||
pipelineCreateInfo.computeShader = depthReduceLevelShader;
|
||||
depthReduceLevel = graphics->createComputePipeline(pipelineCreateInfo);
|
||||
|
||||
query = graphics->createPipelineStatisticsQuery("DepthPipelineStatistics");
|
||||
resources->registerQueryOutput("DEPTH_QUERY", query);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Graphics/Pipeline.h"
|
||||
#include "Graphics/Query.h"
|
||||
#include "MinimalEngine.h"
|
||||
#include "RenderPass.h"
|
||||
|
||||
namespace Seele {
|
||||
class DepthCullingPass : public RenderPass {
|
||||
@@ -20,10 +20,10 @@ class DepthCullingPass : public RenderPass {
|
||||
private:
|
||||
constexpr static uint64 BLOCK_SIZE = 32;
|
||||
struct MipParam {
|
||||
uint32 srcMipOffset;
|
||||
uint32 dstMipOffset;
|
||||
UVector2 srcMipDim;
|
||||
UVector2 dstMipDim;
|
||||
uint32 sourceOffset;
|
||||
uint32 destOffset;
|
||||
UVector2 sourceDim;
|
||||
UVector2 destDim;
|
||||
};
|
||||
|
||||
Array<uint32> mipOffsets;
|
||||
@@ -38,11 +38,11 @@ class DepthCullingPass : public RenderPass {
|
||||
Gfx::PTimestampQuery timestamps;
|
||||
|
||||
Gfx::OPipelineLayout depthComputeLayout;
|
||||
Gfx::OComputeShader depthInitialReduceShader;
|
||||
Gfx::PComputePipeline depthInitialReduce;
|
||||
Gfx::OComputeShader depthMipGenShader;
|
||||
Gfx::PComputePipeline depthMipGen;
|
||||
|
||||
Gfx::OComputeShader depthSourceCopyShader;
|
||||
Gfx::PComputePipeline depthSourceCopy;
|
||||
Gfx::OComputeShader depthReduceLevelShader;
|
||||
Gfx::PComputePipeline depthReduceLevel;
|
||||
|
||||
Gfx::PShaderBuffer cullingBuffer;
|
||||
};
|
||||
DEFINE_REF(DepthCullingPass)
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
using namespace Seele;
|
||||
|
||||
constexpr static uint64 NUM_DEFAULT_ELEMENTS = 17962284;
|
||||
Map<VertexData::MeshMapping, VertexData::CullingMapping> VertexData::instanceIdMap;
|
||||
uint64 VertexData::instanceCount = 0;
|
||||
uint64 VertexData::meshletCount = 0;
|
||||
|
||||
void VertexData::resetMeshData() {
|
||||
@@ -37,7 +35,7 @@ void VertexData::resetMeshData() {
|
||||
}
|
||||
}
|
||||
|
||||
void VertexData::updateMesh(entt::entity id, uint32 meshIndex, PMesh mesh, Component::Transform& transform) {
|
||||
void VertexData::updateMesh(uint32 meshletOffset, PMesh mesh, Component::Transform& transform) {
|
||||
std::unique_lock l(materialDataLock);
|
||||
PMaterialInstance referencedInstance = mesh->referencedMaterial->getHandle();
|
||||
PMaterial mat = referencedInstance->getBaseMaterial();
|
||||
@@ -49,8 +47,6 @@ void VertexData::updateMesh(entt::entity id, uint32 meshIndex, PMesh mesh, Compo
|
||||
.inverseTransformMatrix = glm::inverse(transformMatrix),
|
||||
};
|
||||
|
||||
auto [instanceId, meshletOffset] = getCullingMapping(id, meshIndex, data.numMeshlets);
|
||||
|
||||
referencedInstance->updateDescriptor();
|
||||
if (mat->hasTransparency()) {
|
||||
auto params = referencedInstance->getMaterialOffsets();
|
||||
@@ -260,7 +256,7 @@ void VertexData::commitMeshes() {
|
||||
indices.clear();
|
||||
meshlets.clear();
|
||||
dirty = false;
|
||||
//graphics->buildBottomLevelAccelerationStructures(std::move(dataToBuild));
|
||||
// graphics->buildBottomLevelAccelerationStructures(std::move(dataToBuild));
|
||||
}
|
||||
|
||||
MeshId VertexData::allocateVertexData(uint64 numVertices) {
|
||||
@@ -282,8 +278,7 @@ void VertexData::serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buf
|
||||
std::unique_lock l(vertexDataLock);
|
||||
Array<Meshlet> out;
|
||||
MeshData data = meshData[id];
|
||||
for (size_t i = 0; i < data.numMeshlets; ++i)
|
||||
{
|
||||
for (size_t i = 0; i < data.numMeshlets; ++i) {
|
||||
MeshletDescription& desc = meshlets[i + data.meshletOffset];
|
||||
Meshlet m;
|
||||
std::memcpy(m.uniqueVertices, &vertexIndices[desc.vertexOffset], desc.vertexCount * sizeof(uint32));
|
||||
@@ -299,7 +294,7 @@ void VertexData::serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buf
|
||||
Serialization::save(buffer, ind);
|
||||
}
|
||||
|
||||
uint64 VertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) {
|
||||
uint64 VertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) {
|
||||
Array<Meshlet> in;
|
||||
Array<uint32> ind;
|
||||
Serialization::load(buffer, in);
|
||||
@@ -385,13 +380,10 @@ void VertexData::destroy() {
|
||||
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];
|
||||
uint32 VertexData::addCullingMapping(MeshId id) {
|
||||
uint32 result = meshletCount;
|
||||
meshletCount += getMeshData(id).numMeshlets;
|
||||
return result;
|
||||
}
|
||||
|
||||
VertexData::VertexData() : idCounter(0), head(0), verticesAllocated(0), dirty(false) {}
|
||||
|
||||
@@ -55,7 +55,7 @@ class VertexData {
|
||||
Gfx::PBottomLevelAS rayTracingScene;
|
||||
};
|
||||
void resetMeshData();
|
||||
void updateMesh(entt::entity id, uint32 meshIndex, PMesh mesh, Component::Transform& transform);
|
||||
void updateMesh(uint32 meshletOffset, PMesh mesh, Component::Transform& transform);
|
||||
void createDescriptors();
|
||||
void loadMesh(MeshId id, Array<uint32> indices, Array<Meshlet> meshlets);
|
||||
void commitMeshes();
|
||||
@@ -85,12 +85,7 @@ class VertexData {
|
||||
virtual void init(Gfx::PGraphics graphics);
|
||||
virtual void destroy();
|
||||
|
||||
struct CullingMapping {
|
||||
uint64 instanceId;
|
||||
uint32 cullingOffset;
|
||||
};
|
||||
static CullingMapping getCullingMapping(entt::entity id, uint32 meshIndex, uint32 numMeshlets);
|
||||
static uint64 getInstanceCount() { return instanceCount; }
|
||||
uint32 addCullingMapping(MeshId id);
|
||||
static uint64 getMeshletCount() { return meshletCount; }
|
||||
|
||||
protected:
|
||||
@@ -125,13 +120,6 @@ class VertexData {
|
||||
Array<uint32> vertexIndices;
|
||||
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;
|
||||
|
||||
@@ -42,7 +42,7 @@ void Seele::beginCompilation(const ShaderCompilationInfo& info, SlangCompileTarg
|
||||
option[1].value.intValue0 = 1;
|
||||
option[2].name = slang::CompilerOptionName::DebugInformation;
|
||||
option[2].value.kind = slang::CompilerOptionValueKind::Int;
|
||||
option[2].value.intValue0 = SLANG_DEBUG_INFO_LEVEL_NONE;
|
||||
option[2].value.intValue0 = SLANG_DEBUG_INFO_LEVEL_STANDARD;
|
||||
option[3].name = slang::CompilerOptionName::DebugInformationFormat;
|
||||
option[3].value.kind = slang::CompilerOptionValueKind::Int;
|
||||
option[3].value.intValue0 = SLANG_DEBUG_INFO_FORMAT_PDB;
|
||||
|
||||
@@ -10,7 +10,12 @@ MeshUpdater::MeshUpdater(PScene scene) : ComponentSystem<Component::Transform, C
|
||||
MeshUpdater::~MeshUpdater() {}
|
||||
|
||||
void MeshUpdater::update(entt::entity id, Component::Transform& transform, Component::Mesh& comp) {
|
||||
if (comp.meshletOffsets.empty()) {
|
||||
for (uint32 i = 0; i < comp.asset->meshes.size(); ++i) {
|
||||
comp.meshletOffsets.add(comp.asset->meshes[i]->vertexData->addCullingMapping(comp.asset->meshes[i]->id));
|
||||
}
|
||||
}
|
||||
for (uint32 i = 0; i < comp.asset->meshes.size(); ++i) {
|
||||
comp.asset->meshes[i]->vertexData->updateMesh(id, i, comp.asset->meshes[i], transform);
|
||||
comp.asset->meshes[i]->vertexData->updateMesh(comp.meshletOffsets[i], comp.asset->meshes[i], transform);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user