diff --git a/res/shaders/lib/StaticMeshVertexData.slang b/res/shaders/lib/StaticMeshVertexData.slang index b28478c..c99d06c 100644 --- a/res/shaders/lib/StaticMeshVertexData.slang +++ b/res/shaders/lib/StaticMeshVertexData.slang @@ -7,27 +7,27 @@ struct StaticMeshVertexData : IVertexData VertexAttributes getAttributes(uint index) { VertexAttributes attributes; - attributes.position_MS = float3(positions[3 * index + 0], positions[3 * index + 1], positions[3 * index + 2]); - attributes.normal_MS = float3(normals[3 * index + 0], normals[3 * index + 1], normals[3 * index + 2]); - attributes.tangent_MS = float3(tangents[3 * index + 0], tangents[3 * index + 1], tangents[3 * index + 2]); - attributes.biTangent_MS = float3(biTangents[3 * index + 0], biTangents[3 * index + 1], biTangents[3 * index + 2]); + attributes.position_MS = positions[index].xyz; + attributes.normal_MS = normals[index].xyz; + attributes.tangent_MS = tangents[index].xyz; + attributes.biTangent_MS = biTangents[index].xyz; for(uint i = 0; i < MAX_TEXCOORDS; ++i) { - attributes.texCoords[i] = float2(texCoords[i][2 * index + 0], texCoords[i][2 * index + 1]); + attributes.texCoords[i] = texCoords[i][index]; } - attributes.vertexColor = float3(color[3 * index + 0], color[3 * index + 1], color[3 * index + 2]); + attributes.vertexColor = color[index].xyz; return attributes; } VertexAttributes getPosition(uint index) { VertexAttributes attributes; - attributes.position_MS = float3(positions[3 * index + 0], positions[3 * index + 1], positions[3 * index + 2]); + attributes.position_MS = positions[index].xyz; return attributes; } - StructuredBuffer positions; - StructuredBuffer normals; - StructuredBuffer tangents; - StructuredBuffer biTangents; - StructuredBuffer color; - StructuredBuffer texCoords[MAX_TEXCOORDS]; + StructuredBuffer positions; + StructuredBuffer normals; + StructuredBuffer tangents; + StructuredBuffer biTangents; + StructuredBuffer color; + StructuredBuffer texCoords[MAX_TEXCOORDS]; }; diff --git a/src/Editor/Asset/MeshLoader.cpp b/src/Editor/Asset/MeshLoader.cpp index fe376e7..9794d61 100644 --- a/src/Editor/Asset/MeshLoader.cpp +++ b/src/Editor/Asset/MeshLoader.cpp @@ -432,19 +432,19 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const ArraymAABB.mMax.x, mesh->mAABB.mMax.y, mesh->mAABB.mMax.z)); // assume static mesh for now - Array positions(mesh->mNumVertices); + Array positions(mesh->mNumVertices); StaticArray, MAX_TEXCOORDS> texCoords; for (size_t i = 0; i < MAX_TEXCOORDS; ++i) { texCoords[i].resize(mesh->mNumVertices); } - Array normals(mesh->mNumVertices); - Array tangents(mesh->mNumVertices); - Array biTangents(mesh->mNumVertices); - Array colors(mesh->mNumVertices); + Array normals(mesh->mNumVertices); + Array tangents(mesh->mNumVertices); + Array biTangents(mesh->mNumVertices); + Array colors(mesh->mNumVertices); StaticMeshVertexData* vertexData = StaticMeshVertexData::getInstance(); for (int32 i = 0; i < mesh->mNumVertices; ++i) { - positions[i] = Vector(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z); + positions[i] = Vector4(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z, 1.0f); for (size_t j = 0; j < MAX_TEXCOORDS; ++j) { if (mesh->HasTextureCoords(j)) { texCoords[j][i] = Vector2(mesh->mTextureCoords[j][i].x, mesh->mTextureCoords[j][i].y); @@ -452,18 +452,18 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const ArraymNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z); + normals[i] = Vector4(mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z, 1.0f); if (mesh->HasTangentsAndBitangents()) { - tangents[i] = Vector(mesh->mTangents[i].x, mesh->mTangents[i].y, mesh->mTangents[i].z); - biTangents[i] = Vector(mesh->mBitangents[i].x, mesh->mBitangents[i].y, mesh->mBitangents[i].z); + tangents[i] = Vector4(mesh->mTangents[i].x, mesh->mTangents[i].y, mesh->mTangents[i].z, 1.0f); + biTangents[i] = Vector4(mesh->mBitangents[i].x, mesh->mBitangents[i].y, mesh->mBitangents[i].z, 1.0f); } else { - tangents[i] = Vector(0, 0, 1); - biTangents[i] = Vector(1, 0, 0); + tangents[i] = Vector4(0, 0, 1, 1); + biTangents[i] = Vector4(1, 0, 0, 1); } if (mesh->HasVertexColors(0)) { - colors[i] = Vector(mesh->mColors[0][i].r, mesh->mColors[0][i].g, mesh->mColors[0][i].b); + colors[i] = Vector4(mesh->mColors[0][i].r, mesh->mColors[0][i].g, mesh->mColors[0][i].b, 1.0f); } else { - colors[i] = Vector(1, 1, 1); + colors[i] = Vector4(1, 1, 1, 1); } } MeshId id = vertexData->allocateVertexData(mesh->mNumVertices); diff --git a/src/Engine/Graphics/Buffer.h b/src/Engine/Graphics/Buffer.h index e582728..7d4d340 100644 --- a/src/Engine/Graphics/Buffer.h +++ b/src/Engine/Graphics/Buffer.h @@ -79,8 +79,6 @@ class ShaderBuffer : public Buffer { virtual void rotateBuffer(uint64 size, bool preserveContents = false) = 0; 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; - virtual void unmap() = 0; virtual void clear() = 0; diff --git a/src/Engine/Graphics/Meshlet.cpp b/src/Engine/Graphics/Meshlet.cpp index dc5e43e..2653c0f 100644 --- a/src/Engine/Graphics/Meshlet.cpp +++ b/src/Engine/Graphics/Meshlet.cpp @@ -166,7 +166,7 @@ void completeMeshlet(Array& meshlets, Meshlet& current) { }; } -bool addTriangle(const Array& positions, Meshlet& current, Triangle& tri) { +bool addTriangle(const Array& positions, Meshlet& current, Triangle& tri) { int f1 = findIndex(current, tri.indices[0]); int f2 = findIndex(current, tri.indices[1]); int f3 = findIndex(current, tri.indices[2]); @@ -184,7 +184,7 @@ bool addTriangle(const Array& positions, Meshlet& current, Triangle& tri return true; } -void Meshlet::build(const Array& positions, const Array& indices, Array& meshlets) { +void Meshlet::build(const Array& positions, const Array& indices, Array& meshlets) { Meshlet current = { .numVertices = 0, .numPrimitives = 0, diff --git a/src/Engine/Graphics/Meshlet.h b/src/Engine/Graphics/Meshlet.h index 304bd75..ab44ff0 100644 --- a/src/Engine/Graphics/Meshlet.h +++ b/src/Engine/Graphics/Meshlet.h @@ -10,6 +10,6 @@ struct Meshlet { uint8 primitiveLayout[Gfx::numPrimitivesPerMeshlet * 3]; // indices into the uniqueVertices array, only uint8 needed uint32 numVertices; uint32 numPrimitives; - static void build(const Array& positions, const Array& indices, Array& meshlets); + static void build(const Array& positions, const Array& indices, Array& meshlets); }; } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp b/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp index fccef3b..f16cbf6 100644 --- a/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp +++ b/src/Engine/Graphics/RenderPass/CachedDepthPass.cpp @@ -45,11 +45,7 @@ CachedDepthPass::~CachedDepthPass() {} void CachedDepthPass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); } -uint64 numFragments = 0; - void CachedDepthPass::render() { - occlusionQuery->resetQuery(); - occlusionQuery->beginQuery(); graphics->beginRenderPass(renderPass); Array commands; @@ -145,14 +141,11 @@ void CachedDepthPass::render() { graphics->executeCommands(std::move(commands)); graphics->endRenderPass(); - occlusionQuery->endQuery(); - numFragments = occlusionQuery->getResults(); } void CachedDepthPass::endFrame() {} void CachedDepthPass::publishOutputs() { - occlusionQuery = graphics->createOcclusionQuery(); // If we render to a part of an image, the depth buffer itself must // still match the size of the whole image or their coordinate systems go out of sync TextureCreateInfo depthBufferInfo = { diff --git a/src/Engine/Graphics/RenderPass/CachedDepthPass.h b/src/Engine/Graphics/RenderPass/CachedDepthPass.h index f4ba186..4290819 100644 --- a/src/Engine/Graphics/RenderPass/CachedDepthPass.h +++ b/src/Engine/Graphics/RenderPass/CachedDepthPass.h @@ -22,7 +22,6 @@ class CachedDepthPass : public RenderPass { Gfx::OTexture2D visibilityBuffer; Gfx::OPipelineLayout depthPrepassLayout; - Gfx::OOcclusionQuery occlusionQuery; Gfx::PShaderBuffer cullingBuffer; }; DEFINE_REF(CachedDepthPass) diff --git a/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp b/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp index 83babd6..74752a9 100644 --- a/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthCullingPass.cpp @@ -54,8 +54,6 @@ DepthCullingPass::~DepthCullingPass() {} void DepthCullingPass::beginFrame(const Component::Camera& cam) { RenderPass::beginFrame(cam); } -extern uint64 numFragments; - void DepthCullingPass::render() { depthAttachment.getTexture()->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, Gfx::SE_ACCESS_TRANSFER_READ_BIT, @@ -78,8 +76,6 @@ void DepthCullingPass::render() { set->updateTexture(0, Gfx::PTexture2D(depthMipTexture)); set->writeChanges(); - occlusionQuery->resetQuery(); - occlusionQuery->beginQuery(); graphics->beginRenderPass(renderPass); if (useDepthCulling) { @@ -177,8 +173,6 @@ void DepthCullingPass::render() { graphics->executeCommands(std::move(commands)); } graphics->endRenderPass(); - occlusionQuery->endQuery(); - std::cout << "Occlusion fragments: " << occlusionQuery->getResults() + numFragments << std::endl; // Sync depth read/write with compute read depthAttachment.getTexture()->pipelineBarrier( Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, @@ -192,8 +186,6 @@ void DepthCullingPass::render() { void DepthCullingPass::endFrame() {} void DepthCullingPass::publishOutputs() { - occlusionQuery = graphics->createOcclusionQuery(); - uint32 width = viewport->getOwner()->getFramebufferWidth(); uint32 height = viewport->getOwner()->getFramebufferHeight(); uint32 mipLevels = static_cast(std::floor(std::log2(std::max(width, height)))) + 1; diff --git a/src/Engine/Graphics/RenderPass/DepthCullingPass.h b/src/Engine/Graphics/RenderPass/DepthCullingPass.h index 90f20f8..2470b18 100644 --- a/src/Engine/Graphics/RenderPass/DepthCullingPass.h +++ b/src/Engine/Graphics/RenderPass/DepthCullingPass.h @@ -23,7 +23,6 @@ class DepthCullingPass : public RenderPass { Gfx::ODescriptorLayout depthTextureLayout; Gfx::OPipelineLayout depthPrepassLayout; - Gfx::OOcclusionQuery occlusionQuery; Gfx::PShaderBuffer cullingBuffer; }; DEFINE_REF(DepthCullingPass) diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp index e893df9..4a751b1 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -6,7 +6,6 @@ #include "RenderGraph.h" #include "Scene/Scene.h" - using namespace Seele; extern bool useLightCulling; @@ -184,10 +183,13 @@ void LightCullingPass::publishOutputs() { structInfo.name = "tLightIndexCounter"; tLightIndexCounter = graphics->createShaderBuffer(structInfo); structInfo = { - .sourceData = {.size = (uint32)sizeof(uint32) * dispatchParams.numThreadGroups.x * dispatchParams.numThreadGroups.y * - dispatchParams.numThreadGroups.z * 8192, - .data = nullptr, - .owner = Gfx::QueueType::COMPUTE}, + .sourceData = + { + .size = (uint32)sizeof(uint32) * dispatchParams.numThreadGroups.x * dispatchParams.numThreadGroups.y * + dispatchParams.numThreadGroups.z * 8192, + .data = nullptr, + .owner = Gfx::QueueType::COMPUTE, + }, .dynamic = false, .name = "oLightIndexList", }; @@ -229,7 +231,10 @@ void LightCullingPass::setupFrustums() { .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER, }); dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{ - .binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .access = Gfx::SE_DESCRIPTOR_ACCESS_WRITE_ONLY_BIT}); + .binding = 1, + .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .access = Gfx::SE_DESCRIPTOR_ACCESS_WRITE_ONLY_BIT, + }); frustumLayout = graphics->createPipelineLayout("FrustumLayout"); frustumLayout->addDescriptorLayout(viewParamsLayout); frustumLayout->addDescriptorLayout(dispatchParamsLayout); @@ -251,17 +256,27 @@ void LightCullingPass::setupFrustums() { frustumPipeline = graphics->createComputePipeline(pipelineInfo); Gfx::OUniformBuffer frustumDispatchParamsBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{ - .sourceData = {.size = sizeof(DispatchParams), .data = (uint8*)&dispatchParams, .owner = Gfx::QueueType::COMPUTE}, + .sourceData = + { + .size = sizeof(DispatchParams), + .data = (uint8*)&dispatchParams, + .owner = Gfx::QueueType::COMPUTE, + }, .dynamic = false, - .name = "FrustumDispatch"}); + .name = "FrustumDispatch", + }); - frustumBuffer = graphics->createShaderBuffer( - ShaderBufferCreateInfo{.sourceData = {.size = sizeof(Frustum) * numThreads.x * numThreads.y * numThreads.z, - .data = nullptr, - .owner = Gfx::QueueType::COMPUTE}, - .numElements = numThreads.x * numThreads.y * numThreads.z, - .dynamic = false, - .name = "FrustumBuffer"}); + frustumBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ + .sourceData = + { + .size = sizeof(Frustum) * numThreads.x * numThreads.y * numThreads.z, + .data = nullptr, + .owner = Gfx::QueueType::COMPUTE, + }, + .numElements = numThreads.x * numThreads.y * numThreads.z, + .dynamic = false, + .name = "FrustumBuffer", + }); Gfx::PDescriptorSet dispatchParamsSet = dispatchParamsLayout->allocateDescriptorSet(); dispatchParamsSet->updateBuffer(0, frustumDispatchParamsBuffer); diff --git a/src/Engine/Graphics/RenderPass/VisibilityPass.cpp b/src/Engine/Graphics/RenderPass/VisibilityPass.cpp index 7afc1e4..cb176c7 100644 --- a/src/Engine/Graphics/RenderPass/VisibilityPass.cpp +++ b/src/Engine/Graphics/RenderPass/VisibilityPass.cpp @@ -34,7 +34,6 @@ void VisibilityPass::render() { Array commands; commands.add(std::move(command)); graphics->executeCommands(std::move(commands)); - 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); diff --git a/src/Engine/Graphics/StaticMeshVertexData.cpp b/src/Engine/Graphics/StaticMeshVertexData.cpp index bb445cf..994c635 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.cpp +++ b/src/Engine/Graphics/StaticMeshVertexData.cpp @@ -16,14 +16,14 @@ StaticMeshVertexData* StaticMeshVertexData::getInstance() { return &instance; } -void StaticMeshVertexData::loadPositions(MeshId id, const Array& data) { +void StaticMeshVertexData::loadPositions(MeshId id, const Array& data) { uint64 offset; { std::unique_lock l(mutex); offset = meshOffsets[id]; } assert(offset + data.size() <= head); - std::memcpy(positionData.data() + offset, data.data(), data.size() * sizeof(Vector)); + std::memcpy(positionData.data() + offset, data.data(), data.size() * sizeof(Vector4)); dirty = true; } @@ -38,47 +38,47 @@ void StaticMeshVertexData::loadTexCoords(MeshId id, uint64 index, const Array& data) { +void StaticMeshVertexData::loadNormals(MeshId id, const Array& data) { uint64 offset; { std::unique_lock l(mutex); offset = meshOffsets[id]; } assert(offset + data.size() <= head); - std::memcpy(normalData.data() + offset, data.data(), data.size() * sizeof(Vector)); + std::memcpy(normalData.data() + offset, data.data(), data.size() * sizeof(Vector4)); dirty = true; } -void StaticMeshVertexData::loadTangents(MeshId id, const Array& data) { +void StaticMeshVertexData::loadTangents(MeshId id, const Array& data) { uint64 offset; { std::unique_lock l(mutex); offset = meshOffsets[id]; } assert(offset + data.size() <= head); - std::memcpy(tangentData.data() + offset, data.data(), data.size() * sizeof(Vector)); + std::memcpy(tangentData.data() + offset, data.data(), data.size() * sizeof(Vector4)); dirty = true; } -void StaticMeshVertexData::loadBiTangents(MeshId id, const Array& data) { +void StaticMeshVertexData::loadBiTangents(MeshId id, const Array& data) { uint64 offset; { std::unique_lock l(mutex); offset = meshOffsets[id]; } assert(offset + data.size() <= head); - std::memcpy(biTangentData.data() + offset, data.data(), data.size() * sizeof(Vector)); + std::memcpy(biTangentData.data() + offset, data.data(), data.size() * sizeof(Vector4)); dirty = true; } -void Seele::StaticMeshVertexData::loadColors(MeshId id, const Array& data) { +void Seele::StaticMeshVertexData::loadColors(MeshId id, const Array& data) { uint64 offset; { std::unique_lock l(mutex); offset = meshOffsets[id]; } assert(offset + data.size() <= head); - std::memcpy(colorData.data() + offset, data.data(), data.size() * sizeof(Vector)); + std::memcpy(colorData.data() + offset, data.data(), data.size() * sizeof(Vector4)); dirty = true; } @@ -88,22 +88,22 @@ void StaticMeshVertexData::serializeMesh(MeshId id, uint64 numVertices, ArchiveB std::unique_lock l(mutex); offset = meshOffsets[id]; } - Array pos(numVertices); + Array pos(numVertices); 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)); 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(Vector)); - std::memcpy(nor.data(), normalData.data() + offset, numVertices * sizeof(Vector)); - std::memcpy(tan.data(), tangentData.data() + offset, numVertices * sizeof(Vector)); - std::memcpy(bit.data(), biTangentData.data() + offset, numVertices * sizeof(Vector)); - std::memcpy(col.data(), colorData.data() + offset, numVertices * sizeof(Vector)); + 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)); Serialization::save(buffer, pos); Serialization::save(buffer, nor); Serialization::save(buffer, tan); @@ -112,16 +112,16 @@ void StaticMeshVertexData::serializeMesh(MeshId id, uint64 numVertices, ArchiveB } void StaticMeshVertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) { - Array pos; + Array pos; Array tex[MAX_TEXCOORDS]; for (size_t i = 0; i < MAX_TEXCOORDS; ++i) { Serialization::load(buffer, tex[i]); loadTexCoords(id, i, tex[i]); } - Array nor; - Array tan; - Array bit; - Array col; + Array nor; + Array tan; + Array bit; + Array col; Serialization::load(buffer, pos); Serialization::load(buffer, nor); Serialization::load(buffer, tan); @@ -143,7 +143,7 @@ void StaticMeshVertexData::init(Gfx::PGraphics _graphics) { 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}); + Gfx::DescriptorBinding{.binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .descriptorCount = MAX_TEXCOORDS,}); descriptorLayout->create(); descriptorSet = descriptorLayout->allocateDescriptorSet(); } @@ -173,9 +173,9 @@ void StaticMeshVertexData::resizeBuffers() { ShaderBufferCreateInfo createInfo = { .sourceData = { - .size = verticesAllocated * sizeof(Vector), + .size = verticesAllocated * sizeof(Vector4), }, - .numElements = verticesAllocated * 3, + .numElements = verticesAllocated, .dynamic = false, .vertexBuffer = 1, .name = "Positions", @@ -192,7 +192,6 @@ void StaticMeshVertexData::resizeBuffers() { colors = graphics->createShaderBuffer(createInfo); createInfo.sourceData.size = verticesAllocated * sizeof(Vector2); createInfo.name = "TexCoords"; - createInfo.numElements = verticesAllocated * 2; for (size_t i = 0; i < MAX_TEXCOORDS; ++i) { texCoords[i] = graphics->createShaderBuffer(createInfo); texCoordsData[i].resize(verticesAllocated); @@ -208,7 +207,7 @@ void StaticMeshVertexData::resizeBuffers() { void StaticMeshVertexData::updateBuffers() { positions->updateContents(ShaderBufferCreateInfo{ .sourceData{ - .size = positionData.size() * sizeof(Vector), + .size = positionData.size() * sizeof(Vector4), .data = (uint8*)positionData.data(), }, .numElements = positionData.size(), @@ -226,27 +225,33 @@ void StaticMeshVertexData::updateBuffers() { normals->updateContents(ShaderBufferCreateInfo{ .sourceData = { - .size = normalData.size() * sizeof(Vector), + .size = normalData.size() * sizeof(Vector4), .data = (uint8*)normalData.data(), }, .numElements = normalData.size(), }); - tangents->updateContents(ShaderBufferCreateInfo{.sourceData = - { - .size = tangentData.size() * sizeof(Vector), - .data = (uint8*)tangentData.data(), - }, - .numElements = tangentData.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(Vector), + .size = biTangentData.size() * sizeof(Vector4), .data = (uint8*)biTangentData.data(), }, .numElements = biTangentData.size(), }); colors->updateContents(ShaderBufferCreateInfo{ - .sourceData = {.size = colorData.size() * sizeof(Vector), .data = (uint8*)colorData.data()}, + .sourceData = + { + .size = colorData.size() * sizeof(Vector4), + .data = (uint8*)colorData.data(), + }, .numElements = colorData.size(), }); descriptorLayout->reset(); diff --git a/src/Engine/Graphics/StaticMeshVertexData.h b/src/Engine/Graphics/StaticMeshVertexData.h index 6b01f6f..268ad90 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.h +++ b/src/Engine/Graphics/StaticMeshVertexData.h @@ -22,12 +22,12 @@ class StaticMeshVertexData : public VertexData { StaticMeshVertexData(); virtual ~StaticMeshVertexData(); static StaticMeshVertexData* getInstance(); - void loadPositions(MeshId id, const Array& data); + void loadPositions(MeshId id, const Array& data); void loadTexCoords(MeshId id, uint64 index, const Array& data); - void loadNormals(MeshId id, const Array& data); - void loadTangents(MeshId id, const Array& data); - void loadBiTangents(MeshId id, const Array& data); - void loadColors(MeshId id, const Array& data); + void loadNormals(MeshId id, const Array& data); + void loadTangents(MeshId id, const Array& data); + void loadBiTangents(MeshId id, const Array& data); + void loadColors(MeshId id, const Array& data); virtual void serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer) override; virtual void deserializeMesh(MeshId id, ArchiveBuffer& buffer) override; virtual void init(Gfx::PGraphics graphics) override; @@ -37,7 +37,6 @@ class StaticMeshVertexData : public VertexData { virtual Gfx::PDescriptorSet getVertexDataSet() override; virtual std::string getTypeName() const override { return "StaticMeshVertexData"; } virtual Gfx::PShaderBuffer getPositionBuffer() const override { return positions; } - virtual Vector* getPositionData() const override { return positionData.data(); } constexpr const Array& getStaticMeshes() const { return staticData; } private: @@ -47,17 +46,17 @@ class StaticMeshVertexData : public VertexData { std::mutex mutex; Gfx::OShaderBuffer positions; - Array positionData; + Array positionData; Gfx::OShaderBuffer texCoords[MAX_TEXCOORDS]; Array texCoordsData[MAX_TEXCOORDS]; Gfx::OShaderBuffer normals; - Array normalData; + Array normalData; Gfx::OShaderBuffer tangents; - Array tangentData; + Array tangentData; Gfx::OShaderBuffer biTangents; - Array biTangentData; + Array biTangentData; Gfx::OShaderBuffer colors; - Array colorData; + Array colorData; Gfx::ODescriptorLayout descriptorLayout; Gfx::PDescriptorSet descriptorSet; }; diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index fa7dc1f..57e168b 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -8,7 +8,6 @@ #include "Material/Material.h" #include "Material/MaterialInstance.h" - using namespace Seele; constexpr static uint64 NUM_DEFAULT_ELEMENTS = 1024 * 1024; @@ -120,32 +119,38 @@ void VertexData::createDescriptors() { } } cullingOffsetBuffer->rotateBuffer(cullingOffsets.size() * sizeof(uint32)); - cullingOffsetBuffer->updateContents(ShaderBufferCreateInfo{.sourceData = - { - .size = cullingOffsets.size() * sizeof(uint32), - .data = (uint8*)cullingOffsets.data(), - }, - .numElements = cullingOffsets.size()}); + 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); instanceBuffer->rotateBuffer(instanceData.size() * sizeof(InstanceData)); - instanceBuffer->updateContents(ShaderBufferCreateInfo{.sourceData = - { - .size = instanceData.size() * sizeof(InstanceData), - .data = (uint8*)instanceData.data(), - }, - .numElements = instanceData.size()}); + instanceBuffer->updateContents(ShaderBufferCreateInfo{ + .sourceData = + { + .size = instanceData.size() * sizeof(InstanceData), + .data = (uint8*)instanceData.data(), + }, + .numElements = instanceData.size(), + }); 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(ShaderBufferCreateInfo{ + .sourceData = + { + .size = sizeof(MeshData) * instanceMeshData.size(), + .data = (uint8*)instanceMeshData.data(), + }, + .numElements = instanceMeshData.size(), + }); 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); instanceDataLayout->reset(); diff --git a/src/Engine/Graphics/VertexData.h b/src/Engine/Graphics/VertexData.h index 4768553..5883b7a 100644 --- a/src/Engine/Graphics/VertexData.h +++ b/src/Engine/Graphics/VertexData.h @@ -52,7 +52,6 @@ class VertexData { virtual Gfx::PDescriptorSet getVertexDataSet() = 0; virtual std::string getTypeName() const = 0; virtual Gfx::PShaderBuffer getPositionBuffer() const = 0; - virtual Vector* getPositionData() const = 0; Gfx::PIndexBuffer getIndexBuffer() const { return indexBuffer; } uint32* getIndexData() const { return indices.data(); } Gfx::PDescriptorLayout getInstanceDataLayout() { return instanceDataLayout; } diff --git a/src/Engine/Graphics/Vulkan/Buffer.cpp b/src/Engine/Graphics/Vulkan/Buffer.cpp index c17ceb8..fef5fe0 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.cpp +++ b/src/Engine/Graphics/Vulkan/Buffer.cpp @@ -2,31 +2,33 @@ #include "Command.h" #include "Enums.h" #include "Graphics/Enums.h" +#include #include using namespace Seele; using namespace Seele::Vulkan; -struct PendingBuffer { - OBufferAllocation allocation; - uint64 offset; - Gfx::QueueType prevQueue; - bool writeOnly; -}; - -static Map pendingBuffers; - -BufferAllocation::BufferAllocation(PGraphics graphics, VkBufferCreateInfo bufferInfo, VmaAllocationCreateInfo allocInfo, - Gfx::QueueType owner) +BufferAllocation::BufferAllocation(PGraphics graphics, const std::string& name, VkBufferCreateInfo bufferInfo, + VmaAllocationCreateInfo allocInfo, Gfx::QueueType owner, uint64 alignment) : CommandBoundResource(graphics), size(bufferInfo.size), owner(owner) { - VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &bufferInfo, &allocInfo, &buffer, &allocation, nullptr)); + VK_CHECK(vmaCreateBufferWithAlignment(graphics->getAllocator(), &bufferInfo, &allocInfo, alignment, &buffer, &allocation, nullptr)); vmaGetAllocationMemoryProperties(graphics->getAllocator(), allocation, &properties); - VkBufferDeviceAddressInfo addrInfo = { - .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR, + VkDebugUtilsObjectNameInfoEXT nameInfo = { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, .pNext = nullptr, - .buffer = buffer, + .objectType = VK_OBJECT_TYPE_BUFFER, + .objectHandle = (uint64)buffer, + .pObjectName = name.c_str(), }; - deviceAddress = vkGetBufferDeviceAddress(graphics->getDevice(), &addrInfo); + vkSetDebugUtilsObjectNameEXT(graphics->getDevice(), &nameInfo); + if (bufferInfo.usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) { + VkBufferDeviceAddressInfo addrInfo = { + .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR, + .pNext = nullptr, + .buffer = buffer, + }; + deviceAddress = vkGetBufferDeviceAddress(graphics->getDevice(), &addrInfo); + } } BufferAllocation::~BufferAllocation() { @@ -58,6 +60,8 @@ void BufferAllocation::transferOwnership(Gfx::QueueType newOwner) { if (size == 0) return; Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping(); + if (mapping.getQueueTypeFamilyIndex(newOwner) == mapping.getQueueTypeFamilyIndex(owner)) + return; VkBufferMemoryBarrier barrier = { .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, .pNext = nullptr, @@ -80,98 +84,91 @@ void BufferAllocation::transferOwnership(Gfx::QueueType newOwner) { owner = newOwner; } -void* BufferAllocation::mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly) { - void* data = nullptr; - PendingBuffer pending; - pending.writeOnly = writeOnly; - pending.prevQueue = owner; - pending.offset = regionOffset; +void BufferAllocation::updateContents(uint64 regionOffset, uint64 regionSize, void* ptr) { + if (regionSize == 0) + return; + VkBufferCreateInfo stagingInfo = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .size = regionSize, + .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + }; + VmaAllocationCreateInfo stagingAlloc = { + .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT, + .usage = VMA_MEMORY_USAGE_AUTO, + }; + OBufferAllocation staging = new BufferAllocation(graphics, "UpdateStaging", stagingInfo, stagingAlloc, Gfx::QueueType::TRANSFER); + + uint8* data; + VK_CHECK(vmaMapMemory(graphics->getAllocator(), staging->allocation, (void**)&data)); + std::memcpy(data, ptr, regionSize); + VK_CHECK(vmaFlushAllocation(graphics->getAllocator(), staging->allocation, 0, regionSize)); + vmaUnmapMemory(graphics->getAllocator(), staging->allocation); + + Gfx::QueueType prevOwner = owner; transferOwnership(Gfx::QueueType::TRANSFER); - if (writeOnly) { - if (properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { - VK_CHECK(vmaMapMemory(graphics->getAllocator(), allocation, &data)); - } else { - VkBufferCreateInfo stagingInfo = { - .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .size = regionSize, - .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - .sharingMode = VK_SHARING_MODE_EXCLUSIVE, - }; - VmaAllocationCreateInfo allocInfo = { - .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT, - .usage = VMA_MEMORY_USAGE_AUTO, - .requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, - }; - pending.allocation = new BufferAllocation(graphics, stagingInfo, allocInfo, Gfx::QueueType::TRANSFER); - vmaMapMemory(graphics->getAllocator(), pending.allocation->allocation, &data); - vmaSetAllocationName(graphics->getAllocator(), pending.allocation->allocation, "MappingStaging"); - } - } else { - assert(false); - } - pendingBuffers[this] = std::move(pending); - return data; + + PCommand cmd = graphics->getQueueCommands(Gfx::QueueType::TRANSFER)->getCommands(); + VkBufferCopy copy = { + .srcOffset = 0, + .dstOffset = regionOffset, + .size = regionSize, + }; + vkCmdCopyBuffer(cmd->getHandle(), staging->buffer, buffer, 1, ©); + cmd->bindResource(PBufferAllocation(this)); + cmd->bindResource(PBufferAllocation(staging)); + + transferOwnership(prevOwner); + graphics->getDestructionManager()->queueResourceForDestruction(std::move(staging)); } -void BufferAllocation::unmap() { - auto found = pendingBuffers.find(this); - if (found != pendingBuffers.end()) { - PendingBuffer& pending = found->value; - if (pending.writeOnly) { - if (properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { - vmaUnmapMemory(graphics->getAllocator(), allocation); - } else { - vmaFlushAllocation(graphics->getAllocator(), pending.allocation->allocation, 0, VK_WHOLE_SIZE); - vmaUnmapMemory(graphics->getAllocator(), pending.allocation->allocation); - PCommand command = graphics->getQueueCommands(owner)->getCommands(); - command->bindResource(PBufferAllocation(pending.allocation)); - VkCommandBuffer cmdHandle = command->getHandle(); +void BufferAllocation::readContents(uint64 regionOffset, uint64 regionSize, void* ptr) { + if (regionSize == 0) + return; - VkBufferCopy region = { - .srcOffset = 0, - .dstOffset = pending.offset, - .size = pending.allocation->size, - }; - VkBufferMemoryBarrier barrier = { - .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = VK_ACCESS_MEMORY_READ_BIT, - .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .buffer = buffer, - .offset = 0, - .size = size, - }; - vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, - &barrier, 0, nullptr); - vkCmdCopyBuffer(cmdHandle, pending.allocation->buffer, buffer, 1, ®ion); - barrier = { - .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, - .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .buffer = buffer, - .offset = 0, - .size = size, - }; - vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 1, - &barrier, 0, nullptr); - graphics->getDestructionManager()->queueResourceForDestruction(std::move(pending.allocation)); - } - } - transferOwnership(pending.prevQueue); - pendingBuffers.erase(this); - } + VkBufferCreateInfo stagingInfo = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .size = regionSize, + .usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT, + }; + VmaAllocationCreateInfo stagingAlloc = { + .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT, + .usage = VMA_MEMORY_USAGE_AUTO, + }; + OBufferAllocation staging = new BufferAllocation(graphics, "ReadStaging", stagingInfo, stagingAlloc, Gfx::QueueType::TRANSFER); + + Gfx::QueueType prevOwner = owner; + transferOwnership(Gfx::QueueType::TRANSFER); + + PCommandPool pool = graphics->getQueueCommands(Gfx::QueueType::TRANSFER); + PCommand cmd = pool->getCommands(); + VkBufferCopy copy = { + .srcOffset = regionOffset, + .dstOffset = 0, + .size = regionSize, + }; + vkCmdCopyBuffer(cmd->getHandle(), buffer, staging->buffer, 1, ©); + cmd->bindResource(PBufferAllocation(this)); + cmd->bindResource(PBufferAllocation(staging)); + pool->submitCommands(); + cmd->getFence()->wait(1000000); + + transferOwnership(prevOwner); + + uint8* data; + VK_CHECK(vmaMapMemory(graphics->getAllocator(), staging->allocation, (void**)&data)); + std::memcpy(buffer, data + regionOffset, regionSize); + VK_CHECK(vmaFlushAllocation(graphics->getAllocator(), staging->allocation, regionOffset, regionSize)); + vmaUnmapMemory(graphics->getAllocator(), staging->allocation); + graphics->getDestructionManager()->queueResourceForDestruction(std::move(staging)); } Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType queueType, bool dynamic, std::string name) : graphics(graphics), currentBuffer(0), initialOwner(queueType), - usage(usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT), + usage(usage | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT), dynamic(dynamic), name(name) { createBuffer(size); } @@ -182,27 +179,25 @@ Buffer::~Buffer() { } } -void* Buffer::map(bool writeOnly) { return mapRegion(0, getSize(), writeOnly); } - -void* Buffer::mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly) { - if (regionSize == 0) - return nullptr; - void* data = getAlloc()->mapRegion(regionOffset, regionSize, writeOnly); - assert(data); - return data; +void Buffer::updateContents(uint64 regionOffset, uint64 regionSize, void* buffer) { + getAlloc()->updateContents(regionOffset, regionSize, buffer); } -void Buffer::unmap() { getAlloc()->unmap(); } +void Buffer::readContents(uint64 regionOffset, uint64 regionSize, void* buffer) { + getAlloc()->readContents(regionOffset, regionSize, buffer); +} void Buffer::rotateBuffer(uint64 size, bool preserveContents) { assert(dynamic); - size = std::max(getSize(), size); + if (buffers.size() > 0) { + size = std::max(getSize(), size); + } for (uint32 i = 0; i < buffers.size(); ++i) { if (buffers[i]->isCurrentlyBound()) { continue; } if (buffers[i]->size < size) { - vmaDestroyBuffer(graphics->getAllocator(), buffers[i]->buffer, buffers[i]->allocation); + graphics->getDestructionManager()->queueResourceForDestruction(std::move(buffers[i])); uint32 family = graphics->getFamilyMapping().getQueueTypeFamilyIndex(initialOwner); VkBufferCreateInfo info = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, @@ -215,22 +210,9 @@ void Buffer::rotateBuffer(uint64 size, bool preserveContents) { .pQueueFamilyIndices = &family, }; VmaAllocationCreateInfo allocInfo = { - .flags = - VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, - .usage = VMA_MEMORY_USAGE_AUTO, + .usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, }; - VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &info, &allocInfo, &buffers[i]->buffer, &buffers[i]->allocation, - &buffers[i]->info)); - vmaGetAllocationMemoryProperties(graphics->getAllocator(), buffers[i]->allocation, &buffers[i]->properties); - if (!name.empty()) { - VkDebugUtilsObjectNameInfoEXT nameInfo = {.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, - .pNext = nullptr, - .objectType = VK_OBJECT_TYPE_BUFFER, - .objectHandle = (uint64)buffers[i]->buffer, - .pObjectName = this->name.c_str()}; - vkSetDebugUtilsObjectNameEXT(graphics->getDevice(), &nameInfo); - } - buffers[i]->size = size; + buffers[i] = new BufferAllocation(graphics, name, info, allocInfo, initialOwner); } if (preserveContents) { copyBuffer(currentBuffer, i); @@ -246,33 +228,22 @@ void Buffer::rotateBuffer(uint64 size, bool preserveContents) { } void Buffer::createBuffer(uint64 size) { - uint32 family = graphics->getFamilyMapping().getQueueTypeFamilyIndex(initialOwner); - VkBufferCreateInfo info = { - .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .size = size, - .usage = usage, - .sharingMode = VK_SHARING_MODE_EXCLUSIVE, - .queueFamilyIndexCount = 1, - .pQueueFamilyIndices = &family, - }; - VmaAllocationCreateInfo allocInfo = { - .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, - .usage = VMA_MEMORY_USAGE_AUTO, - }; - buffers.add(new BufferAllocation(graphics, info, allocInfo, initialOwner)); if (size > 0) { - VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &info, &allocInfo, &buffers.back()->buffer, &buffers.back()->allocation, - &buffers.back()->info)); - if (!name.empty()) { - VkDebugUtilsObjectNameInfoEXT nameInfo = {.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, - .pNext = nullptr, - .objectType = VK_OBJECT_TYPE_BUFFER, - .objectHandle = (uint64)buffers.back()->buffer, - .pObjectName = this->name.c_str()}; - vkSetDebugUtilsObjectNameEXT(graphics->getDevice(), &nameInfo); - } + uint32 family = graphics->getFamilyMapping().getQueueTypeFamilyIndex(initialOwner); + VkBufferCreateInfo info = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .size = size, + .usage = usage, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .queueFamilyIndexCount = 1, + .pQueueFamilyIndices = &family, + }; + VmaAllocationCreateInfo allocInfo = { + .usage = VMA_MEMORY_USAGE_AUTO, + }; + buffers.add(new BufferAllocation(graphics, name, info, allocInfo, initialOwner)); } } @@ -294,7 +265,11 @@ void Buffer::copyBuffer(uint64 src, uint64 dst) { }; vkCmdPipelineBarrier(command->getHandle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &srcBarrier, 0, nullptr); - VkBufferCopy region = {.srcOffset = 0, .dstOffset = 0, .size = buffers[src]->size}; + VkBufferCopy region = { + .srcOffset = 0, + .dstOffset = 0, + .size = buffers[src]->size, + }; vkCmdCopyBuffer(command->getHandle(), buffers[src]->buffer, buffers[dst]->buffer, 1, ®ion); VkBufferMemoryBarrier dstBarrier = { .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, @@ -322,19 +297,17 @@ UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo& : Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo), Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, createInfo.sourceData.owner, createInfo.dynamic, createInfo.name) { - if (getSize() > 0 && createInfo.sourceData.data != nullptr) { - void* data = map(); - std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size); - unmap(); + if (createInfo.sourceData.size > 0 && createInfo.sourceData.data != nullptr) { + getAlloc()->updateContents(createInfo.sourceData.offset, createInfo.sourceData.size, createInfo.sourceData.data); } } UniformBuffer::~UniformBuffer() {} void UniformBuffer::updateContents(const DataSource& sourceData) { - void* data = map(); - std::memcpy(data, sourceData.data, sourceData.size); - unmap(); + if (sourceData.size > 0 && sourceData.data != nullptr) { + getAlloc()->updateContents(sourceData.offset, sourceData.size, sourceData.data); + } } void UniformBuffer::rotateBuffer(uint64 size) { Vulkan::Buffer::rotateBuffer(size); } @@ -354,10 +327,8 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& cre VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT : 0), createInfo.sourceData.owner, createInfo.dynamic, createInfo.name) { - if (getSize() > 0 && createInfo.sourceData.data != nullptr) { - void* data = map(); - std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size); - unmap(); + if (createInfo.sourceData.size > 0 && createInfo.sourceData.data != nullptr) { + getAlloc()->updateContents(createInfo.sourceData.offset, createInfo.sourceData.size, createInfo.sourceData.data); } } @@ -368,20 +339,16 @@ void ShaderBuffer::updateContents(const ShaderBufferCreateInfo& createInfo) { 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(); + if (createInfo.sourceData.size > 0 && createInfo.sourceData.data != nullptr) { + getAlloc()->updateContents(createInfo.sourceData.offset, createInfo.sourceData.size, createInfo.sourceData.data); + } } -void Seele::Vulkan::ShaderBuffer::rotateBuffer(uint64 size, bool preserveContents) { +void ShaderBuffer::rotateBuffer(uint64 size, bool preserveContents) { assert(dynamic); Vulkan::Buffer::rotateBuffer(size, preserveContents); } -void* ShaderBuffer::mapRegion(uint64 offset, uint64 size, bool writeOnly) { return Vulkan::Buffer::mapRegion(offset, size, writeOnly); } - -void ShaderBuffer::unmap() { Vulkan::Buffer::unmap(); } - void ShaderBuffer::clear() { vkCmdFillBuffer(graphics->getQueueCommands(getAlloc()->owner)->getCommands()->getHandle(), Vulkan::Buffer::getHandle(), 0, VK_WHOLE_SIZE, 0); @@ -398,26 +365,18 @@ VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo& cre : Gfx::VertexBuffer(graphics->getFamilyMapping(), createInfo), Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, createInfo.sourceData.owner, false, createInfo.name) { - if (createInfo.sourceData.data != nullptr) { - void* data = map(); - std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size); - unmap(); + if (createInfo.sourceData.size > 0 && createInfo.sourceData.data != nullptr) { + getAlloc()->updateContents(createInfo.sourceData.offset, createInfo.sourceData.size, createInfo.sourceData.data); } } VertexBuffer::~VertexBuffer() {} -void VertexBuffer::updateRegion(DataSource update) { - void* data = mapRegion(update.offset, update.size); - std::memcpy(data, update.data, update.size); - unmap(); -} +void VertexBuffer::updateRegion(DataSource sourceData) { getAlloc()->updateContents(sourceData.offset, sourceData.size, sourceData.data); } void VertexBuffer::download(Array& buffer) { - void* data = map(false); buffer.resize(getSize()); - std::memcpy(buffer.data(), data, getSize()); - unmap(); + getAlloc()->readContents(0, buffer.size(), buffer.data()); } void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { Vulkan::Buffer::transferOwnership(newOwner); } @@ -431,22 +390,16 @@ IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo& create : Gfx::IndexBuffer(graphics->getFamilyMapping(), createInfo), Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | - VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, + VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, createInfo.sourceData.owner, false, createInfo.name) { - if (createInfo.sourceData.data != nullptr) { - void* data = map(); - std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size); - unmap(); - } + getAlloc()->updateContents(createInfo.sourceData.offset, createInfo.sourceData.size, createInfo.sourceData.data); } IndexBuffer::~IndexBuffer() {} void IndexBuffer::download(Array& buffer) { - void* data = map(false); buffer.resize(getSize()); - std::memcpy(buffer.data(), data, getSize()); - unmap(); + getAlloc()->readContents(0, buffer.size(), buffer.data()); } void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { Vulkan::Buffer::transferOwnership(newOwner); } diff --git a/src/Engine/Graphics/Vulkan/Buffer.h b/src/Engine/Graphics/Vulkan/Buffer.h index 61e5867..18225dc 100644 --- a/src/Engine/Graphics/Vulkan/Buffer.h +++ b/src/Engine/Graphics/Vulkan/Buffer.h @@ -10,13 +10,13 @@ DECLARE_REF(Command) DECLARE_REF(Fence) class BufferAllocation : public CommandBoundResource { public: - BufferAllocation(PGraphics graphics, VkBufferCreateInfo bufferInfo, VmaAllocationCreateInfo allocInfo, Gfx::QueueType owner); + BufferAllocation(PGraphics graphics, const std::string& name, VkBufferCreateInfo bufferInfo, VmaAllocationCreateInfo allocInfo, Gfx::QueueType owner, uint64 alignment = 0); virtual ~BufferAllocation(); void pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess, VkPipelineStageFlags dstStage); void transferOwnership(Gfx::QueueType newOwner); - void* mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly = true); - void unmap(); + void updateContents(uint64 regionOffset, uint64 regionSize, void* ptr); + void readContents(uint64 regionOffset, uint64 regionSize, void* ptr); VkBuffer buffer = VK_NULL_HANDLE; VmaAllocation allocation = VmaAllocation(); VmaAllocationInfo info = VmaAllocationInfo(); @@ -34,9 +34,8 @@ class Buffer { VkDeviceAddress getDeviceAddress() const { return buffers[currentBuffer]->deviceAddress; } PBufferAllocation getAlloc() const { return buffers[currentBuffer]; } uint64 getSize() const { return buffers[currentBuffer]->size; } - void* map(bool writeOnly = true); - void* mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly = true); - void unmap(); + void updateContents(uint64 regionOffset, uint64 regionSize, void* ptr); + void readContents(uint64 regionOffset, uint64 regionSize, void* ptr); protected: PGraphics graphics; @@ -109,8 +108,6 @@ class ShaderBuffer : public Gfx::ShaderBuffer, public Buffer { virtual ~ShaderBuffer(); virtual void updateContents(const ShaderBufferCreateInfo& createInfo) override; virtual void rotateBuffer(uint64 size, bool preserveContents = false) override; - virtual void* mapRegion(uint64 offset, uint64 size, bool writeOnly) override; - virtual void unmap() override; virtual void clear() override; diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp index 0f4146b..cb7f0c2 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.cpp +++ b/src/Engine/Graphics/Vulkan/Graphics.cpp @@ -88,7 +88,7 @@ void Graphics::init(GraphicsInitializer initInfo) { pickPhysicalDevice(); createDevice(initInfo); VmaAllocatorCreateInfo createInfo = { - .flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT, + .flags = VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT | VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT, .physicalDevice = physicalDevice, .device = handle, .preferredLargeHeapBlockSize = 0, @@ -152,9 +152,11 @@ Gfx::OTextureCube Graphics::createTextureCube(const TextureCreateInfo& createInf Gfx::OUniformBuffer Graphics::createUniformBuffer(const UniformBufferCreateInfo& bulkData) { return new UniformBuffer(this, bulkData); } Gfx::OShaderBuffer Graphics::createShaderBuffer(const ShaderBufferCreateInfo& bulkData) { return new ShaderBuffer(this, bulkData); } + Gfx::OVertexBuffer Graphics::createVertexBuffer(const VertexBufferCreateInfo& bulkData) { return new VertexBuffer(this, bulkData); } Gfx::OIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo& bulkData) { return new IndexBuffer(this, bulkData); } + Gfx::ORenderCommand Graphics::createRenderCommand(const std::string& name) { return getGraphicsCommands()->createRenderCommand(name); } Gfx::OComputeCommand Graphics::createComputeCommand(const std::string& name) { return getComputeCommands()->createComputeCommand(name); } @@ -275,29 +277,32 @@ void Graphics::resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) { void Graphics::copyTexture(Gfx::PTexture source, Gfx::PTexture destination) { PTextureBase src = source.cast(); PTextureBase dst = destination.cast(); - VkImageBlit blit = {.srcSubresource = - { - .aspectMask = src->getAspect(), - .mipLevel = 0, - .baseArrayLayer = 0, - .layerCount = 1, - }, - .srcOffsets = - { - {0, 0, 0}, - {(int32)src->getWidth(), (int32)src->getHeight(), (int32)src->getDepth()}, - }, - .dstSubresource = - { - .aspectMask = dst->getAspect(), - .mipLevel = 0, - .baseArrayLayer = 0, - .layerCount = 1, - }, - .dstOffsets = { - {0, 0, 0}, - {(int32)dst->getWidth(), (int32)dst->getHeight(), (int32)dst->getDepth()}, - }}; + VkImageBlit blit = { + .srcSubresource = + { + .aspectMask = src->getAspect(), + .mipLevel = 0, + .baseArrayLayer = 0, + .layerCount = 1, + }, + .srcOffsets = + { + {0, 0, 0}, + {(int32)src->getWidth(), (int32)src->getHeight(), (int32)src->getDepth()}, + }, + .dstSubresource = + { + .aspectMask = dst->getAspect(), + .mipLevel = 0, + .baseArrayLayer = 0, + .layerCount = 1, + }, + .dstOffsets = + { + {0, 0, 0}, + {(int32)dst->getWidth(), (int32)dst->getHeight(), (int32)dst->getDepth()}, + }, + }; PCommand command = getGraphicsCommands()->getCommands(); vkCmdBlitImage(command->getHandle(), src->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, @@ -430,33 +435,41 @@ void Graphics::pickPhysicalDevice() { vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data()); VkPhysicalDevice bestDevice = VK_NULL_HANDLE; uint32 deviceRating = 0; + props = VkPhysicalDeviceProperties2{ + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, + .pNext = &accelerationProperties, + }; + accelerationProperties = VkPhysicalDeviceAccelerationStructurePropertiesKHR{ + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR, + .pNext = nullptr, + }; for (auto dev : physicalDevices) { uint32 currentRating = 0; - vkGetPhysicalDeviceProperties(dev, &props); - if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) { - std::cout << "found dedicated gpu " << props.deviceName << std::endl; + vkGetPhysicalDeviceProperties2(dev, &props); + if (props.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) { + std::cout << "found dedicated gpu " << props.properties.deviceName << std::endl; currentRating += 100; - } else if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) { - std::cout << "found integrated gpu " << props.deviceName << std::endl; + } else if (props.properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) { + std::cout << "found integrated gpu " << props.properties.deviceName << std::endl; currentRating += 10; } if (currentRating > deviceRating) { deviceRating = currentRating; bestDevice = dev; - std::cout << "bestDevice: " << props.deviceName << std::endl; + std::cout << "bestDevice: " << props.properties.deviceName << std::endl; } } physicalDevice = bestDevice; - vkGetPhysicalDeviceProperties(physicalDevice, &props); - acceleration = { + vkGetPhysicalDeviceProperties2(physicalDevice, &props); + accelerationFeatures = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR, .pNext = nullptr, .accelerationStructure = true, }; meshShaderFeatures = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT, - .pNext = &acceleration, + .pNext = &accelerationFeatures, .taskShader = true, .meshShader = true, .meshShaderQueries = true, @@ -464,14 +477,23 @@ void Graphics::pickPhysicalDevice() { features12 = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, .pNext = &meshShaderFeatures, + .storageBuffer8BitAccess = true, .bufferDeviceAddress = true, }; - features = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, - .pNext = &features12, - .features = { - .occlusionQueryPrecise = true, - .inheritedQueries = true, - }}; + features = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, + .pNext = &features12, + .features = + { + .geometryShader = true, + .fillModeNonSolid = true, + .wideLines = true, + .occlusionQueryPrecise = true, + .fragmentStoresAndAtomics = true, + .shaderInt64 = true, + .inheritedQueries = true, + }, + }; if (Gfx::useMeshShading) { uint32 count = 0; vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &count, nullptr); @@ -562,6 +584,7 @@ void Graphics::createDevice(GraphicsInitializer initializer) { #endif initializer.deviceExtensions.add(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); initializer.deviceExtensions.add(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME); + initializer.deviceExtensions.add(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME); VkDeviceCreateInfo deviceInfo = { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, .pNext = &features, diff --git a/src/Engine/Graphics/Vulkan/Graphics.h b/src/Engine/Graphics/Vulkan/Graphics.h index f830b32..0b9488e 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.h +++ b/src/Engine/Graphics/Vulkan/Graphics.h @@ -13,9 +13,10 @@ class Graphics : public Gfx::Graphics { public: Graphics(); virtual ~Graphics(); - constexpr VkInstance getInstance() const { return instance; }; - constexpr VkDevice getDevice() const { return handle; }; - constexpr VkPhysicalDevice getPhysicalDevice() const { return physicalDevice; }; + constexpr VkInstance getInstance() const { return instance; } + constexpr VkDevice getDevice() const { return handle; } + constexpr VkPhysicalDevice getPhysicalDevice() const { return physicalDevice; } + constexpr VkPhysicalDeviceAccelerationStructurePropertiesKHR getAccelerationProperties() const { return accelerationProperties; } PCommandPool getQueueCommands(Gfx::QueueType queueType); PCommandPool getGraphicsCommands(); @@ -94,11 +95,12 @@ class Graphics : public Gfx::Graphics { thread_local static PCommandPool transferCommands; std::mutex poolLock; Array pools; - VkPhysicalDeviceProperties props; + VkPhysicalDeviceProperties2 props; VkPhysicalDeviceFeatures2 features; VkPhysicalDeviceVulkan12Features features12; VkPhysicalDeviceMeshShaderFeaturesEXT meshShaderFeatures; - VkPhysicalDeviceAccelerationStructureFeaturesKHR acceleration; + VkPhysicalDeviceAccelerationStructureFeaturesKHR accelerationFeatures; + VkPhysicalDeviceAccelerationStructurePropertiesKHR accelerationProperties; VkDebugUtilsMessengerEXT callback; Map allocatedFramebuffers; VmaAllocator allocator; diff --git a/src/Engine/Graphics/Vulkan/Query.cpp b/src/Engine/Graphics/Vulkan/Query.cpp index 0d026a1..82ae45b 100644 --- a/src/Engine/Graphics/Vulkan/Query.cpp +++ b/src/Engine/Graphics/Vulkan/Query.cpp @@ -22,7 +22,7 @@ void OcclusionQuery::beginQuery() { vkCmdBeginQuery(graphics->getGraphicsCommand void OcclusionQuery::endQuery() { vkCmdEndQuery(graphics->getGraphicsCommands()->getCommands()->getHandle(), handle, 0); } -void OcclusionQuery::resetQuery() { vkResetQueryPool(graphics->getDevice(), handle, 0, 1); } +void OcclusionQuery::resetQuery() { vkCmdResetQueryPool(graphics->getGraphicsCommands()->getCommands()->getHandle(), handle, 0, 1); } uint64 OcclusionQuery::getResults() { graphics->getGraphicsCommands()->submitCommands(); diff --git a/src/Engine/Graphics/Vulkan/RayTracing.cpp b/src/Engine/Graphics/Vulkan/RayTracing.cpp index 422e923..949e160 100644 --- a/src/Engine/Graphics/Vulkan/RayTracing.cpp +++ b/src/Engine/Graphics/Vulkan/RayTracing.cpp @@ -28,18 +28,21 @@ BottomLevelAS::BottomLevelAS(PGraphics graphics, const Gfx::BottomLevelASCreateI .pNext = nullptr, .flags = 0, .size = sizeof(VkTransformMatrixKHR), - .usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, + .usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | + VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR, }; VmaAllocationCreateInfo transformAllocInfo = { .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT, .usage = VMA_MEMORY_USAGE_AUTO, }; - OBufferAllocation transformBuffer = new BufferAllocation(graphics, transformBufferInfo, transformAllocInfo, Gfx::QueueType::GRAPHICS); + OBufferAllocation transformBuffer = + new BufferAllocation(graphics, "TransformBuffer", transformBufferInfo, transformAllocInfo, Gfx::QueueType::GRAPHICS); VkDeviceOrHostAddressConstKHR vertexDataAddress = { - .deviceAddress = positionBuffer.cast()->getDeviceAddress() + vertexData->getMeshOffset(createInfo.mesh->id), + .deviceAddress = + positionBuffer.cast()->getDeviceAddress() + vertexData->getMeshOffset(createInfo.mesh->id) * sizeof(Vector4), }; VkDeviceOrHostAddressConstKHR indexDataAddress = { - .deviceAddress = indexBuffer.cast()->getDeviceAddress() + meshData.firstIndex, + .deviceAddress = indexBuffer.cast()->getDeviceAddress() + meshData.firstIndex * sizeof(uint32), }; VkDeviceOrHostAddressConstKHR transformDataAddress = { .deviceAddress = transformBuffer->deviceAddress, @@ -71,13 +74,13 @@ BottomLevelAS::BottomLevelAS(PGraphics graphics, const Gfx::BottomLevelASCreateI .pGeometries = &geometry, }; - const uint32 primitiveCount = 1; + const uint32 primitiveCount = meshData.numIndices / 3; VkAccelerationStructureBuildSizesInfoKHR buildSizesInfo = { .sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR, .pNext = nullptr, }; - vkGetAccelerationStructureBuildSizesKHR(graphics->getDevice(), VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, &structureBuildGeometry, + vkGetAccelerationStructureBuildSizesKHR(graphics->getDevice(), VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, &structureBuildGeometry, &primitiveCount, &buildSizesInfo); VkBufferCreateInfo tempBufferInfo = { @@ -90,7 +93,7 @@ BottomLevelAS::BottomLevelAS(PGraphics graphics, const Gfx::BottomLevelASCreateI VmaAllocationCreateInfo tempBufferAllocInfo = { .usage = VMA_MEMORY_USAGE_AUTO, }; - OBufferAllocation tempAlloc = new BufferAllocation(graphics, tempBufferInfo, tempBufferAllocInfo, Gfx::QueueType::GRAPHICS); + OBufferAllocation tempAlloc = new BufferAllocation(graphics, "TempBuffer", tempBufferInfo, tempBufferAllocInfo, Gfx::QueueType::GRAPHICS); VkAccelerationStructureCreateInfoKHR tempInfo = { .sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR, @@ -114,24 +117,19 @@ BottomLevelAS::BottomLevelAS(PGraphics graphics, const Gfx::BottomLevelASCreateI VmaAllocationCreateInfo scratchAllocInfo = { .usage = VMA_MEMORY_USAGE_AUTO, }; - OBufferAllocation scratchAlloc = new BufferAllocation(graphics, scratchInfo, scratchAllocInfo, Gfx::QueueType::GRAPHICS); + OBufferAllocation scratchAlloc = + new BufferAllocation(graphics, "ScratchBuffer", scratchInfo, scratchAllocInfo, Gfx::QueueType::GRAPHICS, + graphics->getAccelerationProperties().minAccelerationStructureScratchOffsetAlignment); - VkAccelerationStructureBuildGeometryInfoKHR buildGeometry = {.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR, - .pNext = nullptr, - .type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR, - .flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR, - .mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR, - .dstAccelerationStructure = tempAS, - .geometryCount = 1, - .pGeometries = &geometry, - .scratchData = {.deviceAddress = scratchAlloc->deviceAddress}}; + structureBuildGeometry.dstAccelerationStructure = tempAS; + structureBuildGeometry.scratchData.deviceAddress = scratchAlloc->deviceAddress; VkAccelerationStructureBuildRangeInfoKHR buildRangeInfo = { - .primitiveCount = meshData.numIndices / 3, .primitiveOffset = 0, .firstVertex = 0, .transformOffset = 0}; + .primitiveCount = primitiveCount, .primitiveOffset = 0, .firstVertex = 0, .transformOffset = 0}; Array ranges = {&buildRangeInfo}; PCommand cmd = graphics->getGraphicsCommands()->getCommands(); - vkCmdBuildAccelerationStructuresKHR(cmd->getHandle(), 1, &buildGeometry, ranges.data()); + vkCmdBuildAccelerationStructuresKHR(cmd->getHandle(), 1, &structureBuildGeometry, ranges.data()); cmd->bindResource(PBufferAllocation(transformBuffer)); cmd->bindResource(PBufferAllocation(tempAlloc)); cmd->bindResource(PBufferAllocation(scratchAlloc)); diff --git a/src/Engine/Graphics/Vulkan/Texture.cpp b/src/Engine/Graphics/Vulkan/Texture.cpp index 6114c87..ce8646a 100644 --- a/src/Engine/Graphics/Vulkan/Texture.cpp +++ b/src/Engine/Graphics/Vulkan/Texture.cpp @@ -31,7 +31,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const : CommandBoundResource(graphics), image(existingImage), width(createInfo.width), height(createInfo.height), depth(createInfo.depth), arrayCount(createInfo.elements), layerCount(createInfo.layers), mipLevels(createInfo.mipLevels), samples(createInfo.samples), format(createInfo.format), usage(createInfo.usage), layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED), - aspect(getAspectFromFormat(createInfo.format)), ownsImage(false) { + aspect(getAspectFromFormat(createInfo.format)), ownsImage(false), owner(createInfo.sourceData.owner) { if (existingImage == VK_NULL_HANDLE) { VkImageType type = VK_IMAGE_TYPE_MAX_ENUM; VkImageCreateFlags flags = 0; @@ -102,10 +102,8 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT, .usage = VMA_MEMORY_USAGE_AUTO, }; - OBufferAllocation stagingAlloc = new BufferAllocation(graphics, stagingInfo, alloc, Gfx::QueueType::TRANSFER); + OBufferAllocation stagingAlloc = new BufferAllocation(graphics, createInfo.name, stagingInfo, alloc, Gfx::QueueType::TRANSFER); vmaMapMemory(graphics->getAllocator(), stagingAlloc->allocation, &data); - vmaSetAllocationName(graphics->getAllocator(), stagingAlloc->allocation, "TextureStaging"); - std::memcpy(data, sourceData.data, sourceData.size); vmaUnmapMemory(graphics->getAllocator(), stagingAlloc->allocation); @@ -204,6 +202,8 @@ void TextureHandle::pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlag void TextureHandle::transferOwnership(Gfx::QueueType newOwner) { Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping(); + if (mapping.getQueueTypeFamilyIndex(newOwner) == mapping.getQueueTypeFamilyIndex(owner)) + return; VkImageMemoryBarrier barrier = { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .pNext = nullptr, @@ -282,9 +282,7 @@ void TextureHandle::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Ar .flags = VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT, .usage = VMA_MEMORY_USAGE_AUTO, }; - OBufferAllocation stagingAlloc = new BufferAllocation(graphics, stagingInfo, alloc, owner); - - vmaSetAllocationName(graphics->getAllocator(), stagingAlloc->allocation, "DownloadBuffer"); + OBufferAllocation stagingAlloc = new BufferAllocation(graphics, "DownloadBuffer", stagingInfo, alloc, owner); PCommand cmdBuffer = graphics->getQueueCommands(owner)->getCommands(); // Gfx::FormatCompatibilityInfo formatInfo = Gfx::getFormatInfo(format);