diff --git a/src/common/rendering/hwrenderer/data/hw_renderstate.h b/src/common/rendering/hwrenderer/data/hw_renderstate.h index d325ff73d..a9c2e0ae1 100644 --- a/src/common/rendering/hwrenderer/data/hw_renderstate.h +++ b/src/common/rendering/hwrenderer/data/hw_renderstate.h @@ -827,6 +827,7 @@ public: } // Draw level mesh + virtual void ApplyLevelMesh() { } virtual void DrawLevelMeshRange(int firstIndex, int indexCount, int pipelineID, LevelMeshDrawType drawType, bool noFragmentShader) {} virtual void DispatchLightTiles(const VSMatrix& worldToView, float m5) { } virtual int GetNextQueryIndex() { return 0; } diff --git a/src/common/rendering/vulkan/vk_renderstate.cpp b/src/common/rendering/vulkan/vk_renderstate.cpp index 858aadf65..5aa41a3b0 100644 --- a/src/common/rendering/vulkan/vk_renderstate.cpp +++ b/src/common/rendering/vulkan/vk_renderstate.cpp @@ -919,11 +919,17 @@ void VkRenderState::ApplyLevelMesh() ApplyStencilRef(); ApplyDepthBias(); mNeedApply = true; + mLevelMeshPipelineID = -1; VkBuffer vertexBuffers[2] = { fb->GetLevelMesh()->GetVertexBuffer()->buffer, fb->GetLevelMesh()->GetUniformIndexBuffer()->buffer }; VkDeviceSize vertexBufferOffsets[] = { 0, 0 }; mCommandBuffer->bindVertexBuffers(0, 2, vertexBuffers, vertexBufferOffsets); mCommandBuffer->bindIndexBuffer(fb->GetLevelMesh()->GetIndexBuffer()->buffer, 0, VK_INDEX_TYPE_UINT32); + + // Force rebind everything on next Apply + mLastViewpointOffset = 0xffffffff; + mLastVertexOffsets[0] = 0xffffffff; + mIndexBufferNeedsBind = true; } void VkRenderState::RunZMinMaxPass() @@ -1057,10 +1063,12 @@ void VkRenderState::DispatchLightTiles(const VSMatrix& worldToView, float m5) void VkRenderState::DrawLevelMeshRange(int firstIndex, int indexCount, int pipelineID, LevelMeshDrawType drawType, bool noFragmentShader) { - ApplyLevelMesh(); - - const VkPipelineKey& key = fb->GetLevelMeshPipelineKey(pipelineID); - ApplyLevelMeshPipeline(mCommandBuffer, key, drawType, noFragmentShader); + if (pipelineID != mLevelMeshPipelineID) + { + const VkPipelineKey& key = fb->GetLevelMeshPipelineKey(pipelineID); + ApplyLevelMeshPipeline(mCommandBuffer, key, drawType, noFragmentShader); + mLevelMeshPipelineID = pipelineID; + } mCommandBuffer->drawIndexed(indexCount, 1, firstIndex, 0, 0); } diff --git a/src/common/rendering/vulkan/vk_renderstate.h b/src/common/rendering/vulkan/vk_renderstate.h index 6d7ad5b55..4ef315cf0 100644 --- a/src/common/rendering/vulkan/vk_renderstate.h +++ b/src/common/rendering/vulkan/vk_renderstate.h @@ -57,6 +57,7 @@ public: void ResetVertices() override; // Draw level mesh + void ApplyLevelMesh() override; void DrawLevelMeshRange(int firstIndex, int indexCount, int pipelineID, LevelMeshDrawType drawType, bool noFragmentShader) override; void DispatchLightTiles(const VSMatrix& worldToView, float m5) override; int GetNextQueryIndex() override; @@ -91,7 +92,6 @@ protected: void WaitForStreamBuffers(); void RunZMinMaxPass(); - void ApplyLevelMesh(); void ApplyLevelMeshPipeline(VulkanCommandBuffer* cmdbuffer, VkPipelineKey pipelineKey, LevelMeshDrawType drawType, bool noFragmentShader); VulkanRenderDevice* fb = nullptr; @@ -107,6 +107,8 @@ protected: bool mNeedApply = true; bool mDrawLine = false; + int mLevelMeshPipelineID = -1; + int mScissorX = 0, mScissorY = 0, mScissorWidth = -1, mScissorHeight = -1; int mViewportX = 0, mViewportY = 0, mViewportWidth = -1, mViewportHeight = -1; float mViewportDepthMin = 0.0f, mViewportDepthMax = 1.0f; diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp index 84fb6dc84..8db7c348e 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.cpp +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.cpp @@ -704,19 +704,27 @@ void HWDrawInfo::RenderScene(FRenderState &state) state.EnableBrightmap(true); // To do: replace this is classic light lists + state.ApplyLevelMesh(); DrawSeenSides(state, LevelMeshDrawType::Opaque, true); DrawSeenFlats(state, LevelMeshDrawType::Opaque, true); state.DispatchLightTiles(VPUniforms.mViewMatrix, VPUniforms.mProjectionMatrix.get()[5]); + state.ApplyLevelMesh(); DrawSeenSides(state, LevelMeshDrawType::Opaque, false); drawlists[GLDL_PLAINWALLS].DrawWalls(this, state, false); + + state.ApplyLevelMesh(); DrawSeenFlats(state, LevelMeshDrawType::Opaque, false); drawlists[GLDL_PLAINFLATS].DrawFlats(this, state, false); // Part 2: masked geometry. This is set up so that only pixels with alpha>gl_mask_threshold will show state.AlphaFunc(Alpha_GEqual, gl_mask_threshold); + + state.ApplyLevelMesh(); DrawSeenSides(state, LevelMeshDrawType::Masked, false); drawlists[GLDL_MASKEDWALLS].DrawWalls(this, state, false); + + state.ApplyLevelMesh(); DrawSeenFlats(state, LevelMeshDrawType::Masked, false); drawlists[GLDL_MASKEDFLATS].DrawFlats(this, state, false); @@ -772,6 +780,7 @@ void HWDrawInfo::RenderTranslucent(FRenderState &state) state.SetDepthMask(false); // To do: this needs to be sorted + state.ApplyLevelMesh(); DrawSeenSides(state, LevelMeshDrawType::Translucent, false); DrawSeenFlats(state, LevelMeshDrawType::Translucent, false);