diff --git a/src/common/rendering/hwrenderer/data/buffers.h b/src/common/rendering/hwrenderer/data/buffers.h index 3277fcde9..aae1415f9 100644 --- a/src/common/rendering/hwrenderer/data/buffers.h +++ b/src/common/rendering/hwrenderer/data/buffers.h @@ -26,6 +26,7 @@ enum VATTR_LIGHTMAP, VATTR_BONEWEIGHT, VATTR_BONESELECTOR, + VATTR_UNIFORM_INDEXES, VATTR_MAX }; @@ -37,7 +38,8 @@ enum EVertexAttributeFormat VFmt_Float, VFmt_Byte4, VFmt_Packed_A2R10G10B10, - VFmt_Byte4_UInt + VFmt_Byte4_UInt, + VFmt_Int }; struct FVertexBufferAttribute diff --git a/src/common/rendering/hwrenderer/data/hw_levelmesh.h b/src/common/rendering/hwrenderer/data/hw_levelmesh.h index a7cacebb9..3ae75b149 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 MeshUniformIndexes; 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 f15b42980..caaac929d 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp +++ b/src/common/rendering/vulkan/accelstructs/vk_raytrace.cpp @@ -49,6 +49,7 @@ void VkRaytrace::Reset() { auto deletelist = fb->GetCommands()->DrawDeleteList.get(); deletelist->Add(std::move(VertexBuffer)); + deletelist->Add(std::move(UniformIndexBuffer)); deletelist->Add(std::move(IndexBuffer)); deletelist->Add(std::move(NodeBuffer)); deletelist->Add(std::move(SurfaceBuffer)); @@ -146,6 +147,7 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly) { const SubmeshBufferLocation& cur = locations[i]; transferBufferSize += cur.Submesh->MeshVertices.Size() * sizeof(FFlatVertex); + transferBufferSize += cur.Submesh->MeshUniformIndexes.Size() * sizeof(int); transferBufferSize += cur.Submesh->MeshElements.Size() * sizeof(uint32_t); transferBufferSize += cur.Submesh->Collision->get_nodes().size() * sizeof(CollisionNode); transferBufferSize += cur.Submesh->MeshSurfaceIndexes.Size() * sizeof(int); @@ -217,6 +219,19 @@ void VkRaytrace::UploadMeshes(bool dynamicOnly) datapos += copysize; } + // Copy uniform indexes + for (unsigned int i = start; i < end; i++) + { + const SubmeshBufferLocation& cur = locations[i]; + auto submesh = cur.Submesh; + + size_t copysize = submesh->MeshUniformIndexes.Size() * sizeof(int); + memcpy(data + datapos, submesh->MeshUniformIndexes.Data(), copysize); + if (copysize > 0) + cmdbuffer->copyBuffer(transferBuffer.get(), UniformIndexBuffer.get(), datapos, cur.VertexOffset * sizeof(int), copysize); + datapos += copysize; + } + // Copy indexes for (unsigned int i = start; i < end; i++) { @@ -397,6 +412,14 @@ void VkRaytrace::CreateBuffers() .DebugName("VertexBuffer") .Create(fb->GetDevice()); + UniformIndexBuffer = BufferBuilder() + .Usage( + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | + VK_BUFFER_USAGE_TRANSFER_DST_BIT) + .Size(GetMaxVertexBufferSize() * sizeof(int)) + .DebugName("UniformIndexes") + .Create(fb->GetDevice()); + IndexBuffer = BufferBuilder() .Usage( VK_BUFFER_USAGE_INDEX_BUFFER_BIT | diff --git a/src/common/rendering/vulkan/accelstructs/vk_raytrace.h b/src/common/rendering/vulkan/accelstructs/vk_raytrace.h index 4cac0847a..89b1d0f25 100644 --- a/src/common/rendering/vulkan/accelstructs/vk_raytrace.h +++ b/src/common/rendering/vulkan/accelstructs/vk_raytrace.h @@ -69,6 +69,7 @@ public: VulkanAccelerationStructure* GetAccelStruct() { return TopLevelAS.AccelStruct.get(); } VulkanBuffer* GetVertexBuffer() { return VertexBuffer.get(); } + VulkanBuffer* GetUniformIndexBuffer() { return UniformIndexBuffer.get(); } VulkanBuffer* GetIndexBuffer() { return IndexBuffer.get(); } VulkanBuffer* GetNodeBuffer() { return NodeBuffer.get(); } VulkanBuffer* GetSurfaceIndexBuffer() { return SurfaceIndexBuffer.get(); } @@ -113,6 +114,7 @@ private: LevelMesh* Mesh = nullptr; std::unique_ptr VertexBuffer; + std::unique_ptr UniformIndexBuffer; std::unique_ptr IndexBuffer; std::unique_ptr SurfaceIndexBuffer; std::unique_ptr SurfaceBuffer; diff --git a/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp b/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp index e101b1e0c..850b316a5 100644 --- a/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp +++ b/src/common/rendering/vulkan/descriptorsets/vk_descriptorset.cpp @@ -93,7 +93,6 @@ void VkDescriptorSetManager::UpdateLevelMeshSet() .AddBuffer(LevelMesh.Set.get(), 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetRaytrace()->GetSurfaceUniformsBuffer()) .AddBuffer(LevelMesh.Set.get(), 3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, rsbuffers->Lightbuffer.UBO.get(), 0, sizeof(LightBufferUBO)) .AddBuffer(LevelMesh.Set.get(), 4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, rsbuffers->Bonebuffer.SSO.get()) - .AddBuffer(LevelMesh.Set.get(), 5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, fb->GetRaytrace()->GetSurfaceIndexBuffer()) .Execute(fb->GetDevice()); } @@ -273,7 +272,6 @@ void VkDescriptorSetManager::CreateLevelMeshLayout() .AddBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) .AddBinding(3, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT) .AddBinding(4, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT) - .AddBinding(5, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT) .DebugName("VkDescriptorSetManager.LevelMesh.Layout") .Create(fb->GetDevice()); } @@ -314,7 +312,7 @@ void VkDescriptorSetManager::CreateLevelMeshPool() { LevelMesh.Pool = DescriptorPoolBuilder() .AddPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 3) - .AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 3) + .AddPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2) .MaxSets(1) .DebugName("VkDescriptorSetManager.LevelMesh.Pool") .Create(fb->GetDevice()); diff --git a/src/common/rendering/vulkan/pipelines/vk_renderpass.cpp b/src/common/rendering/vulkan/pipelines/vk_renderpass.cpp index 1c1adb76c..ce66ea308 100644 --- a/src/common/rendering/vulkan/pipelines/vk_renderpass.cpp +++ b/src/common/rendering/vulkan/pipelines/vk_renderpass.cpp @@ -261,7 +261,8 @@ std::unique_ptr VkRenderPassSetup::CreatePipeline(const VkPipeli VK_FORMAT_R32_SFLOAT, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_A2B10G10R10_SNORM_PACK32, - VK_FORMAT_R8G8B8A8_UINT + VK_FORMAT_R8G8B8A8_UINT, + VK_FORMAT_R32_SINT }; bool inputLocations[VATTR_MAX] = {}; diff --git a/src/common/rendering/vulkan/vk_renderdevice.cpp b/src/common/rendering/vulkan/vk_renderdevice.cpp index 6bc730e45..efa2b5da4 100644 --- a/src/common/rendering/vulkan/vk_renderdevice.cpp +++ b/src/common/rendering/vulkan/vk_renderdevice.cpp @@ -662,9 +662,10 @@ void VulkanRenderDevice::DrawLevelMesh(const HWViewpointUniforms& viewpoint) { 0, VATTR_VERTEX, VFmt_Float4, (int)myoffsetof(FFlatVertex, x) }, { 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FFlatVertex, u) }, { 0, VATTR_LIGHTMAP, VFmt_Float2, (int)myoffsetof(FFlatVertex, lu) }, + { 1, VATTR_UNIFORM_INDEXES, VFmt_Int, 0 } }; - int vertexFormatIndex = GetRenderPassManager()->GetVertexFormat(1, 3, sizeof(FFlatVertex), format); - VkBuffer vertexBuffers[2] = { GetRaytrace()->GetVertexBuffer()->buffer, GetRaytrace()->GetVertexBuffer()->buffer }; + int vertexFormatIndex = GetRenderPassManager()->GetVertexFormat(2, 4, sizeof(FFlatVertex), format); + VkBuffer vertexBuffers[2] = { GetRaytrace()->GetVertexBuffer()->buffer, GetRaytrace()->GetUniformIndexBuffer()->buffer }; VkDeviceSize vertexBufferOffsets[] = { 0, 0 }; cmdbuffer->bindVertexBuffers(0, 2, vertexBuffers, vertexBufferOffsets); cmdbuffer->bindIndexBuffer(GetRaytrace()->GetIndexBuffer()->buffer, 0, VK_INDEX_TYPE_UINT32); diff --git a/src/rendering/hwrenderer/doom_levelmesh.cpp b/src/rendering/hwrenderer/doom_levelmesh.cpp index bf647b85f..60ad6d9f7 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelmesh.cpp @@ -267,8 +267,12 @@ int DoomLevelMesh::AddSurfaceLights(const LevelMeshSurface* surface, LevelMeshLi void DoomLevelSubmesh::CreateStatic(FLevelLocals& doomMap) { + Surfaces.Clear(); MeshVertices.Clear(); MeshElements.Clear(); + MeshSurfaceIndexes.Clear(); + MeshUniformIndexes.Clear(); + MeshSurfaceUniforms.Clear(); LightmapSampleDistance = doomMap.LightmapSampleDistance; @@ -301,6 +305,8 @@ void DoomLevelSubmesh::UpdateDynamic(FLevelLocals& doomMap, int lightmapStartInd MeshVertices.Clear(); MeshElements.Clear(); MeshSurfaceIndexes.Clear(); + MeshUniformIndexes.Clear(); + MeshSurfaceUniforms.Clear(); // Look for polyobjects for (unsigned int i = 0; i < doomMap.lines.Size(); i++) @@ -662,6 +668,12 @@ void DoomLevelSubmesh::CreateLinePortalSurface(FLevelLocals& doomMap, side_t* si MeshVertices.Push(verts[2]); MeshVertices.Push(verts[3]); + int surfaceIndex = Surfaces.Size(); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + surf.plane = ToPlane(verts[0].fPos(), verts[1].fPos(), verts[2].fPos(), verts[3].fPos()); surf.sectorGroup = sectorGroup[front->Index()]; surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); @@ -762,6 +774,12 @@ void DoomLevelSubmesh::CreateLineHorizonSurface(FLevelLocals& doomMap, side_t* s MeshVertices.Push(verts[3]); MeshVertices.Push(verts[1]); + int surfaceIndex = Surfaces.Size(); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + surf.plane = ToPlane(verts[0].fPos(), verts[1].fPos(), verts[2].fPos(), verts[3].fPos()); surf.sectorGroup = sectorGroup[front->Index()]; surf.AlwaysUpdate = !!(front->Flags & SECF_LM_DYNAMIC); @@ -815,6 +833,12 @@ void DoomLevelSubmesh::CreateFrontWallSurface(FLevelLocals& doomMap, side_t* sid MeshVertices.Push(verts[3]); MeshVertices.Push(verts[1]); + int surfaceIndex = Surfaces.Size(); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + surf.plane = ToPlane(verts[0].fPos(), verts[1].fPos(), verts[2].fPos(), verts[3].fPos()); surf.Type = ST_MIDDLESIDE; surf.TypeIndex = side->Index(); @@ -908,6 +932,12 @@ void DoomLevelSubmesh::CreateMidWallSurface(FLevelLocals& doomMap, side_t* side) MeshVertices.Push(verts[3]); MeshVertices.Push(verts[1]); + int surfaceIndex = Surfaces.Size(); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + surf.Type = ST_MIDDLESIDE; surf.TypeIndex = side->Index(); surf.sampleDimension = side->textures[side_t::mid].LightmapSampleDistance; @@ -986,6 +1016,12 @@ void DoomLevelSubmesh::Create3DFloorWallSurfaces(FLevelLocals& doomMap, side_t* MeshVertices.Push(verts[3]); MeshVertices.Push(verts[1]); + int surfaceIndex = Surfaces.Size(); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + surf.plane = ToPlane(verts[0].fPos(), verts[1].fPos(), verts[2].fPos(), verts[3].fPos()); surf.sectorGroup = sectorGroup[front->Index()]; surf.texture = side->textures[side_t::mid].texture; @@ -1037,6 +1073,12 @@ void DoomLevelSubmesh::CreateTopWallSurface(FLevelLocals& doomMap, side_t* side) MeshVertices.Push(verts[3]); MeshVertices.Push(verts[1]); + int surfaceIndex = Surfaces.Size(); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + surf.plane = ToPlane(verts[0].fPos(), verts[1].fPos(), verts[2].fPos(), verts[3].fPos()); surf.Type = ST_UPPERSIDE; surf.TypeIndex = side->Index(); @@ -1091,6 +1133,12 @@ void DoomLevelSubmesh::CreateBottomWallSurface(FLevelLocals& doomMap, side_t* si MeshVertices.Push(verts[3]); MeshVertices.Push(verts[1]); + int surfaceIndex = Surfaces.Size(); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + MeshUniformIndexes.Push(surfaceIndex); + surf.plane = ToPlane(verts[0].fPos(), verts[1].fPos(), verts[2].fPos(), verts[3].fPos()); surf.Type = ST_LOWERSIDE; surf.TypeIndex = side->Index(); diff --git a/wadsrc/static/shaders/scene/binding_rsbuffers.glsl b/wadsrc/static/shaders/scene/binding_rsbuffers.glsl index 658d31651..59742e767 100644 --- a/wadsrc/static/shaders/scene/binding_rsbuffers.glsl +++ b/wadsrc/static/shaders/scene/binding_rsbuffers.glsl @@ -108,10 +108,3 @@ layout(set = 1, binding = 5, std430) buffer BoneBufferSSO { mat4 bones[]; }; - -#ifdef USE_LEVELMESH -layout(set = 1, binding = 5) buffer SurfaceIndexBuffer -{ - int surfaceIndices[]; -}; -#endif diff --git a/wadsrc/static/shaders/scene/layout_vert.glsl b/wadsrc/static/shaders/scene/layout_vert.glsl index ec1bb2424..62ed8196b 100644 --- a/wadsrc/static/shaders/scene/layout_vert.glsl +++ b/wadsrc/static/shaders/scene/layout_vert.glsl @@ -28,5 +28,6 @@ layout(location = 8) out vec4 ClipDistanceB; #endif #if defined(USE_LEVELMESH) +layout(location = 9) in int aDataIndex; layout(location = 10) out flat int uDataIndex; #endif diff --git a/wadsrc/static/shaders/scene/vert_main.glsl b/wadsrc/static/shaders/scene/vert_main.glsl index be26de2c0..fc726c2d9 100644 --- a/wadsrc/static/shaders/scene/vert_main.glsl +++ b/wadsrc/static/shaders/scene/vert_main.glsl @@ -9,7 +9,7 @@ void main() vec4 parmPosition; #if defined(USE_LEVELMESH) - uDataIndex = surfaceIndices[gl_VertexIndex / 3]; + uDataIndex = aDataIndex; #endif BonesResult bones = ApplyBones();