From c49744652449bf33ce4e9b6f401c477d4c3405e1 Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 30 Oct 2019 15:33:21 +0000 Subject: [PATCH] Simplify D3D texture render shader parameters, fix scaling bug in D3D12 * We previously relied on setting the viewport smaller than the output dimensions in D3D11 to scale for lower mips. In D3D12 the viewport is set to the output dimensions internally so we can't do that, so instead apply a manual scale. --- renderdoc/data/hlsl/hlsl_cbuffers.h | 5 +-- renderdoc/data/hlsl/texdisplay.hlsl | 3 +- .../driver/d3d11/d3d11_rendertexture.cpp | 23 ++++--------- renderdoc/driver/d3d11/d3d11_replay.cpp | 32 +++++++++++++------ .../driver/d3d12/d3d12_rendertexture.cpp | 20 ++++-------- renderdoc/driver/d3d12/d3d12_replay.cpp | 9 ++++-- 6 files changed, 43 insertions(+), 49 deletions(-) diff --git a/renderdoc/data/hlsl/hlsl_cbuffers.h b/renderdoc/data/hlsl/hlsl_cbuffers.h index f4cbbbfdd..f8e8661e4 100644 --- a/renderdoc/data/hlsl/hlsl_cbuffers.h +++ b/renderdoc/data/hlsl/hlsl_cbuffers.h @@ -57,10 +57,7 @@ cbuffer FontCBuffer REG(b0) cbuffer TexDisplayVSCBuffer REG(b0) { float2 Position; - float2 TextureResolution; - - float2 ScreenAspect; - float Scale; + float2 VertexScale; }; cbuffer TexDisplayPSCBuffer REG(b0) diff --git a/renderdoc/data/hlsl/texdisplay.hlsl b/renderdoc/data/hlsl/texdisplay.hlsl index 8d423b2b9..8f479d079 100644 --- a/renderdoc/data/hlsl/texdisplay.hlsl +++ b/renderdoc/data/hlsl/texdisplay.hlsl @@ -50,8 +50,7 @@ v2f RENDERDOC_TexDisplayVS(uint vertID : SV_VertexID) float2 pos = positions[vertID]; - OUT.pos = float4(Position.xy + pos.xy * TextureResolution.xy * Scale * ScreenAspect.xy, 0, 1) - - float4(1.0, -1.0, 0, 0); + OUT.pos = float4(Position.xy + pos.xy * VertexScale.xy, 0, 1) - float4(1.0, -1.0, 0, 0); OUT.tex.xy = float2(pos.x, -pos.y); return OUT; } diff --git a/renderdoc/driver/d3d11/d3d11_rendertexture.cpp b/renderdoc/driver/d3d11/d3d11_rendertexture.cpp index d591cb8a1..c070cea0e 100644 --- a/renderdoc/driver/d3d11/d3d11_rendertexture.cpp +++ b/renderdoc/driver/d3d11/d3d11_rendertexture.cpp @@ -479,13 +479,6 @@ bool D3D11Replay::RenderTextureInternal(TextureDisplay cfg, bool blendAlpha) vertexData.Position.x = x * (2.0f / m_OutputWidth); vertexData.Position.y = -y * (2.0f / m_OutputHeight); - vertexData.ScreenAspect.x = - (m_OutputHeight / m_OutputWidth); // 0.5 = character width / character height - vertexData.ScreenAspect.y = 1.0f; - - vertexData.TextureResolution.x = 1.0f / vertexData.ScreenAspect.x; - vertexData.TextureResolution.y = 1.0f; - if(cfg.rangeMax <= cfg.rangeMin) cfg.rangeMax += 0.00001f; @@ -534,9 +527,6 @@ bool D3D11Replay::RenderTextureInternal(TextureDisplay cfg, bool blendAlpha) float tex_x = float(details.texWidth); float tex_y = float(details.texType == eTexType_1D ? 100 : details.texHeight); - vertexData.TextureResolution.x *= tex_x / m_OutputWidth; - vertexData.TextureResolution.y *= tex_y / m_OutputHeight; - pixelData.TextureResolutionPS.x = float(RDCMAX(1U, details.texWidth >> cfg.mip)); pixelData.TextureResolutionPS.y = float(RDCMAX(1U, details.texHeight >> cfg.mip)); pixelData.TextureResolutionPS.z = float(RDCMAX(1U, details.texDepth >> cfg.mip)); @@ -544,7 +534,6 @@ bool D3D11Replay::RenderTextureInternal(TextureDisplay cfg, bool blendAlpha) if(details.texArraySize > 1 && details.texType != eTexType_3D) pixelData.TextureResolutionPS.z = float(details.texArraySize); - vertexData.Scale = cfg.scale; pixelData.ScalePS = cfg.scale; pixelData.YUVDownsampleRate = details.YUVDownsampleRate; @@ -555,20 +544,24 @@ bool D3D11Replay::RenderTextureInternal(TextureDisplay cfg, bool blendAlpha) float xscale = m_OutputWidth / tex_x; float yscale = m_OutputHeight / tex_y; - vertexData.Scale = RDCMIN(xscale, yscale); + cfg.scale = RDCMIN(xscale, yscale); if(yscale > xscale) { vertexData.Position.x = 0; - vertexData.Position.y = tex_y * vertexData.Scale / m_OutputHeight - 1.0f; + vertexData.Position.y = tex_y * cfg.scale / m_OutputHeight - 1.0f; } else { vertexData.Position.y = 0; - vertexData.Position.x = 1.0f - tex_x * vertexData.Scale / m_OutputWidth; + vertexData.Position.x = 1.0f - tex_x * cfg.scale / m_OutputWidth; } } + // normalisation factor for output * selected scale * viewport scale + vertexData.VertexScale.x = (tex_x / m_OutputWidth) * cfg.scale * 2.0f; + vertexData.VertexScale.y = (tex_y / m_OutputHeight) * cfg.scale * 2.0f; + ID3D11PixelShader *customPS = NULL; ID3D11Buffer *customBuff = NULL; @@ -708,8 +701,6 @@ bool D3D11Replay::RenderTextureInternal(TextureDisplay cfg, bool blendAlpha) } } - vertexData.Scale *= 2.0f; // viewport is -1 -> 1 - pixelData.MipLevel = (float)cfg.mip; pixelData.OutputDisplayFormat = RESTYPE_TEX2D; pixelData.Slice = float(RDCCLAMP(cfg.sliceFace, 0U, details.texArraySize - 1)); diff --git a/renderdoc/driver/d3d11/d3d11_replay.cpp b/renderdoc/driver/d3d11/d3d11_replay.cpp index 7b7ba3b76..03ca7007f 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.cpp +++ b/renderdoc/driver/d3d11/d3d11_replay.cpp @@ -1945,10 +1945,11 @@ void D3D11Replay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; m_pImmediateContext->ClearRenderTargetView(rtv, color); - D3D11_VIEWPORT viewport = {0, 0, (float)(desc.Width >> mip), 1.0f, 0.0f, 1.0f}; - - SetOutputDimensions(desc.Width, 1); + D3D11_VIEWPORT viewport = { + 0, 0, (float)desc.Width, 1.0f, 0.0f, 1.0f, + }; m_pImmediateContext->RSSetViewports(1, &viewport); + SetOutputDimensions(desc.Width, 1); { TextureDisplay texDisplay; @@ -1964,13 +1965,16 @@ void D3D11Replay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip texDisplay.sliceFace = arrayIdx; texDisplay.rangeMin = params.blackPoint; texDisplay.rangeMax = params.whitePoint; - texDisplay.scale = 1.0f; texDisplay.resourceId = tex; texDisplay.typeHint = params.typeHint; texDisplay.rawOutput = false; texDisplay.xOffset = 0; texDisplay.yOffset = 0; + // we scale our texture rendering by output dimension. To counteract that, add a manual + // scale here + texDisplay.scale = 1.0f / float(1 << mip); + RenderTextureInternal(texDisplay, false); } @@ -2092,8 +2096,9 @@ void D3D11Replay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip float color[4] = {0.0f, 0.0f, 0.0f, 0.0f}; m_pImmediateContext->ClearRenderTargetView(rtv, color); - D3D11_VIEWPORT viewport = {0, 0, (float)(desc.Width >> mip), (float)(desc.Height >> mip), - 0.0f, 1.0f}; + D3D11_VIEWPORT viewport = { + 0, 0, (float)desc.Width, (float)desc.Height, 0.0f, 1.0f, + }; SetOutputDimensions(desc.Width, desc.Height); m_pImmediateContext->RSSetViewports(1, &viewport); @@ -2114,13 +2119,16 @@ void D3D11Replay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip texDisplay.sliceFace /= sampleCount; texDisplay.rangeMin = params.blackPoint; texDisplay.rangeMax = params.whitePoint; - texDisplay.scale = 1.0f; texDisplay.resourceId = tex; texDisplay.typeHint = params.typeHint; texDisplay.rawOutput = false; texDisplay.xOffset = 0; texDisplay.yOffset = 0; + // we scale our texture rendering by output dimension. To counteract that, add a manual + // scale here + texDisplay.scale = 1.0f / float(1 << mip); + RenderTextureInternal(texDisplay, false); } @@ -2239,8 +2247,9 @@ void D3D11Replay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip ID3D11RenderTargetView *wrappedrtv = NULL; ID3D11RenderTargetView *rtv = NULL; - D3D11_VIEWPORT viewport = {0, 0, (float)(desc.Width >> mip), (float)(desc.Height >> mip), - 0.0f, 1.0f}; + D3D11_VIEWPORT viewport = { + 0, 0, (float)desc.Width, (float)desc.Height, 0.0f, 1.0f, + }; for(UINT i = 0; i < (desc.Depth >> mip); i++) { @@ -2276,13 +2285,16 @@ void D3D11Replay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip texDisplay.sliceFace = i << mip; texDisplay.rangeMin = params.blackPoint; texDisplay.rangeMax = params.whitePoint; - texDisplay.scale = 1.0f; texDisplay.resourceId = tex; texDisplay.typeHint = params.typeHint; texDisplay.rawOutput = false; texDisplay.xOffset = 0; texDisplay.yOffset = 0; + // we scale our texture rendering by output dimension. To counteract that, add a manual + // scale here + texDisplay.scale = 1.0f / float(1 << mip); + RenderTextureInternal(texDisplay, false); SAFE_RELEASE(wrappedrtv); diff --git a/renderdoc/driver/d3d12/d3d12_rendertexture.cpp b/renderdoc/driver/d3d12/d3d12_rendertexture.cpp index 69953a0ee..335edc839 100644 --- a/renderdoc/driver/d3d12/d3d12_rendertexture.cpp +++ b/renderdoc/driver/d3d12/d3d12_rendertexture.cpp @@ -367,12 +367,6 @@ bool D3D12Replay::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, Texture vertexData.Position.x = x * (2.0f / m_OutputWidth); vertexData.Position.y = -y * (2.0f / m_OutputHeight); - vertexData.ScreenAspect.x = m_OutputHeight / m_OutputWidth; - vertexData.ScreenAspect.y = 1.0f; - - vertexData.TextureResolution.x = 1.0f / vertexData.ScreenAspect.x; - vertexData.TextureResolution.y = 1.0f; - if(cfg.rangeMax <= cfg.rangeMin) cfg.rangeMax += 0.00001f; @@ -417,9 +411,6 @@ bool D3D12Replay::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, Texture float tex_y = float(resourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D ? 100 : resourceDesc.Height); - vertexData.TextureResolution.x *= tex_x / m_OutputWidth; - vertexData.TextureResolution.y *= tex_y / m_OutputHeight; - pixelData.TextureResolutionPS.x = float(RDCMAX(1U, uint32_t(resourceDesc.Width >> cfg.mip))); pixelData.TextureResolutionPS.y = float(RDCMAX(1U, uint32_t(resourceDesc.Height >> cfg.mip))); pixelData.TextureResolutionPS.z = @@ -428,7 +419,6 @@ bool D3D12Replay::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, Texture if(resourceDesc.DepthOrArraySize > 1 && resourceDesc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D) pixelData.TextureResolutionPS.z = float(resourceDesc.DepthOrArraySize); - vertexData.Scale = cfg.scale; pixelData.ScalePS = cfg.scale; if(cfg.scale <= 0.0f) @@ -436,21 +426,23 @@ bool D3D12Replay::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, Texture float xscale = m_OutputWidth / tex_x; float yscale = m_OutputHeight / tex_y; - vertexData.Scale = RDCMIN(xscale, yscale); + cfg.scale = RDCMIN(xscale, yscale); if(yscale > xscale) { vertexData.Position.x = 0; - vertexData.Position.y = tex_y * vertexData.Scale / m_OutputHeight - 1.0f; + vertexData.Position.y = tex_y * cfg.scale / m_OutputHeight - 1.0f; } else { vertexData.Position.y = 0; - vertexData.Position.x = 1.0f - tex_x * vertexData.Scale / m_OutputWidth; + vertexData.Position.x = 1.0f - tex_x * cfg.scale / m_OutputWidth; } } - vertexData.Scale *= 2.0f; // viewport is -1 -> 1 + // normalisation factor for output * selected scale * viewport scale + vertexData.VertexScale.x = (tex_x / m_OutputWidth) * cfg.scale * 2.0f; + vertexData.VertexScale.y = (tex_y / m_OutputHeight) * cfg.scale * 2.0f; pixelData.MipLevel = (float)cfg.mip; pixelData.OutputDisplayFormat = RESTYPE_TEX2D; diff --git a/renderdoc/driver/d3d12/d3d12_replay.cpp b/renderdoc/driver/d3d12/d3d12_replay.cpp index 67620ba47..4b916e8e3 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.cpp +++ b/renderdoc/driver/d3d12/d3d12_replay.cpp @@ -3066,6 +3066,8 @@ void D3D12Replay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip if(copyDesc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D) copyDesc.DepthOrArraySize = 1; + SetOutputDimensions(uint32_t(copyDesc.Width), copyDesc.Height); + copyDesc.Width = RDCMAX(1ULL, copyDesc.Width >> mip); copyDesc.Height = RDCMAX(1U, copyDesc.Height >> mip); @@ -3075,8 +3077,6 @@ void D3D12Replay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip __uuidof(ID3D12Resource), (void **)&remapTexture); RDCASSERTEQUAL(hr, S_OK); - SetOutputDimensions(uint32_t(copyDesc.Width), copyDesc.Height); - TexDisplayFlags flags = IsSRGBFormat(copyDesc.Format) ? eTexDisplay_None : eTexDisplay_LinearRender; @@ -3128,13 +3128,16 @@ void D3D12Replay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip texDisplay.sliceFace /= sampleCount; texDisplay.rangeMin = params.blackPoint; texDisplay.rangeMax = params.whitePoint; - texDisplay.scale = 1.0f; texDisplay.resourceId = tex; texDisplay.typeHint = CompType::Typeless; texDisplay.rawOutput = false; texDisplay.xOffset = 0; texDisplay.yOffset = 0; + // we scale our texture rendering by output dimension. To counteract that, add a manual + // scale here + texDisplay.scale = 1.0f / float(1 << mip); + if(copyDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) texDisplay.sliceFace = loop << mip;