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.
This commit is contained in:
baldurk
2019-10-30 15:33:21 +00:00
parent 0b15b8b5ce
commit c497446524
6 changed files with 43 additions and 49 deletions
+1 -4
View File
@@ -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)
+1 -2
View File
@@ -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;
}
+7 -16
View File
@@ -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));
+22 -10
View File
@@ -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);
+6 -14
View File
@@ -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;
+6 -3
View File
@@ -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;