diff --git a/res/shaders/LegacyPass.slang b/res/shaders/LegacyPass.slang index 21ab54e..2d7c1e2 100644 --- a/res/shaders/LegacyPass.slang +++ b/res/shaders/LegacyPass.slang @@ -7,7 +7,7 @@ import Scene; FragmentParameter vertexMain( VertexInput input ){ - InstanceData inst = pScene.instances[input.instanceId]; + InstanceData inst = pScene.instances[pOffsets.instanceOffset + input.instanceId]; VertexAttributes attr = pVertexData.getAttributes(input.vertexId); return attr.getParameter(inst.transformMatrix); } \ No newline at end of file diff --git a/res/shaders/MeshletPass.slang b/res/shaders/MeshletPass.slang index 2914226..e0ca848 100644 --- a/res/shaders/MeshletPass.slang +++ b/res/shaders/MeshletPass.slang @@ -18,8 +18,9 @@ void meshMain( out vertices FragmentParameter vertices[MAX_VERTICES], out indices uint3 indices[MAX_PRIMITIVES] ){ - InstanceData inst = pScene.instances[meshPayload.instanceId]; - MeshletDescription m = pScene.meshletInfos[pScene.culledMeshlets[meshPayload.cullingOffset + groupID]]; + InstanceData inst = meshPayload.instanceData; + MeshData data = meshPayload.meshData; + MeshletDescription m = pScene.meshletInfos[data.meshletOffset + groupID]; SetMeshOutputCounts(m.vertexCount, m.primitiveCount); for(uint i = threadID; i < MAX_PRIMITIVES; i += MESH_GROUP_SIZE) @@ -32,7 +33,7 @@ void meshMain( indices[p] = uint3(local_idx0, local_idx1, local_idx2); } } - for(uint i = threadID; i < MAX_VERTICES; i+=MESH_GROUP_SIZE) + for(uint i = threadID; i < MAX_VERTICES; i += MESH_GROUP_SIZE) { uint v = min(i, m.vertexCount - 1); { diff --git a/res/shaders/ViewCullingTask.slang b/res/shaders/ViewCullingTask.slang index b2aca4c..d0b5029 100644 --- a/res/shaders/ViewCullingTask.slang +++ b/res/shaders/ViewCullingTask.slang @@ -28,21 +28,24 @@ void taskMain( viewFrustum.sides[1] = computePlane(origin, corners[1], corners[3]); viewFrustum.sides[2] = computePlane(origin, corners[0], corners[1]); viewFrustum.sides[3] = computePlane(origin, corners[3], corners[2]); - p.instanceId = pOffsets.instanceOffset + groupID; - p.cullingOffset = pScene.cullingOffsets[pOffsets.cullingCounterOffset + groupID]; + //p.instanceId = pOffsets.instanceOffset + groupID; + p.instanceData = instance; + p.meshData = mesh; + //p.cullingOffset = pScene.cullingOffsets[pOffsets.cullingCounterOffset + groupID]; } GroupMemoryBarrierWithGroupSync(); - for(uint i = threadID; i < mesh.numMeshlets; i += TASK_GROUP_SIZE) - { - uint m = mesh.meshletOffset + i; - MeshletDescription meshlet = pScene.meshletInfos[m]; - if(meshlet.bounding.insideFrustum(viewFrustum)) - { - uint index; - InterlockedAdd(head, 1, index); - pScene.culledMeshlets[p.cullingOffset + index] = m; - } - } - GroupMemoryBarrierWithGroupSync(); - DispatchMesh(head, 1, 1, p); + //for(uint i = threadID; i < mesh.numMeshlets; i += TASK_GROUP_SIZE) + //{ + // uint m = mesh.meshletOffset + i; + // MeshletDescription meshlet = pScene.meshletInfos[m]; + // //if(meshlet.bounding.insideFrustum(viewFrustum)) + // { + // uint index; + // InterlockedAdd(head, 1, index); + // p.culledMeshlets[index] = m; + // //pScene.culledMeshlets[p.cullingOffset + index] = m; + // } + //} + //GroupMemoryBarrierWithGroupSync(); + DispatchMesh(mesh.numMeshlets, 1, 1, p); } \ No newline at end of file diff --git a/res/shaders/lib/Scene.slang b/res/shaders/lib/Scene.slang index ac619c3..b7f9ad0 100644 --- a/res/shaders/lib/Scene.slang +++ b/res/shaders/lib/Scene.slang @@ -34,7 +34,6 @@ struct InstanceData struct DrawCallOffsets { uint32_t instanceOffset; - uint32_t cullingCounterOffset; }; layout(push_constant) ConstantBuffer pOffsets; @@ -46,15 +45,16 @@ struct Scene StructuredBuffer meshletInfos; StructuredBuffer primitiveIndices; StructuredBuffer vertexIndices; - StructuredBuffer cullingOffsets; - RWStructuredBuffer culledMeshlets; +// StructuredBuffer cullingOffsets; +// RWStructuredBuffer culledMeshlets; }; layout(set=2) ParameterBlock pScene; struct MeshPayload { - uint instanceId; - uint cullingOffset; + InstanceData instanceData; + MeshData meshData; + uint culledMeshlets[2048]; }; diff --git a/src/Engine/Graphics/Buffer.cpp b/src/Engine/Graphics/Buffer.cpp index f35b2cb..d78ed10 100644 --- a/src/Engine/Graphics/Buffer.cpp +++ b/src/Engine/Graphics/Buffer.cpp @@ -44,51 +44,19 @@ IndexBuffer::~IndexBuffer() } UniformBuffer::UniformBuffer(QueueFamilyMapping mapping, const DataSource& sourceData) : Buffer(mapping, sourceData.owner) - , contents(sourceData.size) -{ - if (sourceData.data != nullptr) - { - std::memcpy(contents.data(), sourceData.data, contents.size()); - } -} +{} UniformBuffer::~UniformBuffer() { } -bool UniformBuffer::updateContents(const DataSource& sourceData) -{ - assert(contents.size() == sourceData.size); - if (std::memcmp(contents.data(), sourceData.data, contents.size()) == 0) - { - return false; - } - std::memcpy(contents.data(), sourceData.data, contents.size()); - return true; -} - ShaderBuffer::ShaderBuffer(QueueFamilyMapping mapping, uint32 numElements, const DataSource& sourceData) : Buffer(mapping, sourceData.owner) - , contents(sourceData.size) , numElements(numElements) { - if (sourceData.data != nullptr) - { - std::memcpy(contents.data(), sourceData.data, sourceData.size); - } } ShaderBuffer::~ShaderBuffer() { } -void ShaderBuffer::updateContents(const ShaderBufferCreateInfo& createInfo) -{ - contents.resize(createInfo.sourceData.size); - numElements = createInfo.numElements; - if (createInfo.sourceData.data != nullptr) - { - std::memcpy(contents.data(), createInfo.sourceData.data, createInfo.sourceData.size); - } -} - diff --git a/src/Engine/Graphics/Buffer.h b/src/Engine/Graphics/Buffer.h index b81c4c6..1b4bc6a 100644 --- a/src/Engine/Graphics/Buffer.h +++ b/src/Engine/Graphics/Buffer.h @@ -64,25 +64,11 @@ class UniformBuffer : public Buffer { public: UniformBuffer(QueueFamilyMapping mapping, const DataSource &sourceData); virtual ~UniformBuffer(); - // returns true if an update was performed, false if the old contents == new - // contents - virtual bool updateContents(const DataSource &sourceData); - bool isDataEquals(PUniformBuffer other) { - if (other == nullptr) { - return false; - } - if (contents.size() != other->contents.size()) { - return false; - } - if (std::memcmp(contents.data(), other->contents.data(), contents.size()) != - 0) { - return false; - } - return true; - } + + virtual void rotateBuffer(uint64 size) = 0; + virtual void updateContents(const DataSource &sourceData) = 0; protected: - Array contents; // Inherited via QueueOwnedResource virtual void executeOwnershipBarrier(QueueType newOwner) = 0; virtual void executePipelineBarrier(SeAccessFlags srcAccess, @@ -97,7 +83,7 @@ public: const DataSource &bulkResourceData); virtual ~ShaderBuffer(); virtual void rotateBuffer(uint64 size) = 0; - virtual void updateContents(const ShaderBufferCreateInfo &sourceData); + virtual void updateContents(const ShaderBufferCreateInfo &sourceData) = 0; constexpr uint32 getNumElements() const { return numElements; } virtual void *mapRegion(uint64 offset = 0, uint64 size = -1, bool writeOnly = true) = 0; @@ -111,7 +97,6 @@ protected: SeAccessFlags dstAccess, SePipelineStageFlags dstStage) = 0; - Array contents; uint32 numElements; }; DEFINE_REF(ShaderBuffer) diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 6bf33cf..75adbb7 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -33,7 +33,7 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) basePassLayout->addDescriptorLayout(lightCullingLayout); basePassLayout->addPushConstants(Gfx::SePushConstantRange{ - .stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT, + .stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, .offset = 0, .size = sizeof(VertexData::DrawCallOffsets), }); @@ -145,7 +145,7 @@ void BasePass::render() pipelineInfo.renderPass = renderPass; pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL; pipelineInfo.multisampleState.samples = viewport->getSamples(); - pipelineInfo.colorBlend.attachmentCount = 1; + pipelineInfo.colorBlend.attachmentCount = 2; Gfx::PGraphicsPipeline pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo)); command->bindPipeline(pipeline); } @@ -153,27 +153,24 @@ void BasePass::render() command->bindDescriptor(viewParamsSet); command->bindDescriptor(scene->getLightEnvironment()->getDescriptorSet()); command->bindDescriptor(opaqueCulling); + command->bindDescriptor(vertexData->getInstanceDataSet()); for (const auto& drawCall : materialData.instances) { - command->bindDescriptor(drawCall.materialInstance->getDescriptorSet()); command->bindDescriptor(vertexData->getInstanceDataSet()); - command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT, 0, sizeof(VertexData::DrawCallOffsets), &drawCall.offsets); + command->bindDescriptor(drawCall.materialInstance->getDescriptorSet()); + command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &drawCall.offsets); if (graphics->supportMeshShading()) { - command->drawMesh(drawCall.numMeshes, 1, 1); + command->drawMesh(drawCall.instanceMeshData.size(), 1, 1); } else { - //command->bindIndexBuffer(vertexData->getIndexBuffer()); - //uint32 instanceOffset = 0; - //for (const auto& meshData : vertexData->getMeshData(instance.meshId)) - //{ - // if (meshData.numIndices > 0) - // { - // command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset); - // } - // instanceOffset++; - //} + command->bindIndexBuffer(vertexData->getIndexBuffer()); + 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), 0); + } } } commands.add(std::move(command)); diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp index 9ecaae1..5effa60 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp @@ -19,7 +19,7 @@ DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene) depthPrepassLayout = graphics->createPipelineLayout("DepthPrepassLayout"); depthPrepassLayout->addDescriptorLayout(viewParamsLayout); depthPrepassLayout->addPushConstants(Gfx::SePushConstantRange{ - .stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT, + .stageFlags = Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, .offset = 0, .size = sizeof(VertexData::DrawCallOffsets), }); @@ -117,23 +117,19 @@ void DepthPrepass::render() for (const auto& drawCall : materialData.instances) { command->bindDescriptor(vertexData->getInstanceDataSet()); - command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT, 0, sizeof(VertexData::DrawCallOffsets), &drawCall.offsets); + command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(VertexData::DrawCallOffsets), &drawCall.offsets); if (graphics->supportMeshShading()) { - command->drawMesh(drawCall.numMeshes, 1, 1); + command->drawMesh(drawCall.instanceMeshData.size(), 1, 1); } else { - //command->bindIndexBuffer(vertexData->getIndexBuffer()); - //uint32 instanceOffset = 0; - //for (const auto& meshData : vertexData->getMeshData(instance.meshId)) - //{ - // if (meshData.numIndices > 0) - // { - // command->drawIndexed(meshData.numIndices, 1, meshData.firstIndex, meshData.indicesOffset, instanceOffset); - // } - // instanceOffset++; - //} + command->bindIndexBuffer(vertexData->getIndexBuffer()); + 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), 0); + } } } commands.add(std::move(command)); diff --git a/src/Engine/Graphics/RenderPass/RenderPass.cpp b/src/Engine/Graphics/RenderPass/RenderPass.cpp index f0d5db8..bba69c4 100644 --- a/src/Engine/Graphics/RenderPass/RenderPass.cpp +++ b/src/Engine/Graphics/RenderPass/RenderPass.cpp @@ -38,6 +38,7 @@ void RenderPass::beginFrame(const Component::Camera& cam) .size = sizeof(ViewParameter), .data = (uint8*)&viewParams, }; + viewParamsBuffer->rotateBuffer(sizeof(ViewParameter)); viewParamsBuffer->updateContents(uniformUpdate); viewParamsBuffer->pipelineBarrier( Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index a7b4d9c..d303669 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -18,7 +18,7 @@ void VertexData::resetMeshData() std::unique_lock l(materialDataLock); for (auto& mat : materialData) { - for (auto inst : mat.instances) + for (auto& inst : mat.instances) { inst.instanceData.clear(); inst.instanceMeshData.clear(); @@ -51,15 +51,15 @@ void VertexData::updateMesh(PMesh mesh, Component::Transform& transform) matData.instances.resize(referencedInstance->getId() + 1); } BatchedDrawCall& matInstanceData = matData.instances[referencedInstance->getId()]; - const auto& data = meshData[mesh->id]; + matInstanceData.materialInstance = referencedInstance; Matrix4 transformMatrix = transform.toMatrix() * mesh->transform; matInstanceData.instanceData.add(InstanceData{ .transformMatrix = transformMatrix, .inverseTransformMatrix = glm::inverse(transformMatrix), }); + const auto& data = meshData[mesh->id]; matInstanceData.instanceMeshData.add(data); - matInstanceData.numMeshes++; for (size_t i = 0; i < 0; ++i) { auto bounding = meshlets[data.meshletOffset + i].bounding; @@ -100,7 +100,6 @@ void VertexData::updateMesh(PMesh mesh, Component::Transform& transform) addDebugVertex(DebugVertex{ .position = corners[7], .color = meshlets[data.meshletOffset + i].color }); } - matInstanceData.materialInstance = referencedInstance; referencedInstance->updateDescriptor(); } @@ -111,53 +110,52 @@ void VertexData::createDescriptors() instanceData.clear(); instanceMeshData.clear(); - uint32 numMeshlets = 0; - Array cullingOffsets; + //uint32 numMeshlets = 0; + //Array cullingOffsets; for (auto& mat : materialData) { for (auto& instance : mat.instances) { instance.offsets.instanceOffset = instanceData.size(); - instance.offsets.cullingCounterOffset = cullingOffsets.size(); - instance.numMeshes = instance.instanceData.size(); - instance.numMeshlets = 0; + //instance.offsets.cullingCounterOffset = cullingOffsets.size(); + //instance.numMeshlets = 0; for (size_t i = 0; i < instance.instanceData.size(); ++i) { instanceData.add(instance.instanceData[i]); instanceMeshData.add(instance.instanceMeshData[i]); - instance.numMeshlets += instance.instanceMeshData[i].numMeshlets; - cullingOffsets.add(numMeshlets); - numMeshlets += instance.numMeshlets; + //instance.numMeshlets += instance.instanceMeshData[i].numMeshlets; + //cullingOffsets.add(numMeshlets); + //numMeshlets += instance.numMeshlets; } } } - cullingOffsetBuffer->rotateBuffer(cullingOffsets.size() * sizeof(uint32)); - cullingOffsetBuffer->updateContents(ShaderBufferCreateInfo{ - .sourceData = { - .size = cullingOffsets.size() * sizeof(uint32), - .data = (uint8*)cullingOffsets.data(), - }, - .numElements = cullingOffsets.size() - }); - cullingOffsetBuffer->pipelineBarrier( - Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, - Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, - Gfx::SE_ACCESS_MEMORY_READ_BIT, - Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT - ); - cullingBuffer->rotateBuffer(numMeshlets * sizeof(uint32)); - cullingBuffer->updateContents(ShaderBufferCreateInfo{ - .sourceData = { - .size = numMeshlets * sizeof(uint32), - }, - .numElements = numMeshlets - }); - cullingBuffer->pipelineBarrier( - Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, - Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, - Gfx::SE_ACCESS_MEMORY_WRITE_BIT, - Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT - ); + //cullingOffsetBuffer->rotateBuffer(cullingOffsets.size() * sizeof(uint32)); + //cullingOffsetBuffer->updateContents(ShaderBufferCreateInfo{ + // .sourceData = { + // .size = cullingOffsets.size() * sizeof(uint32), + // .data = (uint8*)cullingOffsets.data(), + // }, + // .numElements = cullingOffsets.size() + // }); + //cullingOffsetBuffer->pipelineBarrier( + // Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, + // Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, + // Gfx::SE_ACCESS_MEMORY_READ_BIT, + // Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT + //); + //cullingBuffer->rotateBuffer(numMeshlets * sizeof(uint32)); + //cullingBuffer->updateContents(ShaderBufferCreateInfo{ + // .sourceData = { + // .size = numMeshlets * sizeof(uint32), + // }, + // .numElements = numMeshlets + // }); + //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 = { @@ -170,7 +168,7 @@ void VertexData::createDescriptors() Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_MEMORY_READ_BIT, - Gfx::SE_PIPELINE_STAGE_VERTEX_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT + Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT ); instanceMeshDataBuffer->rotateBuffer(sizeof(MeshData) * instanceMeshData.size()); @@ -185,7 +183,7 @@ void VertexData::createDescriptors() Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_MEMORY_READ_BIT, - Gfx::SE_PIPELINE_STAGE_VERTEX_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT + Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT ); instanceDataLayout->reset(); descriptorSet = instanceDataLayout->allocateDescriptorSet(); @@ -194,14 +192,15 @@ void VertexData::createDescriptors() descriptorSet->updateBuffer(2, meshletBuffer); descriptorSet->updateBuffer(3, primitiveIndicesBuffer); descriptorSet->updateBuffer(4, vertexIndicesBuffer); - descriptorSet->updateBuffer(5, cullingOffsetBuffer); - descriptorSet->updateBuffer(6, cullingBuffer); + //descriptorSet->updateBuffer(5, cullingOffsetBuffer); + //descriptorSet->updateBuffer(6, cullingBuffer); descriptorSet->writeChanges(); } void VertexData::loadMesh(MeshId id, Array loadedIndices, Array loadedMeshlets) { + assert(loadedMeshlets.size() < 2048); std::unique_lock l(vertexDataLock); meshlets.reserve(meshlets.size() + loadedMeshlets.size()); vertexIndices.reserve(vertexIndices.size() + loadedMeshlets.size() * Gfx::numVerticesPerMeshlet); @@ -232,10 +231,10 @@ void VertexData::loadMesh(MeshId id, Array loadedIndices, Array .bounding = meshAABB,//.toSphere(), .numMeshlets = (uint32)loadedMeshlets.size(), .meshletOffset = meshletOffset, + .firstIndex = (uint32)indices.size(), + .numIndices = (uint32)loadedIndices.size(), }; - meshData[id].firstIndex = indices.size(); - meshData[id].numIndices = loadedIndices.size(); if (!graphics->supportMeshShading()) { indices.resize(indices.size() + loadedIndices.size()); @@ -340,18 +339,18 @@ void VertexData::init(Gfx::PGraphics _graphics) // vertexIndices instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER }); // cullingList - instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER }); + //instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER }); // cullingOffset - instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 6, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER }); + //instanceDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 6, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER }); - cullingOffsetBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ - .dynamic = true, - .name = "MeshletOffset", - }); - cullingBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ - .dynamic = true, - .name = "MeshletCulling", - }); + //cullingOffsetBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ + // .dynamic = true, + // .name = "MeshletOffset", + // }); + //cullingBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ + // .dynamic = true, + // .name = "MeshletCulling", + // }); instanceBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ .dynamic = true, .name = "InstanceBuffer", diff --git a/src/Engine/Graphics/VertexData.h b/src/Engine/Graphics/VertexData.h index 09536ff..e11afc4 100644 --- a/src/Engine/Graphics/VertexData.h +++ b/src/Engine/Graphics/VertexData.h @@ -44,13 +44,10 @@ public: struct DrawCallOffsets { uint32 instanceOffset = 0; - uint32 cullingCounterOffset = 0; }; struct BatchedDrawCall { PMaterialInstance materialInstance; - uint64 numMeshes = 0; - uint64 numMeshlets = 0; DrawCallOffsets offsets; Array instanceData; Array instanceMeshData; @@ -78,6 +75,7 @@ public: Gfx::PDescriptorSet getInstanceDataSet() { return descriptorSet; } const Array& getMaterialData() const { return materialData; } const MeshData& getMeshData(MeshId id) { return meshData[id]; } + uint64 getIndicesOffset(uint32 meshletIndex) { return meshlets[meshletIndex].indicesOffset; } static List getList(); static VertexData* findByTypeName(std::string name); virtual void init(Gfx::PGraphics graphics); @@ -113,8 +111,8 @@ protected: Gfx::OShaderBuffer vertexIndicesBuffer; Gfx::OShaderBuffer primitiveIndicesBuffer; // temporary meshlet culling buffer, passed from task to mesh shader - Gfx::OShaderBuffer cullingBuffer; - Gfx::OShaderBuffer cullingOffsetBuffer; + //Gfx::OShaderBuffer cullingBuffer; + //Gfx::OShaderBuffer cullingOffsetBuffer; // for legacy pipeline Gfx::OIndexBuffer indexBuffer; // Material data diff --git a/src/Engine/Graphics/Vulkan/Buffer.cpp b/src/Engine/Graphics/Vulkan/Buffer.cpp index b6e30e0..4c14ab3 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.cpp +++ b/src/Engine/Graphics/Vulkan/Buffer.cpp @@ -222,6 +222,7 @@ void Buffer::unmap() { } void Buffer::rotateBuffer(uint64 size) { + assert(dynamic); size = std::max(getSize(), size); for (size_t i = 0; i < buffers.size(); ++i) { if (buffers[i]->isCurrentlyBound()) { @@ -316,15 +317,15 @@ UniformBuffer::UniformBuffer(PGraphics graphics, UniformBuffer::~UniformBuffer() {} -bool UniformBuffer::updateContents(const DataSource &sourceData) { - if (!Gfx::UniformBuffer::updateContents(sourceData)) { - // no update was performed, skip - return false; - } +void UniformBuffer::updateContents(const DataSource &sourceData) { void *data = map(); std::memcpy(data, sourceData.data, sourceData.size); unmap(); - return true; +} + +void UniformBuffer::rotateBuffer(uint64 size) +{ + Vulkan::Buffer::rotateBuffer(size); } void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { @@ -368,11 +369,10 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, ShaderBuffer::~ShaderBuffer() {} void ShaderBuffer::updateContents(const ShaderBufferCreateInfo &createInfo) { - Gfx::ShaderBuffer::updateContents(createInfo); - // We always want to update, as the contents could be different on the GPU if (createInfo.sourceData.data == nullptr) { return; } + // We always want to update, as the contents could be different on the GPU void *data = map(); std::memcpy((char*)data + createInfo.sourceData.offset, createInfo.sourceData.data, createInfo.sourceData.size); unmap(); diff --git a/src/Engine/Graphics/Vulkan/Buffer.h b/src/Engine/Graphics/Vulkan/Buffer.h index 2b3478b..7ba09cb 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.h +++ b/src/Engine/Graphics/Vulkan/Buffer.h @@ -103,7 +103,8 @@ class UniformBuffer : public Gfx::UniformBuffer, public Buffer { public: UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &sourceData); virtual ~UniformBuffer(); - virtual bool updateContents(const DataSource &sourceData) override; + virtual void updateContents(const DataSource &sourceData) override; + virtual void rotateBuffer(uint64 size) override; protected: // Inherited via Vulkan::Buffer diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp index aa052eb..70a2311 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.cpp +++ b/src/Engine/Graphics/Vulkan/Graphics.cpp @@ -399,7 +399,7 @@ void Graphics::initInstance(GraphicsInitializer initInfo) .applicationVersion = VK_MAKE_VERSION(0, 0, 1), .pEngineName = initInfo.engineName, .engineVersion = VK_MAKE_VERSION(0, 0, 1), - .apiVersion = VK_API_VERSION_1_2, + .apiVersion = VK_API_VERSION_1_3, }; Array extensions = getRequiredExtensions(); @@ -496,7 +496,7 @@ void Graphics::pickPhysicalDevice() { if (std::strcmp(VK_EXT_MESH_SHADER_EXTENSION_NAME, extensionProps[i].extensionName) == 0) { - meshShadingEnabled = true; + //meshShadingEnabled = true; break; } } diff --git a/src/Engine/Graphics/Vulkan/PipelineCache.cpp b/src/Engine/Graphics/Vulkan/PipelineCache.cpp index 8af581f..f942773 100644 --- a/src/Engine/Graphics/Vulkan/PipelineCache.cpp +++ b/src/Engine/Graphics/Vulkan/PipelineCache.cpp @@ -50,8 +50,12 @@ PipelineCache::~PipelineCache() PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gfxInfo) { + uint32 hash = CRC::Calculate(&gfxInfo, sizeof(Gfx::LegacyPipelineCreateInfo), CRC::CRC_32()); + if (graphicsPipelines.contains(hash)) + { + return graphicsPipelines[hash]; + } PPipelineLayout layout = Gfx::PPipelineLayout(gfxInfo.pipelineLayout).cast(); - uint32 hash = layout->getHash(); Array bindings; Array attributes; if (gfxInfo.vertexInput != nullptr) @@ -74,8 +78,6 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf .offset = a.offset, }; } - hash = CRC::Calculate(bindings.data(), sizeof(VkVertexInputBindingDescription) * bindings.size(), CRC::CRC_32(), hash); - hash = CRC::Calculate(attributes.data(), sizeof(VkVertexInputAttributeDescription) * attributes.size(), CRC::CRC_32(), hash); } VkPipelineVertexInputStateCreateInfo vertexInput = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, @@ -116,7 +118,6 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf .pSpecializationInfo = nullptr, }; } - hash = CRC::Calculate(stageInfos, sizeof(stageInfos), CRC::CRC_32(), hash); VkPipelineInputAssemblyStateCreateInfo assemblyInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, .pNext = nullptr, @@ -124,7 +125,6 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf .topology = cast(gfxInfo.topology), .primitiveRestartEnable = false, }; - hash = CRC::Calculate(&assemblyInfo, sizeof(assemblyInfo), CRC::CRC_32(), hash); VkPipelineViewportStateCreateInfo viewportInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, .pNext = nullptr, @@ -134,7 +134,6 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf .scissorCount = 1, .pScissors = nullptr, }; - hash = CRC::Calculate(&viewportInfo, sizeof(viewportInfo), CRC::CRC_32(), hash); VkPipelineRasterizationStateCreateInfo rasterizationState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, .pNext = nullptr, @@ -150,8 +149,6 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf .depthBiasSlopeFactor = gfxInfo.rasterizationState.depthBiasSlopeFactor, .lineWidth = gfxInfo.rasterizationState.lineWidth, }; - hash = CRC::Calculate(&rasterizationState, sizeof(rasterizationState), CRC::CRC_32(), hash); - VkPipelineMultisampleStateCreateInfo multisampleState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .pNext = nullptr, @@ -162,8 +159,6 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf .alphaToCoverageEnable = gfxInfo.multisampleState.alphaCoverageEnable, .alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable, }; - hash = CRC::Calculate(&multisampleState, sizeof(multisampleState), CRC::CRC_32(), hash); - VkPipelineDepthStencilStateCreateInfo depthStencilState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, .pNext = nullptr, @@ -177,8 +172,6 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf .minDepthBounds = gfxInfo.depthStencilState.minDepthBounds, .maxDepthBounds = gfxInfo.depthStencilState.maxDepthBounds, }; - hash = CRC::Calculate(&depthStencilState, sizeof(depthStencilState), CRC::CRC_32(), hash); - Array blendAttachments; for(uint32 i = 0; i < gfxInfo.colorBlend.attachmentCount; ++i) { @@ -194,8 +187,6 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf .colorWriteMask = attachment.colorWriteMask, }; } - hash = CRC::Calculate(blendAttachments.data(), blendAttachments.size() * sizeof(VkPipelineColorBlendAttachmentState), CRC::CRC_32(), hash); - VkPipelineColorBlendStateCreateInfo blendState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, .pNext = nullptr, @@ -206,13 +197,11 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf .pAttachments = blendAttachments.data(), }; std::memcpy(blendState.blendConstants, gfxInfo.colorBlend.blendConstants.data(), sizeof(blendState.blendConstants)); - hash = CRC::Calculate(&blendState, sizeof(blendState), CRC::CRC_32(), hash); uint32 numDynamicEnabled = 0; StaticArray dynamicEnabled; dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_VIEWPORT; dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_SCISSOR; - hash = CRC::Calculate(dynamicEnabled.data(), dynamicEnabled.size() * sizeof(VkDynamicState), CRC::CRC_32(), hash); VkPipelineDynamicStateCreateInfo dynamicState = { .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, @@ -221,11 +210,6 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf .dynamicStateCount = (uint32)dynamicEnabled.size(), .pDynamicStates = dynamicEnabled.data(), }; - - if (graphicsPipelines.contains(hash)) - { - return graphicsPipelines[hash]; - } VkPipeline pipelineHandle; VkGraphicsPipelineCreateInfo createInfo = {