diff --git a/src/common/rendering/hwrenderer/data/hw_levelmesh.h b/src/common/rendering/hwrenderer/data/hw_levelmesh.h index 7f3dd302c..a7cacebb9 100644 --- a/src/common/rendering/hwrenderer/data/hw_levelmesh.h +++ b/src/common/rendering/hwrenderer/data/hw_levelmesh.h @@ -231,6 +231,7 @@ public: TArray MeshVertices; TArray MeshElements; TArray MeshSurfaceIndexes; + TArray MeshSurfaceUniforms; TArray Portals; diff --git a/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp b/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp index 8cfd4ad4c..f15b42980 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp +++ b/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp @@ -52,6 +52,7 @@ void VkRaytrace::Reset() deletelist->Add(std::move(IndexBuffer)); deletelist->Add(std::move(NodeBuffer)); deletelist->Add(std::move(SurfaceBuffer)); + deletelist->Add(std::move(SurfaceUniformsBuffer)); deletelist->Add(std::move(SurfaceIndexBuffer)); deletelist->Add(std::move(PortalBuffer)); deletelist->Add(std::move(StaticBLAS.ScratchBuffer)); @@ -108,6 +109,7 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly) location.NodeSize = (int)submesh->Collision->get_nodes().size(); location.SurfaceIndexSize = submesh->MeshSurfaceIndexes.Size(); location.SurfaceSize = submesh->GetSurfaceCount(); + location.SurfaceUniformsSize = submesh->MeshSurfaceUniforms.Size(); locations.Push(location); } @@ -121,12 +123,14 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly) cur.NodeOffset = prev.NodeOffset + prev.NodeSize; cur.SurfaceIndexOffset = prev.SurfaceIndexOffset + prev.SurfaceIndexSize; cur.SurfaceOffset = prev.SurfaceOffset + prev.SurfaceSize; + cur.SurfaceUniformsOffset = prev.SurfaceUniformsOffset + prev.SurfaceUniformsSize; if ( cur.VertexOffset + cur.VertexSize > GetMaxVertexBufferSize() || cur.IndexOffset + cur.IndexSize > GetMaxIndexBufferSize() || cur.NodeOffset + cur.NodeSize > GetMaxNodeBufferSize() || cur.SurfaceOffset + cur.SurfaceSize > GetMaxSurfaceBufferSize() || + cur.SurfaceUniformsOffset + cur.SurfaceUniformsSize > GetMaxSurfaceUniformsBufferSize() || cur.SurfaceIndexOffset + cur.SurfaceIndexSize > GetMaxSurfaceIndexBufferSize()) { I_FatalError("Dynamic accel struct buffers are too small!"); @@ -146,6 +150,7 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly) transferBufferSize += cur.Submesh->Collision->get_nodes().size() * sizeof(CollisionNode); transferBufferSize += cur.Submesh->MeshSurfaceIndexes.Size() * sizeof(int); transferBufferSize += cur.Submesh->GetSurfaceCount() * sizeof(SurfaceInfo); + transferBufferSize += cur.Submesh->MeshSurfaceUniforms.Size() * sizeof(SurfaceUniforms); } if (!dynamicOnly) transferBufferSize += Mesh->StaticMesh->Portals.Size() * sizeof(PortalInfo); @@ -284,6 +289,7 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly) info.PortalIndex = surface->portalIndex; info.SamplingDistance = (float)surface->sampleDimension; info.Sky = surface->bSky; + info.Alpha = surface->alpha; if (surface->texture.isValid()) { auto mat = FMaterial::ValidateTexture(TexMan.GetGameTexture(surface->texture), 0); @@ -293,7 +299,7 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly) { info.TextureIndex = -1; } - info.Alpha = surface->alpha; + submesh->MeshSurfaceUniforms[j].uTextureIndex = info.TextureIndex; // Bit of a hack, but we don't know the texture index before now *(surfaces++) = info; } @@ -304,6 +310,20 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly) datapos += copysize; } + // Copy surface uniforms + for (unsigned int i = start; i < end; i++) + { + const SubmeshBufferLocation& cur = locations[i]; + auto submesh = cur.Submesh; + + SurfaceUniforms* uniforms = (SurfaceUniforms*)(data + datapos); + size_t copysize = submesh->MeshSurfaceUniforms.Size() * sizeof(SurfaceUniforms); + memcpy(uniforms, submesh->MeshSurfaceUniforms.Data(), copysize); + if (copysize > 0) + cmdbuffer->copyBuffer(transferBuffer.get(), SurfaceUniformsBuffer.get(), datapos, cur.SurfaceUniformsOffset * sizeof(SurfaceUniforms), copysize); + datapos += copysize; + } + // Copy portals if (!dynamicOnly) { @@ -353,6 +373,11 @@ int VkRaytrace::GetMaxSurfaceBufferSize() return Mesh->StaticMesh->GetSurfaceCount() + MaxDynamicSurfaces; } +int VkRaytrace::GetMaxSurfaceUniformsBufferSize() +{ + return Mesh->StaticMesh->MeshSurfaceUniforms.Size() + MaxDynamicSurfaceUniforms; +} + int VkRaytrace::GetMaxSurfaceIndexBufferSize() { return Mesh->StaticMesh->MeshSurfaceIndexes.Size() + MaxDynamicSurfaceIndexes; @@ -402,6 +427,12 @@ void VkRaytrace::CreateBuffers() .DebugName("SurfaceBuffer") .Create(fb->GetDevice()); + SurfaceUniformsBuffer = BufferBuilder() + .Usage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT) + .Size(GetMaxSurfaceUniformsBufferSize() * sizeof(SurfaceUniforms)) + .DebugName("SurfaceUniformsBuffer") + .Create(fb->GetDevice()); + PortalBuffer = BufferBuilder() .Usage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT) .Size(Mesh->StaticMesh->Portals.Size() * sizeof(PortalInfo)) diff --git a/src/common/rendering/vulkan/accelstructs/vk_raytrace.h b/src/common/rendering/vulkan/accelstructs/vk_raytrace.h index 9a0b8f682..4cac0847a 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_raytrace.h +++ b/src/common/rendering/vulkan/accelstructs/vk_raytrace.h @@ -55,6 +55,8 @@ struct SubmeshBufferLocation int SurfaceIndexSize = 0; int SurfaceOffset = 0; int SurfaceSize = 0; + int SurfaceUniformsOffset = 0; + int SurfaceUniformsSize = 0; }; class VkRaytrace @@ -71,6 +73,7 @@ public: VulkanBuffer* GetNodeBuffer() { return NodeBuffer.get(); } VulkanBuffer* GetSurfaceIndexBuffer() { return SurfaceIndexBuffer.get(); } VulkanBuffer* GetSurfaceBuffer() { return SurfaceBuffer.get(); } + VulkanBuffer* GetSurfaceUniformsBuffer() { return SurfaceUniformsBuffer.get(); } VulkanBuffer* GetPortalBuffer() { return PortalBuffer.get(); } int GetIndexCount(); @@ -99,6 +102,7 @@ private: int GetMaxIndexBufferSize(); int GetMaxNodeBufferSize(); int GetMaxSurfaceBufferSize(); + int GetMaxSurfaceUniformsBufferSize(); int GetMaxSurfaceIndexBufferSize(); VulkanRenderDevice* fb = nullptr; @@ -112,6 +116,7 @@ private: std::unique_ptr IndexBuffer; std::unique_ptr SurfaceIndexBuffer; std::unique_ptr SurfaceBuffer; + std::unique_ptr SurfaceUniformsBuffer; std::unique_ptr PortalBuffer; std::unique_ptr NodeBuffer; @@ -120,6 +125,7 @@ private: static const int MaxDynamicVertices = 100'000; static const int MaxDynamicIndexes = 100'000; static const int MaxDynamicSurfaces = 100'000; + static const int MaxDynamicSurfaceUniforms = 100'000; static const int MaxDynamicSurfaceIndexes = 25'000; static const int MaxDynamicNodes = 10'000; diff --git a/src/rendering/hwrenderer/doom_levelmesh.cpp b/src/rendering/hwrenderer/doom_levelmesh.cpp index 97a126e03..7bbfd1166 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelmesh.cpp @@ -665,8 +665,11 @@ void DoomLevelSubmesh::CreateLinePortalSurface(FLevelLocals& doomMap, side_t* si surf.sectorGroup = sectorGroup[front->Index()]; surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); + SurfaceUniforms uniforms = {}; + SetSideTextureUVs(surf, side, side_t::top, v1Top, v1Bottom, v2Top, v2Bottom); + MeshSurfaceUniforms.Push(uniforms); Surfaces.Push(surf); } @@ -761,8 +764,11 @@ void DoomLevelSubmesh::CreateLineHorizonSurface(FLevelLocals& doomMap, side_t* s surf.sectorGroup = sectorGroup[front->Index()]; surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); + SurfaceUniforms uniforms = {}; + SetSideTextureUVs(surf, side, side_t::top, v1Top, v1Bottom, v2Top, v2Bottom); + MeshSurfaceUniforms.Push(uniforms); Surfaces.Push(surf); } @@ -815,8 +821,12 @@ void DoomLevelSubmesh::CreateFrontWallSurface(FLevelLocals& doomMap, side_t* sid surf.texture = side->textures[side_t::mid].texture; surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); + SurfaceUniforms uniforms = {}; + uniforms.uLightLevel = front->lightlevel; + SetSideTextureUVs(surf, side, side_t::top, v1Top, v1Bottom, v2Top, v2Bottom); + MeshSurfaceUniforms.Push(uniforms); Surfaces.Push(surf); } @@ -904,8 +914,12 @@ void DoomLevelSubmesh::CreateMidWallSurface(FLevelLocals& doomMap, side_t* side) surf.alpha = float(side->linedef->alpha); surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); + SurfaceUniforms uniforms = {}; + uniforms.uLightLevel = front->lightlevel; + SetSideTextureUVs(surf, side, side_t::top, verts[2].z, verts[0].z, verts[3].z, verts[1].z); + MeshSurfaceUniforms.Push(uniforms); Surfaces.Push(surf); } @@ -974,8 +988,12 @@ void DoomLevelSubmesh::Create3DFloorWallSurfaces(FLevelLocals& doomMap, side_t* surf.texture = side->textures[side_t::mid].texture; surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); + SurfaceUniforms uniforms = {}; + uniforms.uLightLevel = front->lightlevel; + SetSideTextureUVs(surf, side, side_t::top, tlZ, blZ, trZ, brZ); + MeshSurfaceUniforms.Push(uniforms); Surfaces.Push(surf); } } @@ -1026,8 +1044,12 @@ void DoomLevelSubmesh::CreateTopWallSurface(FLevelLocals& doomMap, side_t* side) surf.texture = side->textures[side_t::top].texture; surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); + SurfaceUniforms uniforms = {}; + uniforms.uLightLevel = front->lightlevel; + SetSideTextureUVs(surf, side, side_t::top, v1Top, v1TopBack, v2Top, v2TopBack); + MeshSurfaceUniforms.Push(uniforms); Surfaces.Push(surf); } @@ -1076,8 +1098,12 @@ void DoomLevelSubmesh::CreateBottomWallSurface(FLevelLocals& doomMap, side_t* si surf.texture = side->textures[side_t::bottom].texture; surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); + SurfaceUniforms uniforms = {}; + uniforms.uLightLevel = front->lightlevel; + SetSideTextureUVs(surf, side, side_t::bottom, v1BottomBack, v1Bottom, v2BottomBack, v2Bottom); + MeshSurfaceUniforms.Push(uniforms); Surfaces.Push(surf); } @@ -1174,6 +1200,10 @@ void DoomLevelSubmesh::CreateFloorSurface(FLevelLocals &doomMap, subsector_t *su surf.sectorGroup = sectorGroup[sector->Index()]; surf.AlwaysUpdate = !!(sector->Flags & SECF_LM_DYNAMIC); + SurfaceUniforms uniforms = {}; + uniforms.uLightLevel = sector->lightlevel; + + MeshSurfaceUniforms.Push(uniforms); Surfaces.Push(surf); } @@ -1229,6 +1259,10 @@ void DoomLevelSubmesh::CreateCeilingSurface(FLevelLocals& doomMap, subsector_t* surf.sectorGroup = sectorGroup[sector->Index()]; surf.AlwaysUpdate = !!(sector->Flags & SECF_LM_DYNAMIC); + SurfaceUniforms uniforms = {}; + uniforms.uLightLevel = sector->lightlevel; + + MeshSurfaceUniforms.Push(uniforms); Surfaces.Push(surf); }