diff --git a/res/shaders/lib/Scene.slang b/res/shaders/lib/Scene.slang index b18676d..9179579 100644 --- a/res/shaders/lib/Scene.slang +++ b/res/shaders/lib/Scene.slang @@ -20,9 +20,8 @@ struct MeshData uint32_t numIndices; }; -static const uint32_t MAX_VERTICES = 64; -static const uint32_t MAX_PRIMITIVES = 128; -static const uint32_t MAX_MESHLETS_PER_INSTANCE = 2048; +static const uint32_t MAX_VERTICES = 256; +static const uint32_t MAX_PRIMITIVES = 256; struct InstanceData { @@ -77,7 +76,7 @@ uint decodePrimitive(uint32_t encoded) struct MeshPayload { - uint culledMeshlets[MAX_MESHLETS_PER_INSTANCE]; + uint culledMeshlets[2048]; uint instanceId; uint meshletOffset; uint cullingOffset; diff --git a/src/Engine/Graphics/Enums.h b/src/Engine/Graphics/Enums.h index c16df4f..9c59c18 100644 --- a/src/Engine/Graphics/Enums.h +++ b/src/Engine/Graphics/Enums.h @@ -159,8 +159,8 @@ static constexpr bool useAsyncCompute = false; static constexpr bool useMeshShading = true; static constexpr uint32 numFramesBuffered = 3; -static constexpr uint32 numVerticesPerMeshlet = 64; -static constexpr uint32 numPrimitivesPerMeshlet = 126; +static constexpr uint32 numVerticesPerMeshlet = 256; +static constexpr uint32 numPrimitivesPerMeshlet = 256; double getCurrentFrameDelta(); double getCurrentFrameTime(); uint32 getCurrentFrameIndex(); diff --git a/src/Engine/Graphics/Mesh.cpp b/src/Engine/Graphics/Mesh.cpp index 7c0249e..f1d61e2 100644 --- a/src/Engine/Graphics/Mesh.cpp +++ b/src/Engine/Graphics/Mesh.cpp @@ -14,7 +14,7 @@ void Mesh::save(ArchiveBuffer& buffer) const { Serialization::save(buffer, vertexCount); Serialization::save(buffer, referencedMaterial->getFolderPath()); Serialization::save(buffer, referencedMaterial->getName()); - vertexData->serializeMesh(id, vertexCount, buffer); + vertexData->serializeMesh(id, buffer); } void Mesh::load(ArchiveBuffer& buffer) { diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 117205d..20c9905 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -135,10 +135,10 @@ void BasePass::beginFrame(const Component::Camera& cam) { } void BasePass::render() { - /*opaqueCulling->updateBuffer(0, 0, oLightIndexList); - opaqueCulling->updateTexture(1, 0, oLightGrid); - transparentCulling->updateBuffer(0, 0, tLightIndexList); - transparentCulling->updateTexture(1, 0, tLightGrid); + opaqueCulling->updateBuffer(LIGHTINDEX_NAME, 0, oLightIndexList); + opaqueCulling->updateTexture(LIGHTGRID_NAME, 0, oLightGrid); + transparentCulling->updateBuffer(LIGHTINDEX_NAME, 0, tLightIndexList); + transparentCulling->updateTexture(LIGHTGRID_NAME, 0, tLightGrid); opaqueCulling->writeChanges(); transparentCulling->writeChanges(); @@ -153,7 +153,7 @@ void BasePass::render() { // Base Rendering for (VertexData* vertexData : VertexData::getList()) { transparentData.addAll(vertexData->getTransparentData()); - vertexData->getInstanceDataSet()->updateBuffer(6, 0, cullingBuffer); + vertexData->getInstanceDataSet()->updateBuffer(VertexData::CULLINGDATA_NAME, 0, cullingBuffer); vertexData->getInstanceDataSet()->writeChanges(); permutation.setVertexData(vertexData->getTypeName()); const auto& materials = vertexData->getMaterialData(); @@ -231,7 +231,7 @@ void BasePass::render() { Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(VertexData::DrawCallOffsets), &drawCall.offsets); if (graphics->supportMeshShading()) { - command->drawMesh(drawCall.instanceMeshData.size(), 1, 1); + //command->drawMesh(drawCall.instanceMeshData.size(), 1, 1); } else { command->bindIndexBuffer(vertexData->getIndexBuffer()); for (const auto& meshData : drawCall.instanceMeshData) { @@ -247,9 +247,8 @@ void BasePass::render() { //commands.add(waterRenderer->render(viewParamsSet)); //commands.add(terrainRenderer->render(viewParamsSet)); - */ + // Skybox - graphics->beginRenderPass(renderPass); { Gfx::ORenderCommand skyboxCommand = graphics->createRenderCommand("SkyboxRender"); skyboxCommand->setViewport(viewport); @@ -258,8 +257,6 @@ void BasePass::render() { skyboxCommand->draw(36, 1, 0, 0); graphics->executeCommands(std::move(skyboxCommand)); } - graphics->endRenderPass(); - /* // Transparent rendering { permutation.setDepthCulling(false); // ignore visibility infos for transparency @@ -348,7 +345,7 @@ void BasePass::render() { Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(VertexData::DrawCallOffsets), &t.offsets); if (graphics->supportMeshShading()) { - transparentCommand->drawMesh(1, 1, 1); + //transparentCommand->drawMesh(1, 1, 1); } else { // command->bindIndexBuffer(t.vertexData->getIndexBuffer()); // for (const auto& meshData : drawCall.instanceMeshData) { @@ -376,37 +373,40 @@ void BasePass::render() { query->endQuery(); timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "BaseEnd"); gDebugVertices.clear(); - */ } void BasePass::endFrame() {} void BasePass::publishOutputs() { - TextureCreateInfo depthBufferInfo = { + basePassDepth = graphics->createTexture2D(TextureCreateInfo{ .format = Gfx::SE_FORMAT_D32_SFLOAT, .width = viewport->getOwner()->getFramebufferWidth(), .height = viewport->getOwner()->getFramebufferHeight(), .usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - }; - basePassDepth = graphics->createTexture2D(depthBufferInfo); + }); - TextureCreateInfo msDepthInfo = { + basePassColor = graphics->createTexture2D(TextureCreateInfo{ + .format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT, + .width = viewport->getOwner()->getFramebufferWidth(), + .height = viewport->getOwner()->getFramebufferHeight(), + .usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + }); + + msBasePassDepth = graphics->createTexture2D(TextureCreateInfo{ .format = Gfx::SE_FORMAT_D32_SFLOAT, .width = viewport->getOwner()->getFramebufferWidth(), .height = viewport->getOwner()->getFramebufferHeight(), .samples = viewport->getSamples(), .usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, - }; - msBasePassDepth = graphics->createTexture2D(msDepthInfo); - - TextureCreateInfo msBaseColorInfo = { - .format = viewport->getOwner()->getSwapchainFormat(), + }); + + msBasePassColor = graphics->createTexture2D(TextureCreateInfo{ + .format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT, .width = viewport->getOwner()->getFramebufferWidth(), .height = viewport->getOwner()->getFramebufferHeight(), .samples = viewport->getSamples(), .usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, - }; - msBasePassColor = graphics->createTexture2D(msBaseColorInfo); + }); depthAttachment = Gfx::RenderTargetAttachment(basePassDepth, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, @@ -418,7 +418,7 @@ void BasePass::publishOutputs() { msDepthAttachment.clear.depthStencil.depth = 0.0f; colorAttachment = Gfx::RenderTargetAttachment(viewport, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE); + Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE); msColorAttachment = Gfx::RenderTargetAttachment(msBasePassColor, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, diff --git a/src/Engine/Graphics/RenderPass/BasePass.h b/src/Engine/Graphics/RenderPass/BasePass.h index be76023..81507cc 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.h +++ b/src/Engine/Graphics/RenderPass/BasePass.h @@ -19,6 +19,7 @@ class BasePass : public RenderPass { virtual void createRenderPass() override; private: + // hdr Gfx::RenderTargetAttachment msColorAttachment; Gfx::RenderTargetAttachment colorAttachment; Gfx::RenderTargetAttachment msDepthAttachment; @@ -37,7 +38,9 @@ class BasePass : public RenderPass { // use a different texture here so we can do multisampling Gfx::OTexture2D msBasePassDepth; Gfx::OTexture2D basePassDepth; + // hdr Gfx::OTexture2D msBasePassColor; + Gfx::OTexture2D basePassColor; // used for transparency sorting Vector cameraPos; diff --git a/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp b/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp index 8a2212e..8b0b44a 100644 --- a/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp +++ b/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp @@ -43,7 +43,7 @@ CachedDepthPass::~CachedDepthPass() {} void CachedDepthPass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); } void CachedDepthPass::render() { -/* query->beginQuery(); + query->beginQuery(); timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "CachedBegin"); graphics->beginRenderPass(renderPass); Array commands; @@ -53,7 +53,7 @@ void CachedDepthPass::render() { permutation.setDepthCulling(true); for (VertexData* vertexData : VertexData::getList()) { permutation.setVertexData(vertexData->getTypeName()); - vertexData->getInstanceDataSet()->updateBuffer(6, 0, cullingBuffer); + vertexData->getInstanceDataSet()->updateBuffer(VertexData::CULLINGDATA_NAME, 0, cullingBuffer); vertexData->getInstanceDataSet()->writeChanges(); // Create Pipeline(VertexData) @@ -134,9 +134,8 @@ void CachedDepthPass::render() { graphics->executeCommands(std::move(commands)); graphics->endRenderPass(); - graphics->waitDeviceIdle(); timestamps->write(Gfx::SE_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, "CachedEnd"); - query->endQuery();*/ + query->endQuery(); } void CachedDepthPass::endFrame() {} diff --git a/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp b/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp index f16f33b..0e6190d 100644 --- a/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp @@ -68,7 +68,7 @@ DepthCullingPass::~DepthCullingPass() {} void DepthCullingPass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); } void DepthCullingPass::render() { - /*query->beginQuery(); + query->beginQuery(); depthAttachment.getTexture()->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL, 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); @@ -125,7 +125,7 @@ void DepthCullingPass::render() { permutation.setDepthCulling(getGlobals().useDepthCulling); for (VertexData* vertexData : VertexData::getList()) { permutation.setVertexData(vertexData->getTypeName()); - vertexData->getInstanceDataSet()->updateBuffer(6, 0, cullingBuffer); + vertexData->getInstanceDataSet()->updateBuffer(VertexData::CULLINGDATA_NAME, 0, cullingBuffer); vertexData->getInstanceDataSet()->writeChanges(); // Create Pipeline(VertexData) // Descriptors: @@ -217,7 +217,7 @@ void DepthCullingPass::render() { // 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);*/ + Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); } void DepthCullingPass::endFrame() {} diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp index 7aeb007..099031d 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -37,19 +37,19 @@ void LightCullingPass::beginFrame(const Component::Camera& cam) { } void LightCullingPass::render() { - /*query->beginQuery(); + query->beginQuery(); timestamps->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "LightCullBegin"); oLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); tLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); - cullingDescriptorSet->updateTexture(0, 0, depthAttachment); - cullingDescriptorSet->updateBuffer(1, 0, oLightIndexCounter); - cullingDescriptorSet->updateBuffer(2, 0, tLightIndexCounter); - cullingDescriptorSet->updateBuffer(3, 0, oLightIndexList); - cullingDescriptorSet->updateBuffer(4, 0, tLightIndexList); - cullingDescriptorSet->updateTexture(5, 0, oLightGrid); - cullingDescriptorSet->updateTexture(6, 0, tLightGrid); + cullingDescriptorSet->updateTexture(DEPTHATTACHMENT_NAME, 0, depthAttachment); + cullingDescriptorSet->updateBuffer(OLIGHTINDEXCOUNTER_NAME, 0, oLightIndexCounter); + cullingDescriptorSet->updateBuffer(TLIGHTINDEXCOUNTER_NAME, 0, tLightIndexCounter); + cullingDescriptorSet->updateBuffer(OLIGHTINDEXLIST_NAME, 0, oLightIndexList); + cullingDescriptorSet->updateBuffer(TLIGHTINDEXLIST_NAME, 0, tLightIndexList); + cullingDescriptorSet->updateTexture(OLIGHTGRID_NAME, 0, oLightGrid); + cullingDescriptorSet->updateTexture(TLIGHTGRID_NAME, 0, tLightGrid); cullingDescriptorSet->writeChanges(); Gfx::OComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand"); if (getGlobals().useLightCulling) { @@ -58,7 +58,7 @@ void LightCullingPass::render() { computeCommand->bindPipeline(cullingPipeline); } computeCommand->bindDescriptor({viewParamsSet, dispatchParamsSet, cullingDescriptorSet, lightEnv->getDescriptorSet()}); - computeCommand->dispatch(dispatchParams.numThreadGroups.x, dispatchParams.numThreadGroups.y, dispatchParams.numThreadGroups.z); + computeCommand->dispatch(numThreadGroups.x, numThreadGroups.y, numThreadGroups.z); Array commands; commands.add(std::move(computeCommand)); // std::cout << "Execute" << std::endl; @@ -72,7 +72,7 @@ void LightCullingPass::render() { oLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); tLightGrid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, - Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);*/ + Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); } void LightCullingPass::endFrame() {} @@ -81,8 +81,8 @@ void LightCullingPass::publishOutputs() { setupFrustums(); uint32_t viewportWidth = viewport->getWidth(); uint32_t viewportHeight = viewport->getHeight(); - UVector4 numThreadGroups = glm::ceil(glm::vec4(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1, 0)); - UVector4 numThreads = numThreadGroups * glm::uvec4(BLOCK_SIZE, BLOCK_SIZE, 1, 0); + numThreadGroups = glm::ceil(glm::vec4(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1, 0)); + numThreads = numThreadGroups * glm::uvec4(BLOCK_SIZE, BLOCK_SIZE, 1, 0); dispatchParamsSet = dispatchParamsLayout->allocateDescriptorSet(); dispatchParamsSet->updateConstants("numThreadGroups", 0, &numThreadGroups); dispatchParamsSet->updateConstants("numThreads", 0, &numThreads); @@ -225,8 +225,8 @@ void LightCullingPass::setupFrustums() { uint32_t viewportWidth = viewport->getWidth(); uint32_t viewportHeight = viewport->getHeight(); - glm::uvec4 numThreads = glm::ceil(glm::vec4(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1, 0)); - glm::uvec4 numThreadGroups = glm::ceil(glm::vec4(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1, 0)); + numThreads = glm::ceil(glm::vec4(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1, 0)); + numThreadGroups = glm::ceil(glm::vec4(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1, 0)); RenderPass::beginFrame(Component::Camera()); diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.h b/src/Engine/Graphics/RenderPass/LightCullingPass.h index e6a3f4d..2bbc662 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.h +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.h @@ -59,7 +59,9 @@ class LightCullingPass : public RenderPass { Gfx::PComputePipeline cullingEnabledPipeline; Gfx::OPipelineStatisticsQuery query; Gfx::PTimestampQuery timestamps; - + UVector4 numThreadGroups; + UVector4 numThreads; + PScene scene; }; DEFINE_REF(LightCullingPass) diff --git a/src/Engine/Graphics/RenderPass/VisibilityPass.cpp b/src/Engine/Graphics/RenderPass/VisibilityPass.cpp index 69b2857..f26ef87 100644 --- a/src/Engine/Graphics/RenderPass/VisibilityPass.cpp +++ b/src/Engine/Graphics/RenderPass/VisibilityPass.cpp @@ -13,11 +13,12 @@ void VisibilityPass::beginFrame(const Component::Camera& cam) { } void VisibilityPass::render() { - /*cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT, + cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT, Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT); cullingBuffer->clear(); - cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, + cullingBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, + Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); visibilityDescriptor->reset(); visibilitySet = visibilityDescriptor->allocateDescriptorSet(); @@ -38,7 +39,7 @@ void VisibilityPass::render() { query->endQuery(); cullingBuffer->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 | Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT);*/ + Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT | Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT); } void VisibilityPass::endFrame() {} diff --git a/src/Engine/Graphics/StaticMeshVertexData.cpp b/src/Engine/Graphics/StaticMeshVertexData.cpp index 3f37be1..3457866 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.cpp +++ b/src/Engine/Graphics/StaticMeshVertexData.cpp @@ -53,12 +53,14 @@ void StaticMeshVertexData::loadColors(uint64 offset, const Array& dat dirty = true; } -void StaticMeshVertexData::serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) { - VertexData::serializeMesh(id, numVertices, buffer); +void StaticMeshVertexData::serializeMesh(MeshId id, ArchiveBuffer& buffer) { + VertexData::serializeMesh(id, buffer); uint64 offset; + uint64 numVertices; { std::unique_lock l(vertexDataLock); offset = meshOffsets[id]; + numVertices = meshVertexCounts[id]; } Array tex[MAX_TEXCOORDS]; for (size_t i = 0; i < MAX_TEXCOORDS; ++i) { diff --git a/src/Engine/Graphics/StaticMeshVertexData.h b/src/Engine/Graphics/StaticMeshVertexData.h index 1e50915..ed59ac2 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.h +++ b/src/Engine/Graphics/StaticMeshVertexData.h @@ -25,7 +25,7 @@ class StaticMeshVertexData : public VertexData { void loadTangents(uint64 offset, const Array& data); void loadBitangents(uint64 offset, const Array& data); void loadColors(uint64 offset, const Array& data); - virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) override; + virtual void serializeMesh(MeshId id, ArchiveBuffer& buffer) override; virtual uint64 deserializeMesh(MeshId id, ArchiveBuffer& buffer) override; virtual void init(Gfx::PGraphics graphics) override; virtual void destroy() override; diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index dbc854d..fda6d04 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -39,8 +39,6 @@ void VertexData::updateMesh(uint32 meshletOffset, PMesh mesh, Component::Transfo std::unique_lock l(materialDataLock); PMaterialInstance referencedInstance = mesh->referencedMaterial->getHandle(); PMaterial mat = referencedInstance->getBaseMaterial(); - const auto& data = meshData[mesh->id]; - Matrix4 transformMatrix = transform.toMatrix() * mesh->transform; InstanceData inst = InstanceData{ .transformMatrix = transformMatrix, @@ -48,26 +46,6 @@ void VertexData::updateMesh(uint32 meshletOffset, PMesh mesh, Component::Transfo }; referencedInstance->updateDescriptor(); - if (mat->hasTransparency()) { - auto params = referencedInstance->getMaterialOffsets(); - transparentData.add(TransparentDraw{ - .matInst = referencedInstance, - .vertexData = this, - .offsets = - { - .instanceOffset = 0, - .textureOffset = params.textureOffset, - .samplerOffset = params.samplerOffset, - .floatOffset = params.floatOffset, - }, - .worldPosition = Vector(inst.transformMatrix[3]), - .instanceData = inst, - .meshData = data, - .cullingOffset = meshletOffset, - .rayTracingScene = mesh->blas, - }); - return; - } if (materialData.size() <= mat->getId()) { materialData.resize(mat->getId() + 1); } @@ -77,50 +55,33 @@ void VertexData::updateMesh(uint32 meshletOffset, PMesh mesh, Component::Transfo matData.instances.resize(referencedInstance->getId() + 1); } BatchedDrawCall& matInstanceData = matData.instances[referencedInstance->getId()]; - matInstanceData.materialInstance = referencedInstance; - matInstanceData.rayTracingData.add(mesh->blas); - matInstanceData.instanceData.add(inst); - matInstanceData.instanceMeshData.add(data); - matInstanceData.cullingOffsets.add(meshletOffset); - - /* for (size_t i = 0; i < 0; ++i) { - auto bounding = meshlets[data.meshletOffset + i].bounding; - StaticArray corners; - Vector min = bounding.min; // bounding.center - bounding.radius * Vector(1, 1, 1); - Vector max = bounding.max; // bounding.center + bounding.radius * Vector(1, 1, 1); - corners[0] = transformMatrix * Vector4(min.x, min.y, min.z, 1); - corners[1] = transformMatrix * Vector4(min.x, min.y, max.z, 1); - corners[2] = transformMatrix * Vector4(min.x, max.y, min.z, 1); - corners[3] = transformMatrix * Vector4(min.x, max.y, max.z, 1); - corners[4] = transformMatrix * Vector4(max.x, min.y, min.z, 1); - corners[5] = transformMatrix * Vector4(max.x, min.y, max.z, 1); - corners[6] = transformMatrix * Vector4(max.x, max.y, min.z, 1); - corners[7] = transformMatrix * Vector4(max.x, max.y, max.z, 1); - addDebugVertex(DebugVertex{.position = corners[0], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[1], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[0], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[2], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[1], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[3], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[2], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[3], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[0], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[4], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[1], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[5], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[2], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[6], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[3], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[7], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[4], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[5], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[4], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[6], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[6], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[7], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[5], .color = meshlets[data.meshletOffset + i].color}); - addDebugVertex(DebugVertex{.position = corners[7], .color = meshlets[data.meshletOffset + i].color}); - }*/ + for (const auto& data : meshData[mesh->id]) { + if (mat->hasTransparency()) { + auto params = referencedInstance->getMaterialOffsets(); + transparentData.add(TransparentDraw{ + .matInst = referencedInstance, + .vertexData = this, + .offsets = + { + .instanceOffset = 0, + .textureOffset = params.textureOffset, + .samplerOffset = params.samplerOffset, + .floatOffset = params.floatOffset, + }, + .worldPosition = Vector(inst.transformMatrix[3]), + .instanceData = inst, + .meshData = data, + .cullingOffset = meshletOffset, + .rayTracingScene = mesh->blas, + }); + } else { // opaque + matInstanceData.materialInstance = referencedInstance; + matInstanceData.rayTracingData.add(mesh->blas); + matInstanceData.instanceData.add(inst); + matInstanceData.instanceMeshData.add(data); + matInstanceData.cullingOffsets.add(meshletOffset); + } + } } void VertexData::createDescriptors() { @@ -177,37 +138,42 @@ void VertexData::createDescriptors() { void VertexData::loadMesh(MeshId id, Array loadedIndices, Array loadedMeshlets) { std::unique_lock l(vertexDataLock); - uint32 meshletOffset = meshlets.size(); - AABB meshAABB; - for (uint32 i = 0; i < loadedMeshlets.size(); ++i) { - Meshlet& m = loadedMeshlets[i]; - meshAABB = meshAABB.combine(m.boundingBox); - uint32 vertexOffset = vertexIndices.size(); - vertexIndices.resize(vertexOffset + m.numVertices); - std::memcpy(vertexIndices.data() + vertexOffset, m.uniqueVertices, m.numVertices * sizeof(uint32)); - uint32 primitiveOffset = primitiveIndices.size(); - primitiveIndices.resize(primitiveOffset + (m.numPrimitives * 3)); - std::memcpy(primitiveIndices.data() + primitiveOffset, m.primitiveLayout, m.numPrimitives * 3 * sizeof(uint8)); - meshlets.add(MeshletDescription{ - .bounding = m.boundingBox, //.toSphere(), - .vertexCount = m.numVertices, - .primitiveCount = m.numPrimitives, - .vertexOffset = vertexOffset, - .primitiveOffset = primitiveOffset, - .color = Vector((float)rand() / RAND_MAX, (float)rand() / RAND_MAX, (float)rand() / RAND_MAX), - .indicesOffset = (uint32)meshOffsets[id], + uint32 numMeshData = (loadedMeshlets.size() + 2047) / 2048; // todo: magic number + for (uint32 n = 0; n < numMeshData; ++n) { + uint32 meshletsToProcess = std::min(loadedMeshlets.size() - n * 2048, 2048); + uint32 meshletOffset = meshlets.size(); + AABB meshAABB; + for (uint32 i = 0; i < meshletsToProcess; ++i) { + Meshlet& m = loadedMeshlets[n * 2048 + i]; + //... + meshAABB = meshAABB.combine(m.boundingBox); + uint32 vertexOffset = vertexIndices.size(); + vertexIndices.resize(vertexOffset + m.numVertices); + std::memcpy(vertexIndices.data() + vertexOffset, m.uniqueVertices, m.numVertices * sizeof(uint32)); + uint32 primitiveOffset = primitiveIndices.size(); + primitiveIndices.resize(primitiveOffset + (m.numPrimitives * 3)); + std::memcpy(primitiveIndices.data() + primitiveOffset, m.primitiveLayout, m.numPrimitives * 3 * sizeof(uint8)); + meshlets.add(MeshletDescription{ + .bounding = m.boundingBox, //.toSphere(), + .vertexCount = m.numVertices, + .primitiveCount = m.numPrimitives, + .vertexOffset = vertexOffset, + .primitiveOffset = primitiveOffset, + .color = Vector((float)rand() / RAND_MAX, (float)rand() / RAND_MAX, (float)rand() / RAND_MAX), + .indicesOffset = (uint32)meshOffsets[id], + }); + } + meshData[id].add(MeshData{ + .bounding = meshAABB, //.toSphere(), + .numMeshlets = (uint32)meshletsToProcess, + .meshletOffset = meshletOffset, }); } - meshData[id] = MeshData{ - .bounding = meshAABB, //.toSphere(), - .numMeshlets = (uint32)loadedMeshlets.size(), - .meshletOffset = meshletOffset, - .firstIndex = (uint32)indices.size(), - .numIndices = (uint32)loadedIndices.size(), - }; - + // todo: in case of a index split for 16 bit, do something here + meshData[id][0].firstIndex = (uint32)indices.size(); + meshData[id][0].numIndices = (uint32)loadedIndices.size(); indices.resize(indices.size() + loadedIndices.size()); - std::memcpy(indices.data() + meshData[id].firstIndex, loadedIndices.data(), loadedIndices.size() * sizeof(uint32)); + std::memcpy(indices.data() + meshData[id][0].firstIndex, loadedIndices.data(), loadedIndices.size() * sizeof(uint32)); } void VertexData::commitMeshes() { @@ -268,22 +234,24 @@ MeshId VertexData::allocateVertexData(uint64 numVertices) { return res; } -void VertexData::serializeMesh(MeshId id, uint64, ArchiveBuffer& buffer) { +void VertexData::serializeMesh(MeshId id, ArchiveBuffer& buffer) { std::unique_lock l(vertexDataLock); Array out; - MeshData data = meshData[id]; - 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)); - std::memcpy(m.primitiveLayout, &primitiveIndices[desc.primitiveOffset], desc.primitiveCount * 3 * sizeof(uint8)); - m.numPrimitives = desc.primitiveCount; - m.numVertices = desc.vertexCount; - m.boundingBox = desc.bounding; - out.add(std::move(m)); + for (uint32 n = 0; n < meshData[id].size(); ++n) { + MeshData data = meshData[id][n]; + 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)); + std::memcpy(m.primitiveLayout, &primitiveIndices[desc.primitiveOffset], desc.primitiveCount * 3 * sizeof(uint8)); + m.numPrimitives = desc.primitiveCount; + m.numVertices = desc.vertexCount; + m.boundingBox = desc.bounding; + out.add(std::move(m)); + } } - Array ind(data.numIndices); - std::memcpy(ind.data(), &indices[data.firstIndex], data.numIndices * sizeof(uint32)); + Array ind(meshData[id][0].numIndices); + std::memcpy(ind.data(), &indices[meshData[id][0].firstIndex], meshData[id][0].numIndices * sizeof(uint32)); Serialization::save(buffer, out); Serialization::save(buffer, ind); } @@ -383,7 +351,9 @@ void VertexData::destroy() { uint32 VertexData::addCullingMapping(MeshId id) { uint32 result = meshletCount; - meshletCount += getMeshData(id).numMeshlets; + for (const auto& md : getMeshData(id)) { + meshletCount += md.numMeshlets; + } return result; } diff --git a/src/Engine/Graphics/VertexData.h b/src/Engine/Graphics/VertexData.h index a4419bf..139fa50 100644 --- a/src/Engine/Graphics/VertexData.h +++ b/src/Engine/Graphics/VertexData.h @@ -62,7 +62,7 @@ class VertexData { MeshId allocateVertexData(uint64 numVertices); uint64 getMeshOffset(MeshId id) const { return meshOffsets[id]; } uint64 getMeshVertexCount(MeshId id) { return meshVertexCounts[id]; } - virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer); + virtual void serializeMesh(MeshId id, ArchiveBuffer& buffer); virtual uint64 deserializeMesh(MeshId id, ArchiveBuffer& buffer); virtual void bindBuffers(Gfx::PRenderCommand command) = 0; virtual Gfx::PDescriptorLayout getVertexDataLayout() = 0; @@ -76,7 +76,7 @@ class VertexData { const Array& getMaterialData() const { return materialData; } const Array& getTransparentData() const { return transparentData; } const Array& getRayTracingData() const { return rayTracingScene; } - const MeshData& getMeshData(MeshId id) const { return meshData[id]; } + const Array& getMeshData(MeshId id) const { return meshData[id]; } void registerBottomLevelAccelerationStructure(Gfx::PBottomLevelAS blas) { dataToBuild.add(blas); } @@ -89,6 +89,7 @@ class VertexData { uint32 addCullingMapping(MeshId id); static uint64 getMeshletCount() { return meshletCount; } + constexpr static const char* CULLINGDATA_NAME = "cullingData"; protected: virtual void resizeBuffers() = 0; @@ -113,7 +114,8 @@ class VertexData { Array transparentData; std::mutex vertexDataLock; - Array meshData; + // each mesh id can have multiple meshdata, in case it needs to be split for having too many meshlets + Array> meshData; Array meshOffsets; Array meshVertexCounts; @@ -135,7 +137,6 @@ class VertexData { constexpr static const char* PRIMITIVEINDICES_NAME = "primitiveIndices"; Gfx::OShaderBuffer cullingOffsetBuffer; constexpr static const char* CULLINGOFFSETS_NAME = "cullingOffsets"; - constexpr static const char* CULLINGDATA_NAME = "cullingData"; // for legacy pipeline Gfx::OIndexBuffer indexBuffer; diff --git a/src/Engine/Graphics/Vulkan/RayTracing.cpp b/src/Engine/Graphics/Vulkan/RayTracing.cpp index e9370e7..1b4fb4e 100644 --- a/src/Engine/Graphics/Vulkan/RayTracing.cpp +++ b/src/Engine/Graphics/Vulkan/RayTracing.cpp @@ -22,7 +22,8 @@ BottomLevelAS::BottomLevelAS(PGraphics graphics, const Gfx::BottomLevelASCreateI 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, }; VertexData* vertexData = createInfo.mesh->vertexData; - MeshData meshData = vertexData->getMeshData(createInfo.mesh->id); + //todo: indices might be split as well + MeshData meshData = vertexData->getMeshData(createInfo.mesh->id)[0]; vertexOffset = vertexData->getMeshOffset(createInfo.mesh->id) * sizeof(Vector); vertexCount = vertexData->getMeshVertexCount(createInfo.mesh->id); indexOffset = meshData.firstIndex * sizeof(uint32); diff --git a/src/Engine/Graphics/slang-compile.cpp b/src/Engine/Graphics/slang-compile.cpp index fb689d3..55d8494 100644 --- a/src/Engine/Graphics/slang-compile.cpp +++ b/src/Engine/Graphics/slang-compile.cpp @@ -55,7 +55,7 @@ void Seele::beginCompilation(const ShaderCompilationInfo& info, SlangCompileTarg .value = { .kind = slang::CompilerOptionValueKind::Int, - .intValue0 = SLANG_DEBUG_INFO_LEVEL_NONE, + .intValue0 = SLANG_DEBUG_INFO_LEVEL_STANDARD, }, }, {