From c10089c94bf9be14b65d80444e961f9cfee18bbf Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 6 Jul 2020 11:20:23 +0100 Subject: [PATCH] Invert y display for vulkan with negative viewport height. Closes #1971 --- qrenderdoc/Windows/BufferViewer.cpp | 7 +++++++ renderdoc/api/replay/control_types.h | 3 +++ renderdoc/driver/d3d11/d3d11_rendermesh.cpp | 5 +++++ renderdoc/driver/d3d12/d3d12_rendermesh.cpp | 5 +++++ renderdoc/driver/gl/gl_rendermesh.cpp | 5 +++++ renderdoc/driver/vulkan/vk_postvs.cpp | 6 ++++++ renderdoc/driver/vulkan/vk_rendermesh.cpp | 5 +++++ renderdoc/driver/vulkan/vk_replay.h | 1 + 8 files changed, 37 insertions(+) diff --git a/qrenderdoc/Windows/BufferViewer.cpp b/qrenderdoc/Windows/BufferViewer.cpp index 12f25e43f..268060b78 100644 --- a/qrenderdoc/Windows/BufferViewer.cpp +++ b/qrenderdoc/Windows/BufferViewer.cpp @@ -3811,11 +3811,18 @@ void BufferViewer::camGuess_changed(double value) // use estimates from post vs data (calculated from vertex position data) if the user // hasn't overridden the values m_Config.position.nearPlane = 0.1f; + m_Config.position.flipY = false; if(m_CurStage == MeshDataStage::VSOut) + { m_Config.position.nearPlane = m_PostVS.nearPlane; + m_Config.position.flipY = m_PostVS.flipY; + } else if(m_CurStage == MeshDataStage::GSOut) + { m_Config.position.nearPlane = m_PostGS.nearPlane; + m_Config.position.flipY = m_PostGS.flipY; + } if(ui->nearGuess->value() > 0.0) m_Config.position.nearPlane = ui->nearGuess->value(); diff --git a/renderdoc/api/replay/control_types.h b/renderdoc/api/replay/control_types.h index c76794fef..88e389098 100644 --- a/renderdoc/api/replay/control_types.h +++ b/renderdoc/api/replay/control_types.h @@ -84,6 +84,9 @@ struct MeshFormat DOCUMENT("``True`` if this mesh element contains post-projection positional data."); bool unproject = false; + DOCUMENT("``True`` if there is an implicit Y-flip to account for in the projection."); + bool flipY = false; + DOCUMENT("``True`` if this mesh element comes from instanced data. See :data:`instStepRate`."); bool instanced = false; diff --git a/renderdoc/driver/d3d11/d3d11_rendermesh.cpp b/renderdoc/driver/d3d11/d3d11_rendermesh.cpp index 1b236b159..c7b7dc8c5 100644 --- a/renderdoc/driver/d3d11/d3d11_rendermesh.cpp +++ b/renderdoc/driver/d3d11/d3d11_rendermesh.cpp @@ -142,6 +142,11 @@ void D3D11Replay::RenderMesh(uint32_t eventId, const rdcarray &secon guessProj = Matrix4f::Orthographic(cfg.position.nearPlane, cfg.position.farPlane); } + if(cfg.position.flipY) + { + guessProj[5] *= -1.0f; + } + guessProjInv = guessProj.Inverse(); vertexData.ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv)); diff --git a/renderdoc/driver/d3d12/d3d12_rendermesh.cpp b/renderdoc/driver/d3d12/d3d12_rendermesh.cpp index 1f9ab259f..b67106ae1 100644 --- a/renderdoc/driver/d3d12/d3d12_rendermesh.cpp +++ b/renderdoc/driver/d3d12/d3d12_rendermesh.cpp @@ -285,6 +285,11 @@ void D3D12Replay::RenderMesh(uint32_t eventId, const rdcarray &secon guessProj = Matrix4f::Orthographic(cfg.position.nearPlane, cfg.position.farPlane); } + if(cfg.position.flipY) + { + guessProj[5] *= -1.0f; + } + guessProjInv = guessProj.Inverse(); vertexData.ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv)); diff --git a/renderdoc/driver/gl/gl_rendermesh.cpp b/renderdoc/driver/gl/gl_rendermesh.cpp index 62164b0e5..58cc7ec7e 100644 --- a/renderdoc/driver/gl/gl_rendermesh.cpp +++ b/renderdoc/driver/gl/gl_rendermesh.cpp @@ -98,6 +98,11 @@ void GLReplay::RenderMesh(uint32_t eventId, const rdcarray &secondar guessProj = Matrix4f::Orthographic(cfg.position.nearPlane, cfg.position.farPlane); } + if(cfg.position.flipY) + { + guessProj[5] *= -1.0f; + } + guessProjInv = guessProj.Inverse(); ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv)); diff --git a/renderdoc/driver/vulkan/vk_postvs.cpp b/renderdoc/driver/vulkan/vk_postvs.cpp index 832e2ac29..216326614 100644 --- a/renderdoc/driver/vulkan/vk_postvs.cpp +++ b/renderdoc/driver/vulkan/vk_postvs.cpp @@ -1230,6 +1230,7 @@ void VulkanReplay::FetchVSOut(uint32_t eventId, VulkanRenderState &state) m_PostVS.Data[eventId].vsout.farPlane = 0.0f; m_PostVS.Data[eventId].vsout.useIndices = false; m_PostVS.Data[eventId].vsout.hasPosOut = false; + m_PostVS.Data[eventId].vsout.flipY = false; m_PostVS.Data[eventId].vsout.idxbuf = VK_NULL_HANDLE; m_PostVS.Data[eventId].vsout.idxbufmem = VK_NULL_HANDLE; @@ -2346,6 +2347,7 @@ void VulkanReplay::FetchVSOut(uint32_t eventId, VulkanRenderState &state) m_PostVS.Data[eventId].vsout.hasPosOut = refl->outputSignature[0].systemValue == ShaderBuiltin::Position; + m_PostVS.Data[eventId].vsout.flipY = state.views[0].height < 0.0f; // delete descriptors. Technically we don't have to free the descriptor sets, but our tracking on // replay doesn't handle destroying children of pooled objects so we do it explicitly anyway. @@ -2386,6 +2388,7 @@ void VulkanReplay::FetchTessGSOut(uint32_t eventId, VulkanRenderState &state) m_PostVS.Data[eventId].gsout.farPlane = 0.0f; m_PostVS.Data[eventId].gsout.useIndices = false; m_PostVS.Data[eventId].gsout.hasPosOut = false; + m_PostVS.Data[eventId].gsout.flipY = false; m_PostVS.Data[eventId].gsout.idxbuf = VK_NULL_HANDLE; m_PostVS.Data[eventId].gsout.idxbufmem = VK_NULL_HANDLE; } @@ -2447,6 +2450,7 @@ void VulkanReplay::FetchTessGSOut(uint32_t eventId, VulkanRenderState &state) m_PostVS.Data[eventId].gsout.farPlane = 0.0f; m_PostVS.Data[eventId].gsout.useIndices = false; m_PostVS.Data[eventId].gsout.hasPosOut = false; + m_PostVS.Data[eventId].gsout.flipY = false; m_PostVS.Data[eventId].gsout.idxbuf = VK_NULL_HANDLE; m_PostVS.Data[eventId].gsout.idxbufmem = VK_NULL_HANDLE; return; @@ -2898,6 +2902,7 @@ void VulkanReplay::FetchTessGSOut(uint32_t eventId, VulkanRenderState &state) m_PostVS.Data[eventId].gsout.idxbufmem = VK_NULL_HANDLE; m_PostVS.Data[eventId].gsout.hasPosOut = true; + m_PostVS.Data[eventId].gsout.flipY = state.views[0].height < 0.0f; // delete framebuffer and renderpass m_pDriver->vkDestroyFramebuffer(dev, fb, NULL); @@ -3089,6 +3094,7 @@ MeshFormat VulkanReplay::GetPostVSBuffers(uint32_t eventId, uint32_t instID, uin ret.unproject = s.hasPosOut; ret.nearPlane = s.nearPlane; ret.farPlane = s.farPlane; + ret.flipY = s.flipY; if(instID < s.instData.size()) { diff --git a/renderdoc/driver/vulkan/vk_rendermesh.cpp b/renderdoc/driver/vulkan/vk_rendermesh.cpp index a865216db..da4a1040c 100644 --- a/renderdoc/driver/vulkan/vk_rendermesh.cpp +++ b/renderdoc/driver/vulkan/vk_rendermesh.cpp @@ -498,6 +498,11 @@ void VulkanReplay::RenderMesh(uint32_t eventId, const rdcarray &seco guessProj = Matrix4f::Orthographic(cfg.position.nearPlane, cfg.position.farPlane); } + if(cfg.position.flipY) + { + guessProj[5] *= -1.0f; + } + guessProjInv = guessProj.Inverse(); ModelViewProj = projMat.Mul(camMat.Mul(guessProjInv)); diff --git a/renderdoc/driver/vulkan/vk_replay.h b/renderdoc/driver/vulkan/vk_replay.h index 1380db8e4..45151f04e 100644 --- a/renderdoc/driver/vulkan/vk_replay.h +++ b/renderdoc/driver/vulkan/vk_replay.h @@ -172,6 +172,7 @@ struct VulkanPostVSData VkIndexType idxFmt; bool hasPosOut; + bool flipY; float nearPlane; float farPlane;