diff --git a/src/Engine/Graphics/Buffer.h b/src/Engine/Graphics/Buffer.h index 7785788..0daf8ea 100644 --- a/src/Engine/Graphics/Buffer.h +++ b/src/Engine/Graphics/Buffer.h @@ -24,7 +24,7 @@ class VertexBuffer : public Buffer { // Size of one vertex in bytes constexpr uint32 getVertexSize() const { return vertexSize; } - virtual void updateRegion(DataSource update) = 0; + virtual void updateRegion(uint64 offset, uint64 size, void* data) = 0; virtual void download(Array& buffer) = 0; protected: @@ -63,7 +63,7 @@ class UniformBuffer : public Buffer { virtual ~UniformBuffer(); virtual void rotateBuffer(uint64 size) = 0; - virtual void updateContents(const DataSource& sourceData) = 0; + virtual void updateContents(uint64 offset, uint64 size, void* data) = 0; protected: // Inherited via QueueOwnedResource @@ -76,9 +76,11 @@ class ShaderBuffer : public Buffer { public: ShaderBuffer(QueueFamilyMapping mapping, const ShaderBufferCreateInfo& createInfo); virtual ~ShaderBuffer(); - virtual void readContents(Array& data) = 0; + virtual void readContents(uint64 offset, uint64 size, void* data) = 0; virtual void rotateBuffer(uint64 size, bool preserveContents = false) = 0; - virtual void updateContents(const ShaderBufferCreateInfo& sourceData) = 0; + virtual void updateContents(uint64 offset, uint64 size, void* data) = 0; + virtual void* map() = 0; + virtual void unmap() = 0; constexpr uint32 getNumElements() const { return numElements; } virtual void clear() = 0; diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 4e844a6..f61b7f2 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -116,10 +116,7 @@ void BasePass::beginFrame(const Component::Camera& cam) { textureLayout->reset(); skyboxData.transformMatrix = glm::rotate(skyboxData.transformMatrix, (float)(Gfx::getCurrentFrameDelta()), Vector(0, 1, 0)); skyboxBuffer->rotateBuffer(sizeof(SkyboxData)); - skyboxBuffer->updateContents(DataSource{ - .size = sizeof(SkyboxData), - .data = (uint8*)&skyboxData, - }); + skyboxBuffer->updateContents(0, sizeof(SkyboxData), &skyboxData); skyboxBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_UNIFORM_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); skyboxDataSet = skyboxDataLayout->allocateDescriptorSet(); diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp index fc5c50f..8b5f050 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -22,18 +22,10 @@ void LightCullingPass::beginFrame(const Component::Camera& cam) { Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_MEMORY_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT); uint32 reset = 0; - ShaderBufferCreateInfo counterReset = { - .sourceData = - { - .size = sizeof(uint32), - .data = (uint8*)&reset, - .owner = Gfx::QueueType::COMPUTE, - }, - }; oLightIndexCounter->rotateBuffer(sizeof(uint32)); - oLightIndexCounter->updateContents(counterReset); + oLightIndexCounter->updateContents(0, sizeof(uint32), &reset); tLightIndexCounter->rotateBuffer(sizeof(uint32)); - tLightIndexCounter->updateContents(counterReset); + tLightIndexCounter->updateContents(0, sizeof(uint32), &reset); oLightIndexCounter->pipelineBarrier(Gfx::SE_ACCESS_MEMORY_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_MEMORY_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); tLightIndexCounter->pipelineBarrier(Gfx::SE_ACCESS_MEMORY_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, diff --git a/src/Engine/Graphics/RenderPass/RenderPass.cpp b/src/Engine/Graphics/RenderPass/RenderPass.cpp index d3bb97c..eb94b96 100644 --- a/src/Engine/Graphics/RenderPass/RenderPass.cpp +++ b/src/Engine/Graphics/RenderPass/RenderPass.cpp @@ -32,12 +32,8 @@ void RenderPass::beginFrame(const Component::Camera& cam) { .cameraPosition = Vector4(cam.getCameraPosition(), 1), .screenDimensions = Vector2(static_cast(viewport->getWidth()), static_cast(viewport->getHeight())), }; - DataSource uniformUpdate = { - .size = sizeof(ViewParameter), - .data = (uint8*)&viewParams, - }; viewParamsBuffer->rotateBuffer(sizeof(ViewParameter)); - viewParamsBuffer->updateContents(uniformUpdate); + viewParamsBuffer->updateContents(0, sizeof(ViewParameter), &viewParams); viewParamsBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_UNIFORM_READ_BIT | Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT | Gfx::SE_PIPELINE_STAGE_MESH_SHADER_BIT_EXT | diff --git a/src/Engine/Graphics/RenderPass/TextPass.cpp b/src/Engine/Graphics/RenderPass/TextPass.cpp index dee17f0..d6c48f1 100644 --- a/src/Engine/Graphics/RenderPass/TextPass.cpp +++ b/src/Engine/Graphics/RenderPass/TextPass.cpp @@ -53,11 +53,7 @@ void TextPass::beginFrame(const Component::Camera& cam) { }; } auto proj = viewport->getProjectionMatrix(); - DataSource projectionUpdate = { - .size = sizeof(Matrix4), - .data = (uint8*)&proj, - }; - projectionBuffer->updateContents(projectionUpdate); + projectionBuffer->updateContents(0, sizeof(Matrix4), &proj); generalSet->updateBuffer(1, projectionBuffer); generalSet->writeChanges(); // co_return; diff --git a/src/Engine/Graphics/RenderPass/UIPass.cpp b/src/Engine/Graphics/RenderPass/UIPass.cpp index 94b63a7..59602ab 100644 --- a/src/Engine/Graphics/RenderPass/UIPass.cpp +++ b/src/Engine/Graphics/RenderPass/UIPass.cpp @@ -20,10 +20,7 @@ void UIPass::beginFrame(const Component::Camera& cam) { }; elementBuffer = graphics->createVertexBuffer(info); uint32 numTextures = static_cast(usedTextures.size()); - numTexturesBuffer->updateContents({ - .size = sizeof(uint32), - .data = (uint8*)&numTextures, - }); + numTexturesBuffer->updateContents(0, sizeof(uint32), &numTextures); descriptorSet->updateBuffer(2, numTexturesBuffer); descriptorSet->updateTextureArray(3, usedTextures); descriptorSet->writeChanges(); diff --git a/src/Engine/Graphics/StaticMeshVertexData.cpp b/src/Engine/Graphics/StaticMeshVertexData.cpp index 76c37b3..324a772 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.cpp +++ b/src/Engine/Graphics/StaticMeshVertexData.cpp @@ -18,56 +18,44 @@ StaticMeshVertexData* StaticMeshVertexData::getInstance() { } void StaticMeshVertexData::loadPositions(uint64 offset, const Array& data) { - if (swappedOut) { - swapIn(); - } assert(offset + data.size() <= head); - std::memcpy(positionData.data() + offset, data.data(), data.size() * sizeof(Vector4)); + std::memcpy((Vector4*)positions->map() + offset, data.data(), data.size() * sizeof(Vector4)); + //positions->updateContents(offset * sizeof(Vector4), data.size() * sizeof(Vector4), data.data()); dirty = true; } void StaticMeshVertexData::loadTexCoords(uint64 offset, uint64 index, const Array& data) { - if (swappedOut) { - swapIn(); - } assert(offset + data.size() <= head); - std::memcpy(texCoordsData[index].data() + offset, data.data(), data.size() * sizeof(Vector2)); + std::memcpy((Vector2*)texCoords[index]->map() + offset, data.data(), data.size() * sizeof(Vector2)); + //texCoords[index]->updateContents(offset * sizeof(Vector2), data.size() * sizeof(Vector2), data.data()); dirty = true; } void StaticMeshVertexData::loadNormals(uint64 offset, const Array& data) { - if (swappedOut) { - swapIn(); - } assert(offset + data.size() <= head); - std::memcpy(normalData.data() + offset, data.data(), data.size() * sizeof(Vector4)); + std::memcpy((Vector4*)normals->map() + offset, data.data(), data.size() * sizeof(Vector4)); + // normals->updateContents(offset * sizeof(Vector4), data.size() * sizeof(Vector4), data.data()); dirty = true; } void StaticMeshVertexData::loadTangents(uint64 offset, const Array& data) { - if (swappedOut) { - swapIn(); - } assert(offset + data.size() <= head); - std::memcpy(tangentData.data() + offset, data.data(), data.size() * sizeof(Vector4)); + std::memcpy((Vector4*)tangents->map() + offset, data.data(), data.size() * sizeof(Vector4)); + //tangents->updateContents(offset * sizeof(Vector4), data.size() * sizeof(Vector4), data.data()); dirty = true; } void StaticMeshVertexData::loadBiTangents(uint64 offset, const Array& data) { - if (swappedOut) { - swapIn(); - } assert(offset + data.size() <= head); - std::memcpy(biTangentData.data() + offset, data.data(), data.size() * sizeof(Vector4)); + std::memcpy((Vector4*)biTangents->map() + offset, data.data(), data.size() * sizeof(Vector4)); + // biTangents->updateContents(offset * sizeof(Vector4), data.size() * sizeof(Vector4), data.data()); dirty = true; } -void Seele::StaticMeshVertexData::loadColors(uint64 offset, const Array& data) { - if (swappedOut) { - swapIn(); - } +void StaticMeshVertexData::loadColors(uint64 offset, const Array& data) { assert(offset + data.size() <= head); - std::memcpy(colorData.data() + offset, data.data(), data.size() * sizeof(Vector4)); + std::memcpy((Vector4*)colors->map() + offset, data.data(), data.size() * sizeof(Vector4)); + //colors->updateContents(offset * sizeof(Vector4), data.size() * sizeof(Vector4), data.data()); dirty = true; } @@ -82,18 +70,18 @@ void StaticMeshVertexData::serializeMesh(MeshId id, uint64 numVertices, ArchiveB Array tex[MAX_TEXCOORDS]; for (size_t i = 0; i < MAX_TEXCOORDS; ++i) { tex[i].resize(numVertices); - std::memcpy(tex[i].data(), texCoordsData[i].data() + offset, numVertices * sizeof(Vector2)); + texCoords[i]->readContents(offset * sizeof(Vector2), numVertices * sizeof(Vector2), tex[i].data()); Serialization::save(buffer, tex[i]); } Array nor(numVertices); Array tan(numVertices); Array bit(numVertices); Array col(numVertices); - std::memcpy(pos.data(), positionData.data() + offset, numVertices * sizeof(Vector4)); - std::memcpy(nor.data(), normalData.data() + offset, numVertices * sizeof(Vector4)); - std::memcpy(tan.data(), tangentData.data() + offset, numVertices * sizeof(Vector4)); - std::memcpy(bit.data(), biTangentData.data() + offset, numVertices * sizeof(Vector4)); - std::memcpy(col.data(), colorData.data() + offset, numVertices * sizeof(Vector4)); + positions->readContents(offset * sizeof(Vector4), numVertices * sizeof(Vector4), pos.data()); + normals->readContents(offset * sizeof(Vector4), numVertices * sizeof(Vector4), nor.data()); + tangents->readContents(offset * sizeof(Vector4), numVertices * sizeof(Vector4), tan.data()); + biTangents->readContents(offset * sizeof(Vector4), numVertices * sizeof(Vector4), bit.data()); + colors->readContents(offset * sizeof(Vector4), numVertices * sizeof(Vector4), col.data()); Serialization::save(buffer, pos); Serialization::save(buffer, nor); Serialization::save(buffer, tan); @@ -108,13 +96,13 @@ uint64 StaticMeshVertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) { std::unique_lock l(vertexDataLock); offset = meshOffsets[id]; } - Array pos; Array tex[MAX_TEXCOORDS]; for (size_t i = 0; i < MAX_TEXCOORDS; ++i) { Serialization::load(buffer, tex[i]); loadTexCoords(offset, i, tex[i]); result += tex[i].size() * sizeof(Vector2); } + Array pos; Array nor; Array tan; Array bit; @@ -139,51 +127,13 @@ uint64 StaticMeshVertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) { void StaticMeshVertexData::init(Gfx::PGraphics _graphics) { VertexData::init(_graphics); - descriptorLayout = _graphics->createDescriptorLayout("pVertexData"); - descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); - descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); - descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); - descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); - descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); - descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ - .binding = 5, - .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, - .descriptorCount = MAX_TEXCOORDS, - }); - descriptorLayout->create(); - descriptorSet = descriptorLayout->allocateDescriptorSet(); -} - -void StaticMeshVertexData::destroy() { - VertexData::destroy(); - positions = nullptr; - for (size_t i = 0; i < MAX_TEXCOORDS; ++i) { - texCoords[i] = nullptr; - } - normals = nullptr; - tangents = nullptr; - biTangents = nullptr; - colors = nullptr; - descriptorSet = nullptr; - descriptorLayout = nullptr; -} - -void StaticMeshVertexData::bindBuffers(Gfx::PRenderCommand) { - // TODO: for legacy vertex buffer binding -} - -Gfx::PDescriptorLayout StaticMeshVertexData::getVertexDataLayout() { return descriptorLayout; } - -Gfx::PDescriptorSet StaticMeshVertexData::getVertexDataSet() { return descriptorSet; } - -void StaticMeshVertexData::resizeBuffers() { ShaderBufferCreateInfo createInfo = { .sourceData = { .size = verticesAllocated * sizeof(Vector4), }, .numElements = verticesAllocated, - .dynamic = false, + .dynamic = true, .vertexBuffer = true, .name = "Positions", }; @@ -201,68 +151,64 @@ void StaticMeshVertexData::resizeBuffers() { createInfo.name = "TexCoords"; for (size_t i = 0; i < MAX_TEXCOORDS; ++i) { texCoords[i] = graphics->createShaderBuffer(createInfo); - texCoordsData[i].resize(verticesAllocated); } + descriptorLayout = _graphics->createDescriptorLayout("pVertexData"); + descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); + descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); + descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); + descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); + descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{.binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER}); + descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ + .binding = 5, + .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .descriptorCount = MAX_TEXCOORDS, + }); + descriptorLayout->create(); + descriptorSet = descriptorLayout->allocateDescriptorSet(); +} - positionData.resize(verticesAllocated); - normalData.resize(verticesAllocated); - tangentData.resize(verticesAllocated); - biTangentData.resize(verticesAllocated); - colorData.resize(verticesAllocated); +void StaticMeshVertexData::destroy() { + VertexData::destroy(); + for (size_t i = 0; i < MAX_TEXCOORDS; ++i) { + texCoords[i] = nullptr; + } + positions = nullptr; + normals = nullptr; + tangents = nullptr; + biTangents = nullptr; + colors = nullptr; + descriptorSet = nullptr; + descriptorLayout = nullptr; +} + +void StaticMeshVertexData::bindBuffers(Gfx::PRenderCommand) { + // TODO: for legacy vertex buffer binding +} + +Gfx::PDescriptorLayout StaticMeshVertexData::getVertexDataLayout() { return descriptorLayout; } + +Gfx::PDescriptorSet StaticMeshVertexData::getVertexDataSet() { return descriptorSet; } + +void StaticMeshVertexData::resizeBuffers() { + positions->rotateBuffer(verticesAllocated * sizeof(Vector4), true); + normals->rotateBuffer(verticesAllocated * sizeof(Vector4), true); + tangents->rotateBuffer(verticesAllocated * sizeof(Vector4), true); + biTangents->rotateBuffer(verticesAllocated * sizeof(Vector4), true); + colors->rotateBuffer(verticesAllocated * sizeof(Vector4), true); + for (size_t i = 0; i < MAX_TEXCOORDS; ++i) { + texCoords[i]->rotateBuffer(verticesAllocated * sizeof(Vector2), true); + } } void StaticMeshVertexData::updateBuffers() { - positions->updateContents(ShaderBufferCreateInfo{ - .sourceData{ - .size = positionData.size() * sizeof(Vector4), - .data = (uint8*)positionData.data(), - }, - .numElements = positionData.size(), - }); + positions->unmap(); + normals->unmap(); + tangents->unmap(); + biTangents->unmap(); + colors->unmap(); for (size_t i = 0; i < MAX_TEXCOORDS; ++i) { - texCoords[i]->updateContents(ShaderBufferCreateInfo{ - .sourceData = - { - .size = texCoordsData[i].size() * sizeof(Vector2), - .data = (uint8*)texCoordsData[i].data(), - }, - .numElements = texCoordsData[i].size(), - }); + texCoords[i]->unmap(); } - normals->updateContents(ShaderBufferCreateInfo{ - .sourceData = - { - .size = normalData.size() * sizeof(Vector4), - .data = (uint8*)normalData.data(), - }, - .numElements = normalData.size(), - }); - tangents->updateContents(ShaderBufferCreateInfo{ - .sourceData = - { - .size = tangentData.size() * sizeof(Vector4), - .data = (uint8*)tangentData.data(), - }, - .numElements = tangentData.size(), - }); - biTangents->updateContents(ShaderBufferCreateInfo{ - .sourceData = - { - .size = biTangentData.size() * sizeof(Vector4), - .data = (uint8*)biTangentData.data(), - }, - .numElements = biTangentData.size(), - }); - colors->updateContents(ShaderBufferCreateInfo{ - .sourceData = - { - .size = colorData.size() * sizeof(Vector4), - .data = (uint8*)colorData.data(), - }, - .numElements = colorData.size(), - }); - // we just updated the GPU buffers, might not change that for a while - swapOut(); descriptorLayout->reset(); descriptorSet = descriptorLayout->allocateDescriptorSet(); descriptorSet->updateBuffer(0, positions); @@ -275,39 +221,3 @@ void StaticMeshVertexData::updateBuffers() { } descriptorSet->writeChanges(); } - -void StaticMeshVertexData::swapOut() { - ArchiveBuffer buf; - Serialization::save(buf, positionData); - positionData.clear(); - Serialization::save(buf, normalData); - normalData.clear(); - Serialization::save(buf, tangentData); - tangentData.clear(); - Serialization::save(buf, biTangentData); - biTangentData.clear(); - Serialization::save(buf, colorData); - colorData.clear(); - for (size_t i = 0; i < MAX_TEXCOORDS; ++i) { - Serialization::save(buf, texCoordsData[i]); - texCoordsData[i].clear(); - } - std::ofstream str("vertex", std::ios::binary); - buf.writeToStream(str); - swappedOut = true; -} - -void StaticMeshVertexData::swapIn() { - ArchiveBuffer buf; - std::ifstream str("vertex", std::ios::binary); - buf.readFromStream(str); - Serialization::load(buf, positionData); - Serialization::load(buf, normalData); - Serialization::load(buf, tangentData); - Serialization::load(buf, biTangentData); - Serialization::load(buf, colorData); - for (size_t i = 0; i < MAX_TEXCOORDS; ++i) { - Serialization::load(buf, texCoordsData[i]); - } - swappedOut = false; -} diff --git a/src/Engine/Graphics/StaticMeshVertexData.h b/src/Engine/Graphics/StaticMeshVertexData.h index 9d40686..06ea592 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.h +++ b/src/Engine/Graphics/StaticMeshVertexData.h @@ -32,22 +32,12 @@ class StaticMeshVertexData : public VertexData { virtual void resizeBuffers() override; virtual void updateBuffers() override; - void swapOut(); - void swapIn(); - Gfx::OShaderBuffer positions; - Array positionData; Gfx::OShaderBuffer texCoords[MAX_TEXCOORDS]; - Array texCoordsData[MAX_TEXCOORDS]; Gfx::OShaderBuffer normals; - Array normalData; Gfx::OShaderBuffer tangents; - Array tangentData; Gfx::OShaderBuffer biTangents; - Array biTangentData; Gfx::OShaderBuffer colors; - Array colorData; - bool swappedOut = false; Gfx::ODescriptorLayout descriptorLayout; Gfx::PDescriptorSet descriptorSet; }; diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index d118154..96f60c4 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -7,10 +7,11 @@ #include "Graphics/Shader.h" #include "Material/Material.h" #include "Material/MaterialInstance.h" +#include using namespace Seele; -constexpr static uint64 NUM_DEFAULT_ELEMENTS = 1024 * 1024; +constexpr static uint64 NUM_DEFAULT_ELEMENTS = 1024 * 1024;// 17962284 Map VertexData::instanceIdMap; uint64 VertexData::instanceCount = 0; uint64 VertexData::meshletCount = 0; @@ -152,38 +153,17 @@ void VertexData::createDescriptors() { rayTracingScene.add(transparentData[i].rayTracingScene); } cullingOffsetBuffer->rotateBuffer(cullingOffsets.size() * sizeof(uint32)); - cullingOffsetBuffer->updateContents(ShaderBufferCreateInfo{ - .sourceData = - { - .size = cullingOffsets.size() * sizeof(uint32), - .data = (uint8*)cullingOffsets.data(), - }, - .numElements = cullingOffsets.size(), - }); + cullingOffsetBuffer->updateContents(0, cullingOffsets.size() * sizeof(uint32), cullingOffsets.data()); 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); instanceBuffer->rotateBuffer(instanceData.size() * sizeof(InstanceData)); - instanceBuffer->updateContents(ShaderBufferCreateInfo{ - .sourceData = - { - .size = instanceData.size() * sizeof(InstanceData), - .data = (uint8*)instanceData.data(), - }, - .numElements = instanceData.size(), - }); + instanceBuffer->updateContents(0, instanceData.size() * sizeof(InstanceData), instanceData.data()); instanceBuffer->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); instanceMeshDataBuffer->rotateBuffer(sizeof(MeshData) * instanceMeshData.size()); - instanceMeshDataBuffer->updateContents(ShaderBufferCreateInfo{ - .sourceData = - { - .size = sizeof(MeshData) * instanceMeshData.size(), - .data = (uint8*)instanceMeshData.data(), - }, - .numElements = instanceMeshData.size(), - }); + instanceMeshDataBuffer->updateContents(0, sizeof(MeshData) * instanceMeshData.size(), instanceMeshData.data()); instanceMeshDataBuffer->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); @@ -287,7 +267,8 @@ MeshId VertexData::allocateVertexData(uint64 numVertices) { meshData.add({}); head += numVertices; if (head > verticesAllocated) { - verticesAllocated = std::max(head, verticesAllocated + NUM_DEFAULT_ELEMENTS); + verticesAllocated = 2 * head; // double capacity + std::cout << "Resizing buffers to " << verticesAllocated << std::endl; resizeBuffers(); } return res; @@ -383,7 +364,6 @@ void VertexData::init(Gfx::PGraphics _graphics) { .dynamic = true, .name = "MeshDataBuffer", }); - resizeBuffers(); graphics->getShaderCompiler()->registerVertexData(this); } diff --git a/src/Engine/Graphics/Vulkan/Buffer.cpp b/src/Engine/Graphics/Vulkan/Buffer.cpp index 89b0adf..8fa4910 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.cpp +++ b/src/Engine/Graphics/Vulkan/Buffer.cpp @@ -2,13 +2,12 @@ #include "Command.h" #include "Enums.h" #include "Graphics/Enums.h" +#include #include -#include uint64 bufferSize = 0; -uint64 getBufferSize() -{ return bufferSize; } +uint64 getBufferSize() { return bufferSize; } using namespace Seele; using namespace Seele::Vulkan; @@ -186,12 +185,16 @@ void BufferAllocation::readContents(uint64 regionOffset, uint64 regionSize, void } void* BufferAllocation::map() { - void* data; - vmaMapMemory(graphics->getAllocator(), allocation, &data); - return data; + if (mappedPointer == nullptr) { + vmaMapMemory(graphics->getAllocator(), allocation, &mappedPointer); + } + return mappedPointer; } -void BufferAllocation::unmap() { vmaUnmapMemory(graphics->getAllocator(), allocation); } +void BufferAllocation::unmap() { + vmaUnmapMemory(graphics->getAllocator(), allocation); + mappedPointer = nullptr; +} Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType queueType, bool dynamic, std::string name, bool createCleared, uint32 clearValue) @@ -222,10 +225,52 @@ void Buffer::readContents(uint64 regionOffset, uint64 regionSize, void* buffer) getAlloc()->readContents(regionOffset, regionSize, buffer); } +void* Buffer::map() { + if (stagingBuffer == nullptr) { + stagingBuffer = new BufferAllocation(graphics, fmt::format("{}Staging", name), + VkBufferCreateInfo{ + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .size = getSize(), + .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + }, + VmaAllocationCreateInfo{ + .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, + .usage = VMA_MEMORY_USAGE_AUTO, + }, + Gfx::QueueType::GRAPHICS); + } + return stagingBuffer->map(); +} + +void Buffer::unmap() { + if (stagingBuffer == nullptr) + return; + stagingBuffer->unmap(); + + PCommand cmd = graphics->getQueueCommands(Gfx::QueueType::GRAPHICS)->getCommands(); + VkBufferCopy copy = { + .srcOffset = 0, + .dstOffset = 0, + .size = getSize(), + }; + cmd->bindResource(getAlloc()); + cmd->bindResource(PBufferAllocation(stagingBuffer)); + vkCmdCopyBuffer(cmd->getHandle(), stagingBuffer->buffer, getAlloc()->buffer, 1, ©); + pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT); + + // transferOwnership(prevOwner); + graphics->getDestructionManager()->queueResourceForDestruction(std::move(stagingBuffer)); + stagingBuffer = nullptr; +} + void Buffer::rotateBuffer(uint64 size, bool preserveContents) { if (size == 0) return; assert(dynamic); + unmap(); for (uint32 i = 0; i < buffers.size(); ++i) { if (buffers[i]->isCurrentlyBound()) { continue; @@ -353,10 +398,10 @@ UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo& UniformBuffer::~UniformBuffer() {} -void UniformBuffer::updateContents(const DataSource& sourceData) { - if (sourceData.size > 0 && sourceData.data != nullptr) { - rotateBuffer(sourceData.size); - getAlloc()->updateContents(sourceData.offset, sourceData.size, sourceData.data); +void UniformBuffer::updateContents(uint64 offset, uint64 size, void* data) { + if (size > 0 && data != nullptr) { + rotateBuffer(size); + getAlloc()->updateContents(offset, size, data); } } @@ -384,18 +429,15 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& cre ShaderBuffer::~ShaderBuffer() {} -void ShaderBuffer::readContents(Array& data) { - data.resize(getSize()); - getAlloc()->readContents(0, data.size(), data.data()); -} +void ShaderBuffer::readContents(uint64 offset, uint64 size, void* data) { getAlloc()->readContents(offset, size, data); } -void ShaderBuffer::updateContents(const ShaderBufferCreateInfo& createInfo) { - if (createInfo.sourceData.data == nullptr) { +void ShaderBuffer::updateContents(uint64 offset, uint64 size, void* data) { + if (data == nullptr) { return; } // We always want to update, as the contents could be different on the GPU - if (createInfo.sourceData.size > 0 && createInfo.sourceData.data != nullptr) { - getAlloc()->updateContents(createInfo.sourceData.offset, createInfo.sourceData.size, createInfo.sourceData.data); + if (size > 0 && data != nullptr) { + getAlloc()->updateContents(offset, size, data); } } @@ -404,11 +446,14 @@ void ShaderBuffer::rotateBuffer(uint64 size, bool preserveContents) { Vulkan::Buffer::rotateBuffer(size, preserveContents); } +void* ShaderBuffer::map() { return Vulkan::Buffer::map(); } + +void ShaderBuffer::unmap() { Vulkan::Buffer::unmap(); } + void ShaderBuffer::clear() { PCommand command = graphics->getQueueCommands(getAlloc()->owner)->getCommands(); command->bindResource(PBufferAllocation(getAlloc())); - vkCmdFillBuffer(command->getHandle(), Vulkan::Buffer::getHandle(), 0, - VK_WHOLE_SIZE, 0); + vkCmdFillBuffer(command->getHandle(), Vulkan::Buffer::getHandle(), 0, VK_WHOLE_SIZE, 0); } void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { Vulkan::Buffer::transferOwnership(newOwner); } @@ -429,7 +474,7 @@ VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo& cre VertexBuffer::~VertexBuffer() {} -void VertexBuffer::updateRegion(DataSource sourceData) { getAlloc()->updateContents(sourceData.offset, sourceData.size, sourceData.data); } +void VertexBuffer::updateRegion(uint64 offset, uint64 size, void* data) { getAlloc()->updateContents(offset, size, data); } void VertexBuffer::download(Array& buffer) { buffer.resize(getSize()); diff --git a/src/Engine/Graphics/Vulkan/Buffer.h b/src/Engine/Graphics/Vulkan/Buffer.h index 3137b23..e43fdb7 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.h +++ b/src/Engine/Graphics/Vulkan/Buffer.h @@ -26,6 +26,7 @@ class BufferAllocation : public CommandBoundResource { VmaAllocation allocation = VmaAllocation(); VmaAllocationInfo info = VmaAllocationInfo(); VkMemoryPropertyFlags properties = 0; + void* mappedPointer = nullptr; uint64 size = 0; VkDeviceAddress deviceAddress; Gfx::QueueType owner; @@ -42,12 +43,15 @@ class Buffer { uint64 getSize() const { return buffers[currentBuffer]->size; } void updateContents(uint64 regionOffset, uint64 regionSize, void* ptr); void readContents(uint64 regionOffset, uint64 regionSize, void* ptr); + void* map(); + void unmap(); protected: PGraphics graphics; uint32 currentBuffer; Gfx::QueueType initialOwner; Array buffers; + OBufferAllocation stagingBuffer = nullptr; VkBufferUsageFlags usage; bool dynamic; bool createCleared; @@ -67,7 +71,7 @@ class VertexBuffer : public Gfx::VertexBuffer, public Buffer { VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo& sourceData); virtual ~VertexBuffer(); - virtual void updateRegion(DataSource update) override; + virtual void updateRegion(uint64 offset, uint64 size, void* data) override; virtual void download(Array& buffer) override; protected: @@ -96,7 +100,7 @@ class UniformBuffer : public Gfx::UniformBuffer, public Buffer { public: UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo& sourceData); virtual ~UniformBuffer(); - virtual void updateContents(const DataSource& sourceData) override; + virtual void updateContents(uint64 offset, uint64 size, void* data) override; virtual void rotateBuffer(uint64 size) override; protected: @@ -113,9 +117,11 @@ class ShaderBuffer : public Gfx::ShaderBuffer, public Buffer { public: ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& sourceData); virtual ~ShaderBuffer(); - virtual void readContents(Array& data) override; - virtual void updateContents(const ShaderBufferCreateInfo& createInfo) override; + virtual void readContents(uint64 offset, uint64 size, void* data) override; + virtual void updateContents(uint64 offset, uint64 size, void* data) override; virtual void rotateBuffer(uint64 size, bool preserveContents = false) override; + virtual void* map() override; + virtual void unmap() override; virtual void clear() override; diff --git a/src/Engine/Material/Material.cpp b/src/Engine/Material/Material.cpp index 061a61f..92c1b7a 100644 --- a/src/Engine/Material/Material.cpp +++ b/src/Engine/Material/Material.cpp @@ -71,13 +71,7 @@ void Material::destroy() { void Material::updateDescriptor() { floatBuffer->rotateBuffer(floatData.size() * sizeof(float)); - floatBuffer->updateContents(ShaderBufferCreateInfo{ - .sourceData = - { - .size = floatData.size() * sizeof(float), - .data = (uint8*)floatData.data(), - }, - }); + floatBuffer->updateContents(0, floatData.size() * sizeof(float), floatData.data()); floatBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT); layout->reset(); diff --git a/src/Engine/Scene/LightEnvironment.cpp b/src/Engine/Scene/LightEnvironment.cpp index 40ca667..21f75fe 100644 --- a/src/Engine/Scene/LightEnvironment.cpp +++ b/src/Engine/Scene/LightEnvironment.cpp @@ -45,36 +45,19 @@ void LightEnvironment::addPointLight(Component::PointLight pointLight) { points. void LightEnvironment::commit() { lightEnv.numDirectionalLights = dirs.size(); lightEnv.numPointLights = points.size(); - lightEnvBuffer->updateContents(DataSource{ - .size = sizeof(LightEnv), - .data = (uint8*)&lightEnv, - }); + lightEnvBuffer->updateContents(0, sizeof(LightEnv), &lightEnv); lightEnvBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_UNIFORM_READ_BIT | Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR | Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT); directionalLights->rotateBuffer(sizeof(Component::DirectionalLight) * dirs.size()); - directionalLights->updateContents({ - .sourceData = - { - .size = sizeof(Component::DirectionalLight) * dirs.size(), - .data = (uint8*)dirs.data(), - }, - .numElements = dirs.size(), - }); + directionalLights->updateContents(0, sizeof(Component::DirectionalLight) * dirs.size(), dirs.data()); directionalLights->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR | Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT); pointLights->rotateBuffer(sizeof(Component::PointLight) * points.size()); - pointLights->updateContents({ - .sourceData = - { - .size = sizeof(Component::PointLight) * points.size(), - .data = (uint8*)points.data(), - }, - .numElements = points.size(), - }); + pointLights->updateContents(0, sizeof(Component::PointLight) * points.size(), points.data()); pointLights->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT |