From f1b15c5000ccbe5eea1d5a112334683f135831f7 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 23 Oct 2023 21:48:20 +0200 Subject: [PATCH] Fix the second vertex buffer binding bug --- .../rendering/vulkan/buffers/vk_buffer.cpp | 4 ++- .../rendering/vulkan/buffers/vk_rsbuffers.cpp | 5 +-- .../vulkan/pipelines/vk_renderpass.cpp | 35 +++++++------------ .../vulkan/pipelines/vk_renderpass.h | 5 ++- .../rendering/vulkan/vk_renderdevice.cpp | 4 +-- .../rendering/vulkan/vk_renderstate.cpp | 5 +-- src/rendering/hwrenderer/doom_levelmesh.cpp | 8 +++++ wadsrc/static/shaders/scene/frag_main.glsl | 12 +++---- 8 files changed, 38 insertions(+), 40 deletions(-) diff --git a/src/common/rendering/vulkan/buffers/vk_buffer.cpp b/src/common/rendering/vulkan/buffers/vk_buffer.cpp index 1040b75ae..23b6f4d37 100644 --- a/src/common/rendering/vulkan/buffers/vk_buffer.cpp +++ b/src/common/rendering/vulkan/buffers/vk_buffer.cpp @@ -73,7 +73,9 @@ void VkBufferManager::RemoveBuffer(VkHardwareBuffer* buffer) IBuffer* VkBufferManager::CreateVertexBuffer(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute* attrs) { - return new VkHardwareVertexBuffer(fb, fb->GetRenderPassManager()->GetVertexFormat(numBindingPoints, numAttributes, stride, attrs)); + std::vector bufferStrides; + bufferStrides.resize(numBindingPoints, stride); + return new VkHardwareVertexBuffer(fb, fb->GetRenderPassManager()->GetVertexFormat(bufferStrides, std::vector(attrs, attrs + numAttributes))); } IBuffer* VkBufferManager::CreateIndexBuffer() diff --git a/src/common/rendering/vulkan/buffers/vk_rsbuffers.cpp b/src/common/rendering/vulkan/buffers/vk_rsbuffers.cpp index 3ac85c4f9..2b1911486 100644 --- a/src/common/rendering/vulkan/buffers/vk_rsbuffers.cpp +++ b/src/common/rendering/vulkan/buffers/vk_rsbuffers.cpp @@ -30,14 +30,15 @@ VkRSBuffers::VkRSBuffers(VulkanRenderDevice* fb) { - static const FVertexBufferAttribute format[] = + static std::vector format = { { 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) }, }; + static std::vector bufferStrides = { sizeof(FFlatVertex), sizeof(FFlatVertex) }; - Flatbuffer.VertexFormat = fb->GetRenderPassManager()->GetVertexFormat(1, 3, sizeof(FFlatVertex), format); + Flatbuffer.VertexFormat = fb->GetRenderPassManager()->GetVertexFormat(bufferStrides, format); Flatbuffer.VertexBuffer = BufferBuilder() .Usage(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VMA_MEMORY_USAGE_UNKNOWN, VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT) diff --git a/src/common/rendering/vulkan/pipelines/vk_renderpass.cpp b/src/common/rendering/vulkan/pipelines/vk_renderpass.cpp index a9b4ea437..58a09f666 100644 --- a/src/common/rendering/vulkan/pipelines/vk_renderpass.cpp +++ b/src/common/rendering/vulkan/pipelines/vk_renderpass.cpp @@ -94,39 +94,30 @@ VkRenderPassSetup *VkRenderPassManager::GetRenderPass(const VkRenderPassKey &key return item.get(); } -int VkRenderPassManager::GetVertexFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) +int VkRenderPassManager::GetVertexFormat(const std::vector& bufferStrides, const std::vector& attrs) { for (size_t i = 0; i < VertexFormats.size(); i++) { const auto &f = VertexFormats[i]; - if (f.Attrs.size() == (size_t)numAttributes && f.NumBindingPoints == numBindingPoints && f.Stride == stride) + if (f.BufferStrides.size() == bufferStrides.size() && + f.Attrs.size() == attrs.size() && + memcmp(f.BufferStrides.data(), bufferStrides.data(), bufferStrides.size() * sizeof(size_t)) == 0 && + memcmp(f.Attrs.data(), attrs.data(), attrs.size() * sizeof(FVertexBufferAttribute)) == 0) { - bool matches = true; - for (int j = 0; j < numAttributes; j++) - { - if (memcmp(&f.Attrs[j], &attrs[j], sizeof(FVertexBufferAttribute)) != 0) - { - matches = false; - break; - } - } - - if (matches) - return (int)i; + return (int)i; } } VkVertexFormat fmt; - fmt.NumBindingPoints = numBindingPoints; - fmt.Stride = stride; + fmt.BufferStrides = bufferStrides; + fmt.Attrs = attrs; fmt.UseVertexData = 0; - for (int j = 0; j < numAttributes; j++) + for (const FVertexBufferAttribute& attr : fmt.Attrs) { - if (attrs[j].location == VATTR_COLOR) + if (attr.location == VATTR_COLOR) fmt.UseVertexData |= 1; - else if (attrs[j].location == VATTR_NORMAL) + else if (attr.location == VATTR_NORMAL) fmt.UseVertexData |= 2; - fmt.Attrs.push_back(attrs[j]); } VertexFormats.push_back(fmt); return (int)VertexFormats.size() - 1; @@ -253,8 +244,8 @@ std::unique_ptr VkRenderPassSetup::CreatePipeline(const VkPipeli const VkVertexFormat &vfmt = *fb->GetRenderPassManager()->GetVertexFormat(key.VertexFormat); - for (int i = 0; i < vfmt.NumBindingPoints; i++) - builder.AddVertexBufferBinding(i, vfmt.Stride); + for (int i = 0; i < vfmt.BufferStrides.size(); i++) + builder.AddVertexBufferBinding(i, vfmt.BufferStrides[i]); const static VkFormat vkfmts[] = { VK_FORMAT_R32G32B32A32_SFLOAT, diff --git a/src/common/rendering/vulkan/pipelines/vk_renderpass.h b/src/common/rendering/vulkan/pipelines/vk_renderpass.h index 35df3f466..0770817bb 100644 --- a/src/common/rendering/vulkan/pipelines/vk_renderpass.h +++ b/src/common/rendering/vulkan/pipelines/vk_renderpass.h @@ -90,8 +90,7 @@ private: class VkVertexFormat { public: - int NumBindingPoints; - size_t Stride; + std::vector BufferStrides; std::vector Attrs; int UseVertexData; }; @@ -107,7 +106,7 @@ public: void RenderBuffersReset(); VkRenderPassSetup *GetRenderPass(const VkRenderPassKey &key); - int GetVertexFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs); + int GetVertexFormat(const std::vector& bufferStrides, const std::vector& attrs); VkVertexFormat *GetVertexFormat(int index); VulkanPipelineLayout* GetPipelineLayout(int numLayers, bool levelmesh); diff --git a/src/common/rendering/vulkan/vk_renderdevice.cpp b/src/common/rendering/vulkan/vk_renderdevice.cpp index ff2356b0e..7602a070d 100644 --- a/src/common/rendering/vulkan/vk_renderdevice.cpp +++ b/src/common/rendering/vulkan/vk_renderdevice.cpp @@ -658,14 +658,14 @@ void VulkanRenderDevice::DrawLevelMesh(const HWViewpointUniforms& viewpoint) cmdbuffer->setStencilReference(VK_STENCIL_FRONT_AND_BACK, 0); cmdbuffer->setDepthBias(0.0f, 0.0f, 0.0f); - static const FVertexBufferAttribute format[] = + static const std::vector format = { { 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(2, 4, sizeof(FFlatVertex), format); + int vertexFormatIndex = GetRenderPassManager()->GetVertexFormat({ sizeof(FFlatVertex), sizeof(int32_t) }, format); VkBuffer vertexBuffers[2] = { GetRaytrace()->GetVertexBuffer()->buffer, GetRaytrace()->GetUniformIndexBuffer()->buffer }; VkDeviceSize vertexBufferOffsets[] = { 0, 0 }; cmdbuffer->bindVertexBuffers(0, 2, vertexBuffers, vertexBufferOffsets); diff --git a/src/common/rendering/vulkan/vk_renderstate.cpp b/src/common/rendering/vulkan/vk_renderstate.cpp index 3f61457e8..294879a01 100644 --- a/src/common/rendering/vulkan/vk_renderstate.cpp +++ b/src/common/rendering/vulkan/vk_renderstate.cpp @@ -443,19 +443,20 @@ void VkRenderState::ApplyVertexBuffers() { if ((mVertexBuffer != mLastVertexBuffer || mVertexOffsets[0] != mLastVertexOffsets[0] || mVertexOffsets[1] != mLastVertexOffsets[1])) { + // Note: second [0] for BufferStrides is not a typo. Not all the vertex formats have a second buffer and the entire thing assumes they have the same stride anyway. if (mVertexBuffer) { auto vkbuf = static_cast(mVertexBuffer); const VkVertexFormat* format = fb->GetRenderPassManager()->GetVertexFormat(vkbuf->VertexFormat); VkBuffer vertexBuffers[2] = { vkbuf->mBuffer->buffer, vkbuf->mBuffer->buffer }; - VkDeviceSize offsets[] = { mVertexOffsets[0] * format->Stride, mVertexOffsets[1] * format->Stride }; + VkDeviceSize offsets[] = { mVertexOffsets[0] * format->BufferStrides[0], mVertexOffsets[1] * format->BufferStrides[0]}; mCommandBuffer->bindVertexBuffers(0, 2, vertexBuffers, offsets); } else { const VkVertexFormat* format = fb->GetRenderPassManager()->GetVertexFormat(mRSBuffers->Flatbuffer.VertexFormat); VkBuffer vertexBuffers[2] = { mRSBuffers->Flatbuffer.VertexBuffer->buffer, mRSBuffers->Flatbuffer.VertexBuffer->buffer }; - VkDeviceSize offsets[] = { mVertexOffsets[0] * format->Stride, mVertexOffsets[1] * format->Stride }; + VkDeviceSize offsets[] = { mVertexOffsets[0] * format->BufferStrides[0], mVertexOffsets[1] * format->BufferStrides[0]}; mCommandBuffer->bindVertexBuffers(0, 2, vertexBuffers, offsets); } diff --git a/src/rendering/hwrenderer/doom_levelmesh.cpp b/src/rendering/hwrenderer/doom_levelmesh.cpp index 45e5c533c..a311064f4 100644 --- a/src/rendering/hwrenderer/doom_levelmesh.cpp +++ b/src/rendering/hwrenderer/doom_levelmesh.cpp @@ -1231,6 +1231,8 @@ void DoomLevelSubmesh::CreateFloorSurface(FLevelLocals &doomMap, subsector_t *su float h = txt->GetDisplayHeight(); VSMatrix mat = GetPlaneTextureRotationMatrix(txt, sector, sector_t::floor); + int surfaceIndex = Surfaces.Size(); + MeshVertices.Resize(surf.startVertIndex + surf.numVerts); FFlatVertex* verts = &MeshVertices[surf.startVertIndex]; @@ -1246,6 +1248,8 @@ void DoomLevelSubmesh::CreateFloorSurface(FLevelLocals &doomMap, subsector_t *su verts[j].z = (float)plane.ZatPoint(v1); verts[j].u = uv.X; verts[j].v = uv.Y; + + MeshUniformIndexes.Push(surfaceIndex); } surf.Type = ST_FLOOR; @@ -1291,6 +1295,8 @@ void DoomLevelSubmesh::CreateCeilingSurface(FLevelLocals& doomMap, subsector_t* float h = txt->GetDisplayHeight(); VSMatrix mat = GetPlaneTextureRotationMatrix(txt, sector, sector_t::ceiling); + int surfaceIndex = Surfaces.Size(); + MeshVertices.Resize(surf.startVertIndex + surf.numVerts); FFlatVertex* verts = &MeshVertices[surf.startVertIndex]; @@ -1306,6 +1312,8 @@ void DoomLevelSubmesh::CreateCeilingSurface(FLevelLocals& doomMap, subsector_t* verts[j].z = (float)plane.ZatPoint(v1); verts[j].u = uv.X; verts[j].v = uv.Y; + + MeshUniformIndexes.Push(surfaceIndex); } surf.Type = ST_CEILING; diff --git a/wadsrc/static/shaders/scene/frag_main.glsl b/wadsrc/static/shaders/scene/frag_main.glsl index bc9a720c0..f434f61f2 100644 --- a/wadsrc/static/shaders/scene/frag_main.glsl +++ b/wadsrc/static/shaders/scene/frag_main.glsl @@ -2,16 +2,12 @@ void main() { #ifdef USE_LEVELMESH - /*if (vLightmap.z >= 0.0) - { - FragColor = vec4(texture(LightMap, vLightmap).rgb, 1.0); - } - else - { - FragColor = vec4(vec3(pixelpos.w / 1000), 1.0); - }*/ FragColor.rgb = texture(tex, vTexCoord.st).rgb * (uLightLevel / 255.0); FragColor.a = 1.0; + if (vLightmap.z >= 0.0) + { + FragColor.rgb *= texture(LightMap, vLightmap).rgb; + } #else #ifdef NO_CLIPDISTANCE_SUPPORT