Finally fixing it for real for real

This commit is contained in:
Dynamitos
2024-09-07 11:15:47 +02:00
parent e5c3918989
commit 9d2b890d72
15 changed files with 154 additions and 170 deletions
+15 -10
View File
@@ -8,6 +8,7 @@ using namespace Seele;
PlayView::PlayView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo& createInfo, std::string dllPath, bool useMeshCulling)
: GameView(graphics, window, createInfo, dllPath) {
getGlobals().useDepthCulling = useMeshCulling;
renderTimestamp = graphics->createTimestampQuery(2, "RenderTimestamp");
queryThread = std::thread([&]() {
PRenderGraphResources res = renderGraph.getResources();
Gfx::PPipelineStatisticsQuery cachedQuery = res->requestQuery("CACHED_QUERY");
@@ -23,21 +24,23 @@ PlayView::PlayView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate
<< "DepthIAV,DepthIAP,DepthVS,DepthClipInv,DepthClipPrim,DepthFS,DepthCS,DepthTS,DepthMS,"
<< "BaseIAV,BaseIAP,BaseVS,BaseClipInv,BaseClipPrim,BaseFS,BaseCS,BaseTS,BaseMS,"
<< "LightCullIAV,LightCullIAP,LightCullVS,LightCullClipInv,LightCullClipPrim,LightCullFS,LightCullCS,LightCullTS,LightCullMS,"
<< "VisibilityIAV,VisibilityIAP,VisibilityVS,VisibilityClipInv,VisibilityClipPrim,VisibilityFS,VisibilityCS,VisibilityMS,VisibilityMS," << std::endl;
<< "VisibilityIAV,VisibilityIAP,VisibilityVS,VisibilityClipInv,VisibilityClipPrim,VisibilityFS,VisibilityCS,VisibilityMS,"
"VisibilityMS,"
<< std::endl;
uint64 start = 0;
uint64 prevBegin = 0;
std::this_thread::sleep_for(std::chrono::milliseconds(500));
stats << std::fixed << std::setprecision(0);
while (getGlobals().running) {
auto cachedResults = cachedQuery->getResults();
auto depthResults = depthQuery->getResults();
auto baseResults = baseQuery->getResults();
auto lightCullResults = lightCullQuery->getResults();
auto visiblityResults = visibilityQuery->getResults();
int64 renderBegin = renderTimestamp->getResult().time;
int64 renderEnd = renderTimestamp->getResult().time;
Map<std::string, uint64> results;
for (uint32 i = 0; i < 11; ++i)
{
for (uint32 i = 0; i < 11; ++i) {
auto ts = timestamps->getResult();
results[ts.name] = ts.time;
}
@@ -53,12 +56,10 @@ PlayView::PlayView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate
int64 visibilityTime = results.at("VisibilityEnd") - results.at("VisibilityBegin");
int64 frameTime = cachedTime + mipTime + depthTime + baseTime + lightCullTime + visibilityTime;
stats << relTime << "," << cachedTime << "," << mipTime << "," << depthTime << ","
<< visibilityTime
<< "," << lightCullTime << "," << baseTime << ","
<< frameTime << "," << cachedResults << depthResults << baseResults << lightCullResults << visiblityResults << std::endl;
stats << relTime << "," << cachedTime << "," << mipTime << "," << depthTime << "," << visibilityTime << "," << lightCullTime
<< "," << baseTime << "," << frameTime << "," << cachedResults << depthResults << baseResults << lightCullResults
<< visiblityResults << std::endl;
stats.flush();
// std::cout << "Writing " << timestamps[0].time << std::endl;
}
});
}
@@ -73,6 +74,10 @@ void PlayView::commitUpdate() { GameView::commitUpdate(); }
void PlayView::prepareRender() { GameView::prepareRender(); }
void PlayView::render() { GameView::render(); }
void PlayView::render() {
renderTimestamp->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "RenderBegin");
GameView::render();
renderTimestamp->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "RenderEnd");
}
void PlayView::keyCallback(KeyCode code, InputAction action, KeyModifier modifier) { GameView::keyCallback(code, action, modifier); }
+1
View File
@@ -17,6 +17,7 @@ class PlayView : public GameView {
private:
std::thread queryThread;
Gfx::OTimestampQuery renderTimestamp;
};
DECLARE_REF(PlayView)
} // namespace Seele
+2
View File
@@ -45,4 +45,6 @@ void PlayView::keyCallback(KeyCode code, InputAction action, KeyModifier modifie
std::cout << cam.getCameraPosition() << std::endl;
std::cout << tra.getRotation() << std::endl;
}
if (code == KeyCode::KEY_R && action == InputAction::RELEASE) {
}
}
+8 -5
View File
@@ -57,8 +57,11 @@ int main() {
// AssetImporter::importFont(FontImportArgs{
// .filePath = "./fonts/Calibri.ttf",
// });
//AssetImporter::importMesh(MeshImportArgs{
// .filePath = sourcePath / "import/models/cube.fbx",
//});
AssetImporter::importMesh(MeshImportArgs{
.filePath = sourcePath / "import/models/cube.fbx",
.filePath = sourcePath / "import/models/culling.fbx",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = sourcePath / "import/textures/skyboxsun5deg_tn.jpg",
@@ -72,10 +75,10 @@ int main() {
.filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb",
.importPath = "Whitechapel",
});
AssetImporter::importMesh(MeshImportArgs{
.filePath = sourcePath / "import/models/city-suburbs/source/city-suburbs.obj",
.importPath = "suburbs",
});
//AssetImporter::importMesh(MeshImportArgs{
// .filePath = sourcePath / "import/models/city-suburbs/source/city-suburbs.obj",
// .importPath = "suburbs",
//});
getThreadPool().waitIdle();
vd->commitMeshes();
WindowCreateInfo mainWindowInfo = {
+1
View File
@@ -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), &params);
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), &param);
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)
+8 -16
View File
@@ -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) {}
+2 -14
View File
@@ -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;
+1 -1
View File
@@ -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;
+6 -1
View File
@@ -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);
}
}