Be more precise with texture remapping to handle integer textures

This commit is contained in:
baldurk
2019-11-20 11:59:37 +00:00
parent 45144ed478
commit edc8fb6bd6
31 changed files with 646 additions and 165 deletions
+1
View File
@@ -376,6 +376,7 @@ set(data
data/glsl/quadresolve.frag
data/glsl/quadwrite.frag
data/glsl/texdisplay.frag
data/glsl/texremap.frag
data/glsl/gl_texsample.h
data/glsl/gles_texsample.h
data/glsl/vk_texsample.h
+68 -37
View File
@@ -2151,64 +2151,89 @@ void ReplayProxy::RemapProxyTextureIfNeeded(TextureDescription &tex, GetTextureD
switch(tex.format.type)
{
case ResourceFormatType::S8:
case ResourceFormatType::D16S8: params.remap = RemapTexture::D32S8; break;
case ResourceFormatType::ASTC: params.remap = RemapTexture::RGBA16; break;
case ResourceFormatType::D16S8:
case ResourceFormatType::D24S8:
case ResourceFormatType::D32S8:
tex.format.compType = CompType::Float;
params.remap = RemapTexture::RGBA32;
tex.creationFlags &= ~TextureCategory::DepthTarget;
break;
case ResourceFormatType::A8:
tex.format.compType = CompType::UNorm;
params.remap = RemapTexture::RGBA8;
break;
case ResourceFormatType::BC1:
case ResourceFormatType::BC2:
case ResourceFormatType::BC3:
case ResourceFormatType::BC4:
case ResourceFormatType::BC5:
tex.format.compType = CompType::UNorm;
params.remap = RemapTexture::RGBA8;
break;
case ResourceFormatType::BC6:
tex.format.compType = CompType::Float;
params.remap = RemapTexture::RGBA16;
break;
case ResourceFormatType::BC7:
tex.format.compType = CompType::UNorm;
params.remap = RemapTexture::RGBA16;
break;
case ResourceFormatType::ASTC:
tex.format.compType = CompType::Float;
params.remap = RemapTexture::RGBA16;
break;
case ResourceFormatType::EAC:
case ResourceFormatType::R5G6B5:
case ResourceFormatType::R5G5B5A1:
case ResourceFormatType::R4G4:
case ResourceFormatType::R4G4B4A4:
case ResourceFormatType::ETC2: params.remap = RemapTexture::RGBA8; break;
case ResourceFormatType::R10G10B10A2: params.remap = RemapTexture::RGBA16; break;
default:
RDCERR("Don't know how to remap resource format type %u, falling back to RGBA32",
tex.format.type);
tex.format.compType = CompType::Float;
params.remap = RemapTexture::RGBA32;
break;
}
tex.format.type = ResourceFormatType::Regular;
}
else
{
if(tex.format.compByteWidth == 4)
params.remap = RemapTexture::RGBA32;
if(tex.format.compByteWidth == 1)
params.remap = RemapTexture::RGBA8;
else if(tex.format.compByteWidth == 2)
params.remap = RemapTexture::RGBA16;
else if(tex.format.compByteWidth == 1)
params.remap = RemapTexture::RGBA8;
else
params.remap = RemapTexture::RGBA32;
if(tex.format.compType == CompType::Depth)
tex.format.compType = CompType::Float;
}
// since the texture type is unsupported, remove the BGRAOrder() flag and remap it to RGBA
if(tex.format.BGRAOrder() && m_APIProps.localRenderer == GraphicsAPI::OpenGL)
tex.format.SetBGRAOrder(false);
tex.format.SetBGRAOrder(false);
tex.format.type = ResourceFormatType::Regular;
tex.format.compCount = 4;
switch(params.remap)
{
case RemapTexture::NoRemap: RDCERR("IsTextureSupported == false, but we have no remap"); break;
case RemapTexture::RGBA8:
tex.format.compCount = 4;
tex.format.compByteWidth = 1;
if(tex.format.compType != CompType::UNormSRGB)
tex.format.compType = CompType::UNorm;
// Range adaptation is only needed when remapping a higher precision format down to RGBA8.
params.whitePoint = 1.0f;
break;
case RemapTexture::RGBA16:
tex.format.compCount = 4;
tex.format.compByteWidth = 2;
tex.format.compType = CompType::Float;
break;
case RemapTexture::RGBA32:
tex.format.compCount = 4;
tex.format.compByteWidth = 4;
tex.format.compType = CompType::Float;
break;
case RemapTexture::D32S8: RDCERR("Remapping depth/stencil formats not implemented."); break;
case RemapTexture::RGBA8: tex.format.compByteWidth = 1; break;
case RemapTexture::RGBA16: tex.format.compByteWidth = 2; break;
case RemapTexture::RGBA32: tex.format.compByteWidth = 4; break;
}
}
void ReplayProxy::EnsureTexCached(ResourceId texid, const Subresource &sub)
void ReplayProxy::EnsureTexCached(ResourceId &texid, CompType typeCast, const Subresource &sub)
{
if(m_Reader.IsErrored() || m_Writer.IsErrored())
return;
if(m_LocalTextures.find(texid) != m_LocalTextures.end())
return;
if(texid == ResourceId())
return;
TextureCacheEntry entry = {texid, sub};
// ignore parameters in the key which don't matter for this texture
@@ -2227,12 +2252,11 @@ void ReplayProxy::EnsureTexCached(ResourceId texid, const Subresource &sub)
}
}
if(m_LocalTextures.find(texid) != m_LocalTextures.end())
return;
auto proxyit = m_ProxyTextures.find(texid);
if(m_TextureProxyCache.find(entry) == m_TextureProxyCache.end())
{
if(m_ProxyTextures.find(texid) == m_ProxyTextures.end())
if(proxyit == m_ProxyTextures.end())
{
TextureDescription tex = GetTexture(texid);
@@ -2241,10 +2265,10 @@ void ReplayProxy::EnsureTexCached(ResourceId texid, const Subresource &sub)
proxy.id = m_Proxy->CreateProxyTexture(tex);
proxy.msSamp = RDCMAX(1U, tex.msSamp);
m_ProxyTextures[texid] = proxy;
proxyit = m_ProxyTextures.insert(std::make_pair(texid, proxy)).first;
}
const ProxyTextureProperties &proxy = m_ProxyTextures[texid];
const ProxyTextureProperties &proxy = proxyit->second;
for(uint32_t sample = 0; sample < proxy.msSamp; sample++)
{
@@ -2253,10 +2277,14 @@ void ReplayProxy::EnsureTexCached(ResourceId texid, const Subresource &sub)
TextureCacheEntry sampleArrayEntry = {texid, s};
GetTextureDataParams params = proxy.params;
params.typeCast = typeCast;
#if ENABLED(TRANSFER_RESOURCE_CONTENTS_DELTAS)
CacheTextureData(texid, s, proxy.params);
CacheTextureData(texid, s, params);
#else
GetTextureData(texid, s, proxy.params, m_ProxyTextureData[entry]);
GetTextureData(texid, s, params, m_ProxyTextureData[entry]);
#endif
auto it = m_ProxyTextureData.find(sampleArrayEntry);
@@ -2266,6 +2294,9 @@ void ReplayProxy::EnsureTexCached(ResourceId texid, const Subresource &sub)
m_TextureProxyCache.insert(entry);
}
// change texid to the proxy texture's ID for passing to our proxy renderer
texid = proxyit->second.id;
}
void ReplayProxy::EnsureBufCached(ResourceId bufid)
+21 -19
View File
@@ -249,10 +249,10 @@ public:
{
if(m_Proxy)
{
EnsureTexCached(cfg.resourceId, cfg.subresource);
if(cfg.resourceId == ResourceId() || m_ProxyTextures[cfg.resourceId] == ResourceId())
EnsureTexCached(cfg.resourceId, cfg.typeCast, cfg.subresource);
if(cfg.resourceId == ResourceId())
return false;
cfg.resourceId = m_ProxyTextures[cfg.resourceId];
// due to OpenGL having origin bottom-left compared to the rest of the world,
// we need to flip going in or out of GL.
@@ -273,11 +273,10 @@ public:
{
if(m_Proxy)
{
EnsureTexCached(texture, sub);
if(texture == ResourceId() || m_ProxyTextures[texture] == ResourceId())
return;
EnsureTexCached(texture, typeCast, sub);
texture = m_ProxyTextures[texture];
if(texture == ResourceId())
return;
// due to OpenGL having origin bottom-left compared to the rest of the world,
// we need to flip going in or out of GL.
@@ -300,10 +299,12 @@ public:
{
if(m_Proxy)
{
EnsureTexCached(texid, sub);
if(texid == ResourceId() || m_ProxyTextures[texid] == ResourceId())
EnsureTexCached(texid, typeCast, sub);
if(texid == ResourceId())
return false;
return m_Proxy->GetMinMax(m_ProxyTextures[texid], sub, typeCast, minval, maxval);
return m_Proxy->GetMinMax(texid, sub, typeCast, minval, maxval);
}
return false;
@@ -314,11 +315,12 @@ public:
{
if(m_Proxy)
{
EnsureTexCached(texid, sub);
if(texid == ResourceId() || m_ProxyTextures[texid] == ResourceId())
EnsureTexCached(texid, typeCast, sub);
if(texid == ResourceId())
return false;
return m_Proxy->GetHistogram(m_ProxyTextures[texid], sub, typeCast, minval, maxval, channels,
histogram);
return m_Proxy->GetHistogram(texid, sub, typeCast, minval, maxval, channels, histogram);
}
return false;
@@ -436,10 +438,11 @@ public:
{
if(m_Proxy)
{
EnsureTexCached(texid, sub);
if(texid == ResourceId() || m_ProxyTextures[texid] == ResourceId())
EnsureTexCached(texid, typeCast, sub);
if(texid == ResourceId())
return ResourceId();
texid = m_ProxyTextures[texid];
ResourceId customResourceId = m_Proxy->ApplyCustomShader(shader, texid, sub, typeCast);
m_LocalTextures.insert(customResourceId);
m_ProxyTextures[customResourceId] = customResourceId;
@@ -572,7 +575,7 @@ public:
}
private:
void EnsureTexCached(ResourceId texid, const Subresource &sub);
void EnsureTexCached(ResourceId &texid, CompType typeCast, const Subresource &sub);
void RemapProxyTextureIfNeeded(TextureDescription &tex, GetTextureDataParams &params);
void EnsureBufCached(ResourceId bufid);
IMPLEMENT_FUNCTION_PROXIED(bool, NeedRemapForFetch, const ResourceFormat &format);
@@ -609,7 +612,6 @@ private:
ProxyTextureProperties() {}
// Create a proxy Id with the default get-data parameters.
ProxyTextureProperties(ResourceId proxyid) : id(proxyid) {}
operator ResourceId() const { return id; }
bool operator==(const ResourceId &other) const { return id == other; }
};
// this cache only exists on the client side, with the proxy renderer. It contains the created
+1
View File
@@ -58,5 +58,6 @@ DECLARE_EMBED(glsl_ms2array_comp);
DECLARE_EMBED(glsl_deptharr2ms_frag);
DECLARE_EMBED(glsl_depthms2arr_frag);
DECLARE_EMBED(glsl_gles_texsample_h);
DECLARE_EMBED(glsl_texremap_frag);
#undef DECLARE_EMBED
+86
View File
@@ -0,0 +1,86 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2019 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#if defined(OPENGL_ES)
#extension GL_EXT_texture_cube_map_array : enable
#extension GL_EXT_texture_buffer : enable
#endif
#define TEXDISPLAY_UBO
#include "glsl_ubos.h"
#if defined(VULKAN)
#include "vk_texsample.h"
#elif defined(OPENGL_ES)
#include "gles_texsample.h"
#elif defined(OPENGL)
#include "gl_texsample.h"
#endif
// for GLES compatibility where we must match blit.vert
IO_LOCATION(0) in vec2 uv;
#if UINT_TEX
IO_LOCATION(0) out uvec4 color_out;
#elif SINT_TEX
IO_LOCATION(0) out ivec4 color_out;
#else
IO_LOCATION(0) out vec4 color_out;
#endif
void main(void)
{
int texType = (texdisplay.OutputDisplayFormat & TEXDISPLAY_TYPEMASK);
// calc screen co-ords with origin top left, modified by Position
vec2 scr = gl_FragCoord.xy / texdisplay.TextureResolutionPS.xy;
#if UINT_TEX
color_out = SampleTextureUInt4(texType, scr, texdisplay.Slice, texdisplay.MipLevel,
texdisplay.SampleIdx, texdisplay.TextureResolutionPS);
#elif SINT_TEX
color_out = SampleTextureSInt4(texType, scr, texdisplay.Slice, texdisplay.MipLevel,
texdisplay.SampleIdx, texdisplay.TextureResolutionPS);
#else
color_out = SampleTextureFloat4(texType, scr, texdisplay.Slice, texdisplay.MipLevel,
texdisplay.SampleIdx, texdisplay.TextureResolutionPS,
texdisplay.YUVDownsampleRate, texdisplay.YUVAChannels);
#endif
if(texdisplay.Channels == vec4(1, 0, 0, 0))
{
color_out.y = color_out.x;
color_out.z = color_out.x;
color_out.w = color_out.x;
}
else if(texdisplay.Channels == vec4(0, 1, 0, 0))
{
color_out.x = color_out.y;
color_out.z = color_out.y;
color_out.w = color_out.y;
}
}
+51
View File
@@ -0,0 +1,51 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2019 Baldur Karlsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
#include "hlsl_cbuffers.h"
#include "hlsl_texsample.h"
struct v2f
{
float4 pos : SV_Position;
float4 tex : TEXCOORD0;
};
float4 RENDERDOC_TexRemapFloat(v2f IN) : SV_Target0
{
return SampleTextureFloat4(OutputDisplayFormat & TEXDISPLAY_TYPEMASK,
(ScalePS < 1 && MipLevel == 0), IN.tex.xy, Slice, MipLevel, SampleIdx,
TextureResolutionPS, YUVDownsampleRate, YUVAChannels);
}
uint4 RENDERDOC_TexRemapUInt(v2f IN) : SV_Target0
{
return SampleTextureUInt4(OutputDisplayFormat & TEXDISPLAY_TYPEMASK, IN.tex.xy, Slice, MipLevel,
SampleIdx, TextureResolutionPS);
}
int4 RENDERDOC_TexRemapSInt(v2f IN) : SV_Target0
{
return SampleTextureInt4(OutputDisplayFormat & TEXDISPLAY_TYPEMASK, IN.tex.xy, Slice, MipLevel,
SampleIdx, TextureResolutionPS);
}
+2
View File
@@ -112,6 +112,7 @@ RESOURCE_mesh_hlsl TYPE_EMBED "hlsl/mesh.hlsl"
RESOURCE_texdisplay_hlsl TYPE_EMBED "hlsl/texdisplay.hlsl"
RESOURCE_pixelhistory_hlsl TYPE_EMBED "hlsl/pixelhistory.hlsl"
RESOURCE_quadoverdraw_hlsl TYPE_EMBED "hlsl/quadoverdraw.hlsl"
RESOURCE_texremap_hlsl TYPE_EMBED "hlsl/texremap.hlsl"
RESOURCE_sourcecodepro_ttf TYPE_EMBED "sourcecodepro.ttf"
@@ -143,6 +144,7 @@ RESOURCE_glsl_gles_texsample_h TYPE_EMBED "glsl/gles_texsample.h"
RESOURCE_glsl_gltext_vert TYPE_EMBED "glsl/gltext.vert"
RESOURCE_glsl_gltext_frag TYPE_EMBED "glsl/gltext.frag"
RESOURCE_glsl_glsl_globals_h TYPE_EMBED "glsl/glsl_globals.h"
RESOURCE_glsl_texremap_frag TYPE_EMBED "glsl/texremap.frag"
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
+2
View File
@@ -15,6 +15,7 @@
#define RESOURCE_texdisplay_hlsl 108
#define RESOURCE_pixelhistory_hlsl 109
#define RESOURCE_quadoverdraw_hlsl 110
#define RESOURCE_texremap_hlsl 111
#define RESOURCE_sourcecodepro_ttf 301
@@ -46,6 +47,7 @@
#define RESOURCE_glsl_gltext_vert 429
#define RESOURCE_glsl_gltext_frag 430
#define RESOURCE_glsl_glsl_globals_h 440
#define RESOURCE_glsl_texremap_frag 441
// Next default values for new objects
//
+10
View File
@@ -480,6 +480,14 @@ void D3D11Replay::TextureRendering::Init(WrappedID3D11Device *device)
TexDisplayPS = shaderCache->MakePShader(hlsl.c_str(), "RENDERDOC_TexDisplayPS", "ps_5_0");
}
{
std::string hlsl = GetEmbeddedResource(texremap_hlsl);
TexRemapPS[0] = shaderCache->MakePShader(hlsl.c_str(), "RENDERDOC_TexRemapFloat", "ps_5_0");
TexRemapPS[1] = shaderCache->MakePShader(hlsl.c_str(), "RENDERDOC_TexRemapUInt", "ps_5_0");
TexRemapPS[2] = shaderCache->MakePShader(hlsl.c_str(), "RENDERDOC_TexRemapSInt", "ps_5_0");
}
{
D3D11_BLEND_DESC blendDesc;
RDCEraseEl(blendDesc);
@@ -539,6 +547,8 @@ void D3D11Replay::TextureRendering::Release()
SAFE_RELEASE(BlendState);
SAFE_RELEASE(TexDisplayVS);
SAFE_RELEASE(TexDisplayPS);
for(int i = 0; i < 3; i++)
SAFE_RELEASE(TexRemapPS[i]);
}
void D3D11Replay::OverlayRendering::Init(WrappedID3D11Device *device)
+18 -8
View File
@@ -449,12 +449,14 @@ TextureShaderDetails D3D11DebugManager::GetShaderDetails(ResourceId id, CompType
return details;
}
bool D3D11Replay::RenderTextureInternal(TextureDisplay cfg, bool blendAlpha)
bool D3D11Replay::RenderTextureInternal(TextureDisplay cfg, TexDisplayFlags flags)
{
TexDisplayVSCBuffer vertexData = {};
TexDisplayPSCBuffer pixelData = {};
HeatmapData heatmapData = {};
bool blendAlpha = (flags & eTexDisplay_BlendAlpha) != 0;
{
if(cfg.overlay == DebugOverlay::QuadOverdrawDraw || cfg.overlay == DebugOverlay::QuadOverdrawPass)
{
@@ -785,17 +787,25 @@ bool D3D11Replay::RenderTextureInternal(TextureDisplay cfg, bool blendAlpha)
m_pImmediateContext->RSSetState(m_General.RasterState);
if(customPS == NULL)
{
m_pImmediateContext->PSSetShader(m_TexRender.TexDisplayPS, NULL, 0);
m_pImmediateContext->PSSetConstantBuffers(0, 1, &psCBuffer);
m_pImmediateContext->PSSetConstantBuffers(1, 1, &psHeatCBuffer);
}
else
if(customPS)
{
m_pImmediateContext->PSSetShader(customPS, NULL, 0);
m_pImmediateContext->PSSetConstantBuffers(0, 1, &customBuff);
}
else
{
m_pImmediateContext->PSSetConstantBuffers(0, 1, &psCBuffer);
m_pImmediateContext->PSSetConstantBuffers(1, 1, &psHeatCBuffer);
if(flags & eTexDisplay_RemapFloat)
m_pImmediateContext->PSSetShader(m_TexRender.TexRemapPS[0], NULL, 0);
else if(flags & eTexDisplay_RemapUInt)
m_pImmediateContext->PSSetShader(m_TexRender.TexRemapPS[1], NULL, 0);
else if(flags & eTexDisplay_RemapSInt)
m_pImmediateContext->PSSetShader(m_TexRender.TexRemapPS[2], NULL, 0);
else
m_pImmediateContext->PSSetShader(m_TexRender.TexDisplayPS, NULL, 0);
}
ID3D11UnorderedAccessView *NullUAVs[D3D11_1_UAV_SLOT_COUNT] = {0};
UINT UAV_keepcounts[D3D11_1_UAV_SLOT_COUNT];
+53 -29
View File
@@ -1633,7 +1633,7 @@ void D3D11Replay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, const Su
texDisplay.xOffset = -float(x << sub.mip);
texDisplay.yOffset = -float(y << sub.mip);
RenderTextureInternal(texDisplay, false);
RenderTextureInternal(texDisplay, eTexDisplay_None);
}
D3D11_BOX box;
@@ -1962,16 +1962,17 @@ void D3D11Replay::GetTextureData(ResourceId tex, const Subresource &sub,
{
if(params.remap == RemapTexture::RGBA8)
{
desc.Format = IsSRGBFormat(desc.Format) ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
: DXGI_FORMAT_R8G8B8A8_UNORM;
if(IsSRGBFormat(desc.Format) && params.typeCast == CompType::Typeless)
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
desc.Format = GetTypedFormat(DXGI_FORMAT_R8G8B8A8_TYPELESS, params.typeCast);
}
else if(params.remap == RemapTexture::RGBA16)
{
desc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
desc.Format = GetTypedFormat(DXGI_FORMAT_R16G16B16A16_TYPELESS, params.typeCast);
}
else if(params.remap == RemapTexture::RGBA32)
{
desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
desc.Format = GetTypedFormat(DXGI_FORMAT_R32G32B32A32_TYPELESS, params.typeCast);
}
desc.ArraySize = 1;
@@ -2037,6 +2038,15 @@ void D3D11Replay::GetTextureData(ResourceId tex, const Subresource &sub,
m_pImmediateContext->RSSetViewports(1, &viewport);
SetOutputDimensions(desc.Width, 1);
TexDisplayFlags flags = eTexDisplay_None;
if(IsUIntFormat(desc.Format))
flags = eTexDisplay_RemapUInt;
else if(IsIntFormat(desc.Format))
flags = eTexDisplay_RemapSInt;
else
flags = eTexDisplay_RemapFloat;
{
TextureDisplay texDisplay;
@@ -2060,7 +2070,7 @@ void D3D11Replay::GetTextureData(ResourceId tex, const Subresource &sub,
// scale here
texDisplay.scale = 1.0f / float(1 << sub.mip);
RenderTextureInternal(texDisplay, false);
RenderTextureInternal(texDisplay, flags);
}
m_pImmediateContext->CopyResource(d, rtTex);
@@ -2111,17 +2121,18 @@ void D3D11Replay::GetTextureData(ResourceId tex, const Subresource &sub,
{
if(params.remap == RemapTexture::RGBA8)
{
desc.Format = (IsSRGBFormat(desc.Format) || wrapTex->m_RealDescriptor)
? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
: DXGI_FORMAT_R8G8B8A8_UNORM;
if((IsSRGBFormat(desc.Format) || wrapTex->m_RealDescriptor) &&
params.typeCast == CompType::Typeless)
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
desc.Format = GetTypedFormat(DXGI_FORMAT_R8G8B8A8_TYPELESS, params.typeCast);
}
else if(params.remap == RemapTexture::RGBA16)
{
desc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
desc.Format = GetTypedFormat(DXGI_FORMAT_R16G16B16A16_TYPELESS, params.typeCast);
}
else if(params.remap == RemapTexture::RGBA32)
{
desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
desc.Format = GetTypedFormat(DXGI_FORMAT_R32G32B32A32_TYPELESS, params.typeCast);
}
desc.ArraySize = 1;
@@ -2188,6 +2199,15 @@ void D3D11Replay::GetTextureData(ResourceId tex, const Subresource &sub,
SetOutputDimensions(desc.Width, desc.Height);
m_pImmediateContext->RSSetViewports(1, &viewport);
TexDisplayFlags flags = eTexDisplay_None;
if(IsUIntFormat(desc.Format))
flags = eTexDisplay_RemapUInt;
else if(IsIntFormat(desc.Format))
flags = eTexDisplay_RemapSInt;
else
flags = eTexDisplay_RemapFloat;
{
TextureDisplay texDisplay;
@@ -2212,7 +2232,7 @@ void D3D11Replay::GetTextureData(ResourceId tex, const Subresource &sub,
// scale here
texDisplay.scale = 1.0f / float(1 << sub.mip);
RenderTextureInternal(texDisplay, false);
RenderTextureInternal(texDisplay, flags);
}
m_pImmediateContext->CopyResource(d, rtTex);
@@ -2277,16 +2297,17 @@ void D3D11Replay::GetTextureData(ResourceId tex, const Subresource &sub,
{
if(params.remap == RemapTexture::RGBA8)
{
desc.Format = IsSRGBFormat(desc.Format) ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
: DXGI_FORMAT_R8G8B8A8_UNORM;
if(IsSRGBFormat(desc.Format) && params.typeCast == CompType::Typeless)
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
desc.Format = GetTypedFormat(DXGI_FORMAT_R8G8B8A8_TYPELESS, params.typeCast);
}
else if(params.remap == RemapTexture::RGBA16)
{
desc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
desc.Format = GetTypedFormat(DXGI_FORMAT_R16G16B16A16_TYPELESS, params.typeCast);
}
else if(params.remap == RemapTexture::RGBA32)
{
desc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
desc.Format = GetTypedFormat(DXGI_FORMAT_R32G32B32A32_TYPELESS, params.typeCast);
}
}
@@ -2336,6 +2357,15 @@ void D3D11Replay::GetTextureData(ResourceId tex, const Subresource &sub,
0, 0, (float)desc.Width, (float)desc.Height, 0.0f, 1.0f,
};
TexDisplayFlags flags = eTexDisplay_None;
if(IsUIntFormat(desc.Format))
flags = eTexDisplay_RemapUInt;
else if(IsIntFormat(desc.Format))
flags = eTexDisplay_RemapSInt;
else
flags = eTexDisplay_RemapFloat;
for(UINT i = 0; i < (desc.Depth >> sub.mip); i++)
{
rtvDesc.Texture3D.FirstWSlice = i;
@@ -2380,7 +2410,7 @@ void D3D11Replay::GetTextureData(ResourceId tex, const Subresource &sub,
// scale here
texDisplay.scale = 1.0f / float(1 << sub.mip);
RenderTextureInternal(texDisplay, false);
RenderTextureInternal(texDisplay, flags);
SAFE_RELEASE(wrappedrtv);
}
@@ -2627,7 +2657,7 @@ void D3D11Replay::BuildCustomShader(ShaderEncoding sourceEncoding, bytebuf sourc
bool D3D11Replay::RenderTexture(TextureDisplay cfg)
{
return RenderTextureInternal(cfg, true);
return RenderTextureInternal(cfg, eTexDisplay_BlendAlpha);
}
void D3D11Replay::RenderCheckerboard()
@@ -3308,7 +3338,7 @@ ResourceId D3D11Replay::ApplyCustomShader(ResourceId shader, ResourceId texid,
SetOutputDimensions(RDCMAX(1U, details.texWidth >> sub.mip),
RDCMAX(1U, details.texHeight >> sub.mip));
RenderTextureInternal(disp, true);
RenderTextureInternal(disp, eTexDisplay_BlendAlpha);
return m_CustomShaderResourceId;
}
@@ -3347,7 +3377,7 @@ ResourceId D3D11Replay::CreateProxyTexture(const TextureDescription &templateTex
desc.BindFlags |= D3D11_BIND_DEPTH_STENCIL;
desc.CPUAccessFlags = 0;
desc.Format = MakeDXGIFormat(templateTex.format);
desc.Format = GetTypelessFormat(MakeDXGIFormat(templateTex.format));
desc.MipLevels = templateTex.mips;
desc.MiscFlags = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
@@ -3362,9 +3392,6 @@ ResourceId D3D11Replay::CreateProxyTexture(const TextureDescription &templateTex
resource = throwaway;
if(templateTex.creationFlags & TextureCategory::DepthTarget)
desc.Format = GetTypelessFormat(desc.Format);
ret = ((WrappedID3D11Texture1D *)throwaway)->GetResourceID();
if(templateTex.creationFlags & TextureCategory::DepthTarget)
@@ -3379,7 +3406,7 @@ ResourceId D3D11Replay::CreateProxyTexture(const TextureDescription &templateTex
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
desc.Format = MakeDXGIFormat(templateTex.format);
desc.Format = GetTypelessFormat(MakeDXGIFormat(templateTex.format));
desc.MipLevels = templateTex.mips;
desc.MiscFlags = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
@@ -3388,11 +3415,8 @@ ResourceId D3D11Replay::CreateProxyTexture(const TextureDescription &templateTex
desc.SampleDesc.Count = RDCMAX(1U, templateTex.msSamp);
desc.SampleDesc.Quality = templateTex.msQual;
if(templateTex.creationFlags & TextureCategory::DepthTarget || IsDepthFormat(desc.Format))
{
if(IsDepthFormat(desc.Format))
desc.BindFlags |= D3D11_BIND_DEPTH_STENCIL;
desc.Format = GetTypelessFormat(desc.Format);
}
if(templateTex.cubemap)
desc.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE;
@@ -3421,7 +3445,7 @@ ResourceId D3D11Replay::CreateProxyTexture(const TextureDescription &templateTex
desc.BindFlags |= D3D11_BIND_DEPTH_STENCIL;
desc.CPUAccessFlags = 0;
desc.Format = MakeDXGIFormat(templateTex.format);
desc.Format = GetTypelessFormat(MakeDXGIFormat(templateTex.format));
desc.MipLevels = templateTex.mips;
desc.MiscFlags = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
+11 -1
View File
@@ -86,6 +86,15 @@ struct D3D11PostVSData
}
};
enum TexDisplayFlags
{
eTexDisplay_None = 0,
eTexDisplay_BlendAlpha = 0x1,
eTexDisplay_RemapFloat = 0x2,
eTexDisplay_RemapUInt = 0x4,
eTexDisplay_RemapSInt = 0x8,
};
class D3D11Replay : public IReplayDriver
{
public:
@@ -277,7 +286,7 @@ private:
void SerializeImmediateContext();
bool RenderTextureInternal(TextureDisplay cfg, bool blendAlpha);
bool RenderTextureInternal(TextureDisplay cfg, TexDisplayFlags flags);
void CreateCustomShaderTex(uint32_t w, uint32_t h);
@@ -366,6 +375,7 @@ private:
ID3D11BlendState *BlendState = NULL;
ID3D11VertexShader *TexDisplayVS = NULL;
ID3D11PixelShader *TexDisplayPS = NULL;
ID3D11PixelShader *TexRemapPS[3] = {};
} m_TexRender;
struct OverlayRendering
+53
View File
@@ -1046,6 +1046,52 @@ void D3D12Replay::TextureRendering::Init(WrappedID3D12Device *device, D3D12Debug
}
SAFE_RELEASE(TexDisplayPS);
hlsl = GetEmbeddedResource(texremap_hlsl);
ID3DBlob *TexRemap[3] = {};
DXGI_FORMAT formats[3] = {
DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R16G16B16A16_TYPELESS,
DXGI_FORMAT_R32G32B32A32_TYPELESS,
};
shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_TexRemapFloat",
D3DCOMPILE_WARNINGS_ARE_ERRORS, "ps_5_0", &TexRemap[0]);
RDCASSERT(TexRemap[0]);
shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_TexRemapUInt",
D3DCOMPILE_WARNINGS_ARE_ERRORS, "ps_5_0", &TexRemap[1]);
RDCASSERT(TexRemap[1]);
shaderCache->GetShaderBlob(hlsl.c_str(), "RENDERDOC_TexRemapSInt",
D3DCOMPILE_WARNINGS_ARE_ERRORS, "ps_5_0", &TexRemap[2]);
RDCASSERT(TexRemap[2]);
for(int f = 0; f < 3; f++)
{
for(int i = 0; i < 3; i++)
{
pipeDesc.PS.BytecodeLength = TexRemap[i]->GetBufferSize();
pipeDesc.PS.pShaderBytecode = TexRemap[i]->GetBufferPointer();
if(i == 0)
pipeDesc.RTVFormats[0] = GetFloatTypedFormat(formats[f]);
else if(i == 1)
pipeDesc.RTVFormats[0] = GetUIntTypedFormat(formats[f]);
else
pipeDesc.RTVFormats[0] = GetSIntTypedFormat(formats[f]);
hr = device->CreateGraphicsPipelineState(&pipeDesc, __uuidof(ID3D12PipelineState),
(void **)&m_TexRemapPipe[f][i]);
if(FAILED(hr))
{
RDCERR("Couldn't create m_TexRemapPipe for %s! HRESULT: %s",
ToStr(pipeDesc.RTVFormats[0]).c_str(), ToStr(hr).c_str());
}
}
}
for(int i = 0; i < 3; i++)
SAFE_RELEASE(TexRemap[i]);
}
shaderCache->SetCaching(false);
@@ -1060,6 +1106,13 @@ void D3D12Replay::TextureRendering::Release()
SAFE_RELEASE(F32Pipe);
SAFE_RELEASE(RootSig);
SAFE_RELEASE(VS);
for(int f = 0; f < 3; f++)
{
for(int i = 0; i < 3; i++)
{
SAFE_RELEASE(m_TexRemapPipe[f][i]);
}
}
}
void D3D12Replay::OverlayRendering::Init(WrappedID3D12Device *device, D3D12DebugManager *debug)
+22 -2
View File
@@ -673,11 +673,31 @@ bool D3D12Replay::RenderTextureInternal(D3D12_CPU_DESCRIPTOR_HANDLE rtv, Texture
{
list->SetPipelineState(customPSO);
}
else if(flags & (eTexDisplay_RemapFloat | eTexDisplay_RemapUInt | eTexDisplay_RemapSInt))
{
int i = 0;
if(flags & eTexDisplay_RemapFloat)
i = 0;
else if(flags & eTexDisplay_RemapUInt)
i = 1;
else if(flags & eTexDisplay_RemapSInt)
i = 2;
int f = 0;
if(flags & eTexDisplay_32Render)
f = 2;
else if(flags & eTexDisplay_16Render)
f = 1;
else
f = 0;
list->SetPipelineState(m_TexRender.m_TexRemapPipe[f][i]);
}
else if(cfg.rawOutput || !blendAlpha || cfg.customShaderId != ResourceId())
{
if(flags & eTexDisplay_F32Render)
if(flags & eTexDisplay_32Render)
list->SetPipelineState(m_TexRender.F32Pipe);
else if(flags & eTexDisplay_F16Render)
else if(flags & eTexDisplay_16Render)
list->SetPipelineState(m_TexRender.F16Pipe);
else if(flags & eTexDisplay_LinearRender)
list->SetPipelineState(m_TexRender.LinearPipe);
+18 -10
View File
@@ -2182,7 +2182,7 @@ void D3D12Replay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, const Su
texDisplay.yOffset = -float(y << sub.mip);
RenderTextureInternal(GetDebugManager()->GetCPUHandle(PICK_PIXEL_RTV), texDisplay,
eTexDisplay_F32Render);
eTexDisplay_32Render);
}
ID3D12GraphicsCommandList *list = m_pDevice->GetNewList();
@@ -3058,16 +3058,17 @@ void D3D12Replay::GetTextureData(ResourceId tex, const Subresource &sub,
{
if(params.remap == RemapTexture::RGBA8)
{
copyDesc.Format = IsSRGBFormat(copyDesc.Format) ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
: DXGI_FORMAT_R8G8B8A8_UNORM;
if(IsSRGBFormat(copyDesc.Format) && params.typeCast == CompType::Typeless)
copyDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
copyDesc.Format = GetTypedFormat(DXGI_FORMAT_R8G8B8A8_TYPELESS, params.typeCast);
}
else if(params.remap == RemapTexture::RGBA16)
{
copyDesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
copyDesc.Format = GetTypedFormat(DXGI_FORMAT_R16G16B16A16_TYPELESS, params.typeCast);
}
else if(params.remap == RemapTexture::RGBA32)
{
copyDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
copyDesc.Format = GetTypedFormat(DXGI_FORMAT_R32G32B32A32_TYPELESS, params.typeCast);
}
// force to 1 mip
@@ -3092,10 +3093,17 @@ void D3D12Replay::GetTextureData(ResourceId tex, const Subresource &sub,
TexDisplayFlags flags =
IsSRGBFormat(copyDesc.Format) ? eTexDisplay_None : eTexDisplay_LinearRender;
if(copyDesc.Format == DXGI_FORMAT_R16G16B16A16_FLOAT)
flags = eTexDisplay_F16Render;
else if(copyDesc.Format == DXGI_FORMAT_R32G32B32A32_FLOAT)
flags = eTexDisplay_F32Render;
if(GetTypelessFormat(copyDesc.Format) == DXGI_FORMAT_R16G16B16A16_TYPELESS)
flags = eTexDisplay_16Render;
else if(GetTypelessFormat(copyDesc.Format) == DXGI_FORMAT_R32G32B32A32_TYPELESS)
flags = eTexDisplay_32Render;
if(IsUIntFormat(copyDesc.Format))
flags = TexDisplayFlags(flags | eTexDisplay_RemapUInt);
else if(IsIntFormat(copyDesc.Format))
flags = TexDisplayFlags(flags | eTexDisplay_RemapSInt);
else
flags = TexDisplayFlags(flags | eTexDisplay_RemapFloat);
uint32_t loopCount = 1;
@@ -3141,7 +3149,7 @@ void D3D12Replay::GetTextureData(ResourceId tex, const Subresource &sub,
texDisplay.rangeMin = params.blackPoint;
texDisplay.rangeMax = params.whitePoint;
texDisplay.resourceId = tex;
texDisplay.typeCast = CompType::Typeless;
texDisplay.typeCast = params.typeCast;
texDisplay.rawOutput = false;
texDisplay.xOffset = 0;
texDisplay.yOffset = 0;
+7 -2
View File
@@ -43,9 +43,12 @@ enum TexDisplayFlags
{
eTexDisplay_None = 0,
eTexDisplay_LinearRender = 0x1,
eTexDisplay_F16Render = 0x2,
eTexDisplay_F32Render = 0x4,
eTexDisplay_16Render = 0x2,
eTexDisplay_32Render = 0x4,
eTexDisplay_BlendAlpha = 0x8,
eTexDisplay_RemapFloat = 0x10,
eTexDisplay_RemapUInt = 0x20,
eTexDisplay_RemapSInt = 0x40,
};
class D3D12Replay : public IReplayDriver
@@ -354,6 +357,8 @@ private:
ID3D12PipelineState *F16Pipe = NULL;
ID3D12PipelineState *F32Pipe = NULL;
ID3D12PipelineState *BlendPipe = NULL;
// for each of 8-bit, 16-bit, 32-bit and float, uint, sint
ID3D12PipelineState *m_TexRemapPipe[3][3] = {};
} m_TexRender;
struct OverlayRendering
+7 -2
View File
@@ -2221,8 +2221,13 @@ GLenum MakeGLFormat(ResourceFormat fmt)
case ResourceFormatType::R4G4B4A4: ret = eGL_RGBA4; break;
case ResourceFormatType::D24S8: ret = eGL_DEPTH24_STENCIL8; break;
case ResourceFormatType::D32S8: ret = eGL_DEPTH32F_STENCIL8; break;
case ResourceFormatType::ASTC: RDCERR("ASTC can't be decoded unambiguously"); break;
case ResourceFormatType::PVRTC: RDCERR("PVRTC can't be decoded unambiguously"); break;
case ResourceFormatType::D16S8: return eGL_NONE; break;
case ResourceFormatType::ASTC:
RDCWARN("ASTC can't be decoded unambiguously");
return eGL_NONE;
case ResourceFormatType::PVRTC:
RDCWARN("PVRTC can't be decoded unambiguously");
return eGL_NONE;
case ResourceFormatType::S8: ret = eGL_STENCIL_INDEX8; break;
case ResourceFormatType::A8: ret = eGL_ALPHA8_EXT; break;
case ResourceFormatType::Undefined: return eGL_NONE;
+12
View File
@@ -467,6 +467,14 @@ void GLReplay::InitDebugData()
BindUBO(DebugData.texDisplayProg[i], "TexDisplayUBOData", 0);
BindUBO(DebugData.texDisplayProg[i], "HeatmapData", 1);
ConfigureTexDisplayProgramBindings(DebugData.texDisplayProg[i]);
fs = GenerateGLSLShader(GetEmbeddedResource(glsl_texremap_frag), shaderType, glslBaseVer,
defines + texSampleDefines);
DebugData.texRemapProg[i] = CreateShaderProgram(vs, fs);
BindUBO(DebugData.texRemapProg[i], "TexDisplayUBOData", 0);
ConfigureTexDisplayProgramBindings(DebugData.texRemapProg[i]);
}
RenderDoc::Inst().SetProgress(LoadProgress::DebugManagerInit, 0.2f);
@@ -1182,8 +1190,12 @@ void GLReplay::DeleteDebugData()
if(DebugData.texDisplayVertexShader)
drv.glDeleteShader(DebugData.texDisplayVertexShader);
for(int i = 0; i < 3; i++)
{
if(DebugData.texDisplayProg[i])
drv.glDeleteProgram(DebugData.texDisplayProg[i]);
if(DebugData.texRemapProg[i])
drv.glDeleteProgram(DebugData.texRemapProg[i]);
}
if(DebugData.checkerProg)
drv.glDeleteProgram(DebugData.checkerProg);
+10 -3
View File
@@ -34,10 +34,10 @@
bool GLReplay::RenderTexture(TextureDisplay cfg)
{
return RenderTextureInternal(cfg, eTexDisplay_BlendAlpha | eTexDisplay_MipShift);
return RenderTextureInternal(cfg, TexDisplayFlags(eTexDisplay_BlendAlpha | eTexDisplay_MipShift));
}
bool GLReplay::RenderTextureInternal(TextureDisplay cfg, int flags)
bool GLReplay::RenderTextureInternal(TextureDisplay cfg, TexDisplayFlags flags)
{
const bool blendAlpha = (flags & eTexDisplay_BlendAlpha) != 0;
const bool mipShift = (flags & eTexDisplay_MipShift) != 0;
@@ -353,7 +353,14 @@ bool GLReplay::RenderTextureInternal(TextureDisplay cfg, int flags)
}
drv.glBindProgramPipeline(0);
drv.glUseProgram(DebugData.texDisplayProg[intIdx]);
if(flags & eTexDisplay_RemapFloat)
drv.glUseProgram(DebugData.texRemapProg[0]);
else if(flags & eTexDisplay_RemapUInt)
drv.glUseProgram(DebugData.texRemapProg[1]);
else if(flags & eTexDisplay_RemapSInt)
drv.glUseProgram(DebugData.texRemapProg[2]);
else
drv.glUseProgram(DebugData.texDisplayProg[intIdx]);
GLuint customProgram = 0;
+15 -3
View File
@@ -2318,6 +2318,9 @@ void GLReplay::GetTextureData(ResourceId tex, const Subresource &sub,
else if(params.remap == RemapTexture::RGBA32)
remapFormat = eGL_RGBA32F;
if(params.typeCast != CompType::Typeless)
remapFormat = GetViewCastedFormat(remapFormat, params.typeCast);
if(intFormat != remapFormat)
{
MakeCurrentReplayContext(m_DebugCtx);
@@ -2364,6 +2367,15 @@ void GLReplay::GetTextureData(ResourceId tex, const Subresource &sub,
GLenum baseFormat = !IsCompressedFormat(intFormat) ? GetBaseFormat(intFormat) : eGL_RGBA;
TexDisplayFlags flags = eTexDisplay_None;
if(IsUIntFormat(intFormat))
flags = eTexDisplay_RemapUInt;
else if(IsSIntFormat(intFormat))
flags = eTexDisplay_RemapSInt;
else
flags = eTexDisplay_RemapFloat;
for(GLsizei d = 0; d < (newtarget == eGL_TEXTURE_3D ? depth : 1); d++)
{
TextureDisplay texDisplay;
@@ -2381,7 +2393,7 @@ void GLReplay::GetTextureData(ResourceId tex, const Subresource &sub,
texDisplay.rangeMax = params.whitePoint;
texDisplay.scale = 1.0f;
texDisplay.resourceId = tex;
texDisplay.typeCast = CompType::Typeless;
texDisplay.typeCast = params.typeCast;
texDisplay.rawOutput = false;
texDisplay.xOffset = 0;
texDisplay.yOffset = 0;
@@ -2405,7 +2417,7 @@ void GLReplay::GetTextureData(ResourceId tex, const Subresource &sub,
drv.glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
}
RenderTextureInternal(texDisplay, 0);
RenderTextureInternal(texDisplay, flags);
drv.glColorMask(color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
}
@@ -2440,7 +2452,7 @@ void GLReplay::GetTextureData(ResourceId tex, const Subresource &sub,
drv.glGetBooleanv(eGL_COLOR_WRITEMASK, color_mask);
drv.glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE);
RenderTextureInternal(texDisplay, 0);
RenderTextureInternal(texDisplay, flags);
drv.glColorMask(color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
}
+12 -7
View File
@@ -80,6 +80,16 @@ struct GLPostVSData
}
};
enum TexDisplayFlags
{
eTexDisplay_None = 0x0,
eTexDisplay_BlendAlpha = 0x1,
eTexDisplay_MipShift = 0x2,
eTexDisplay_RemapFloat = 0x4,
eTexDisplay_RemapUInt = 0x8,
eTexDisplay_RemapSInt = 0x10,
};
class GLReplay : public IReplayDriver
{
public:
@@ -183,14 +193,8 @@ public:
std::string *errors);
void FreeCustomShader(ResourceId id);
enum TexDisplayFlags
{
eTexDisplay_BlendAlpha = 0x1,
eTexDisplay_MipShift = 0x2,
};
bool RenderTexture(TextureDisplay cfg);
bool RenderTextureInternal(TextureDisplay cfg, int flags);
bool RenderTextureInternal(TextureDisplay cfg, TexDisplayFlags flags);
void RenderCheckerboard();
@@ -330,6 +334,7 @@ private:
GLuint texDisplayVertexShader;
GLuint texDisplayProg[3]; // float/uint/sint
GLuint texRemapProg[3]; // float/uint/sint
GLuint customFBO;
GLuint customTex;
+41 -1
View File
@@ -1830,6 +1830,8 @@ void VulkanReplay::TextureRendering::Init(WrappedVulkan *driver, VkDescriptorPoo
0xf, // writeMask
};
ConciseGraphicsPipeline texRemapInfo = texDisplayInfo;
CREATE_OBJECT(Pipeline, texDisplayInfo);
texDisplayInfo.renderPass = RGBA32RP;
@@ -1844,8 +1846,42 @@ void VulkanReplay::TextureRendering::Init(WrappedVulkan *driver, VkDescriptorPoo
texDisplayInfo.dstBlend = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
CREATE_OBJECT(BlendPipeline, texDisplayInfo);
VkFormat formats[3] = {VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_R16G16B16A16_UINT,
VK_FORMAT_R32G32B32A32_UINT};
CompType cast[3] = {CompType::Float, CompType::UInt, CompType::SInt};
BuiltinShader shaders[3] = {BuiltinShader::TexRemapFloat, BuiltinShader::TexRemapUInt,
BuiltinShader::TexRemapSInt};
for(int f = 0; f < 3; f++)
{
for(int i = 0; i < 3; i++)
{
texRemapInfo.fragment = shaderCache->GetBuiltinModule(shaders[i]);
CREATE_OBJECT(texRemapInfo.renderPass, GetViewCastedFormat(formats[f], cast[i]));
CREATE_OBJECT(RemapPipeline[f][i][0], texRemapInfo);
driver->vkDestroyRenderPass(driver->GetDev(), texRemapInfo.renderPass, NULL);
}
}
// make versions that only write to green, for doing two-pass stencil writes
texDisplayInfo.writeMask = 0x2;
texRemapInfo.writeMask = texDisplayInfo.writeMask = 0x2;
for(int f = 0; f < 3; f++)
{
for(int i = 0; i < 3; i++)
{
texRemapInfo.fragment = shaderCache->GetBuiltinModule(shaders[i]);
CREATE_OBJECT(texRemapInfo.renderPass, GetViewCastedFormat(formats[f], cast[i]));
CREATE_OBJECT(RemapPipeline[f][i][1], texRemapInfo);
driver->vkDestroyRenderPass(driver->GetDev(), texRemapInfo.renderPass, NULL);
}
}
texDisplayInfo.renderPass = SRGBA8RP;
CREATE_OBJECT(PipelineGreenOnly, texDisplayInfo);
@@ -2073,6 +2109,10 @@ void VulkanReplay::TextureRendering::Destroy(WrappedVulkan *driver)
driver->vkDestroyPipeline(driver->GetDev(), BlendPipeline, NULL);
driver->vkDestroyPipeline(driver->GetDev(), F16Pipeline, NULL);
driver->vkDestroyPipeline(driver->GetDev(), F32Pipeline, NULL);
for(size_t f = 0; f < 3; f++)
for(size_t i = 0; i < 3; i++)
for(size_t g = 0; g < 2; g++)
driver->vkDestroyPipeline(driver->GetDev(), RemapPipeline[f][i][g], NULL);
driver->vkDestroyPipeline(driver->GetDev(), PipelineGreenOnly, NULL);
driver->vkDestroyPipeline(driver->GetDev(), F16PipelineGreenOnly, NULL);
+22 -2
View File
@@ -152,9 +152,9 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn
{
const bool blendAlpha = (flags & eTexDisplay_BlendAlpha) != 0;
const bool mipShift = (flags & eTexDisplay_MipShift) != 0;
const bool f16render = (flags & eTexDisplay_F16Render) != 0;
const bool f16render = (flags & eTexDisplay_16Render) != 0;
const bool greenonly = (flags & eTexDisplay_GreenOnly) != 0;
const bool f32render = (flags & eTexDisplay_F32Render) != 0;
const bool f32render = (flags & eTexDisplay_32Render) != 0;
VkDevice dev = m_pDriver->GetDev();
VkCommandBuffer cmd = m_pDriver->GetNextCmd();
@@ -546,6 +546,26 @@ bool VulkanReplay::RenderTextureInternal(TextureDisplay cfg, VkRenderPassBeginIn
GetDebugManager()->CreateCustomShaderPipeline(cfg.customShaderId, m_TexRender.PipeLayout);
pipe = GetDebugManager()->GetCustomPipeline();
}
else if(flags & (eTexDisplay_RemapFloat | eTexDisplay_RemapUInt | eTexDisplay_RemapSInt))
{
int i = 0;
if(flags & eTexDisplay_RemapFloat)
i = 0;
else if(flags & eTexDisplay_RemapUInt)
i = 1;
else if(flags & eTexDisplay_RemapSInt)
i = 2;
int f = 0;
if(flags & eTexDisplay_32Render)
f = 2;
else if(flags & eTexDisplay_16Render)
f = 1;
else
f = 0;
pipe = m_TexRender.RemapPipeline[f][i][greenonly ? 1 : 0];
}
else if(f16render)
{
pipe = greenonly ? m_TexRender.F16PipelineGreenOnly : m_TexRender.F16Pipeline;
+56 -9
View File
@@ -2020,7 +2020,7 @@ void VulkanReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, const S
&clearval,
};
RenderTextureInternal(texDisplay, rpbegin, eTexDisplay_F32Render | eTexDisplay_MipShift);
RenderTextureInternal(texDisplay, rpbegin, eTexDisplay_32Render | eTexDisplay_MipShift);
}
VkDevice dev = m_pDriver->GetDev();
@@ -2889,18 +2889,28 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
else if(params.remap == RemapTexture::RGBA16)
{
imCreateInfo.format = VK_FORMAT_R16G16B16A16_SFLOAT;
renderFlags = eTexDisplay_F16Render;
renderFlags = eTexDisplay_16Render;
}
else if(params.remap == RemapTexture::RGBA32)
{
imCreateInfo.format = VK_FORMAT_R32G32B32A32_SFLOAT;
renderFlags = eTexDisplay_F32Render;
renderFlags = eTexDisplay_32Render;
}
else
{
RDCERR("Unsupported remap format: %u", params.remap);
}
if(params.typeCast != CompType::Typeless)
imCreateInfo.format = GetViewCastedFormat(imCreateInfo.format, params.typeCast);
if(IsUIntFormat(imCreateInfo.format))
renderFlags |= eTexDisplay_RemapUInt;
else if(IsSIntFormat(imCreateInfo.format))
renderFlags |= eTexDisplay_RemapSInt;
else
renderFlags |= eTexDisplay_RemapFloat;
// force to 1 array slice, 1 mip
imCreateInfo.arrayLayers = 1;
imCreateInfo.mipLevels = 1;
@@ -2908,6 +2918,10 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
imCreateInfo.imageType = VK_IMAGE_TYPE_2D;
imCreateInfo.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
// we'll need to cast to remap the stencil part
if(IsDepthAndStencilFormat(imInfo.format))
imCreateInfo.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
imCreateInfo.extent.width = RDCMAX(1U, imCreateInfo.extent.width >> s.mip);
imCreateInfo.extent.height = RDCMAX(1U, imCreateInfo.extent.height >> s.mip);
imCreateInfo.extent.depth = RDCMAX(1U, imCreateInfo.extent.depth >> s.mip);
@@ -2997,8 +3011,18 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
vt->CreateRenderPass(Unwrap(dev), &rpinfo, NULL, &tmpRP);
numFBs = imCreateInfo.arrayLayers;
tmpFB = new VkFramebuffer[numFBs];
tmpView = new VkImageView[numFBs];
// we'll need twice as many temp views/FBs for stencil views
if(IsDepthAndStencilFormat(imInfo.format))
{
tmpFB = new VkFramebuffer[numFBs * 2];
tmpView = new VkImageView[numFBs * 2];
}
else
{
tmpFB = new VkFramebuffer[numFBs];
tmpView = new VkImageView[numFBs];
}
int oldW = m_DebugWidth, oldH = m_DebugHeight;
@@ -3030,7 +3054,7 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
texDisplay.rangeMax = params.whitePoint;
texDisplay.scale = 1.0f;
texDisplay.resourceId = tex;
texDisplay.typeCast = CompType::Typeless;
texDisplay.typeCast = params.typeCast;
texDisplay.rawOutput = false;
texDisplay.xOffset = 0;
texDisplay.yOffset = 0;
@@ -3049,7 +3073,8 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
},
};
vt->CreateImageView(Unwrap(dev), &viewInfo, NULL, &tmpView[i]);
vkr = vt->CreateImageView(Unwrap(dev), &viewInfo, NULL, &tmpView[i]);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
VkFramebufferCreateInfo fbinfo = {
VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
@@ -3085,8 +3110,18 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
// for textures with stencil, do another draw to copy the stencil
if(isStencil)
{
viewInfo.format = GetViewCastedFormat(viewInfo.format, CompType::UInt);
vkr = vt->CreateImageView(Unwrap(dev), &viewInfo, NULL, &tmpView[i + numFBs]);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
fbinfo.pAttachments = &tmpView[i + numFBs];
vkr = vt->CreateFramebuffer(Unwrap(dev), &fbinfo, NULL, &tmpFB[i + numFBs]);
RDCASSERTEQUAL(vkr, VK_SUCCESS);
rpbegin.framebuffer = tmpFB[i + numFBs];
texDisplay.red = texDisplay.blue = texDisplay.alpha = false;
RenderTextureInternal(texDisplay, rpbegin, renderFlags | eTexDisplay_GreenOnly);
RenderTextureInternal(texDisplay, rpbegin, (renderFlags & ~eTexDisplay_RemapFloat) |
eTexDisplay_RemapUInt | eTexDisplay_GreenOnly);
}
}
@@ -3693,7 +3728,16 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
data.resize(dataSize);
if(isDepth && isStencil)
if(params.remap == RemapTexture::RGBA32 && IsDepthAndStencilFormat(imInfo.format))
{
memcpy(data.data(), pData, dataSize);
Vec4f *output = (Vec4f *)data.data();
Vec4u *input = (Vec4u *)pData;
for(size_t i = 0; i < dataSize / sizeof(Vec4u); i++)
output[i].y = float(input[i].y) / 255.0f;
}
else if(isDepth && isStencil)
{
size_t pixelCount =
imCreateInfo.extent.width * imCreateInfo.extent.height * imCreateInfo.extent.depth;
@@ -3788,6 +3832,9 @@ void VulkanReplay::GetTextureData(ResourceId tex, const Subresource &sub,
if(tmpFB != NULL)
{
if(IsDepthAndStencilFormat(imInfo.format))
numFBs *= 2;
for(uint32_t i = 0; i < numFBs; i++)
{
vt->DestroyFramebuffer(Unwrap(dev), tmpFB[i], NULL);
+14 -9
View File
@@ -236,6 +236,18 @@ struct DynamicUsedBinds
std::vector<BindIdx> used;
};
enum TexDisplayFlags
{
eTexDisplay_16Render = 0x1,
eTexDisplay_32Render = 0x2,
eTexDisplay_BlendAlpha = 0x4,
eTexDisplay_MipShift = 0x8,
eTexDisplay_GreenOnly = 0x10,
eTexDisplay_RemapFloat = 0x20,
eTexDisplay_RemapUInt = 0x40,
eTexDisplay_RemapSInt = 0x80,
};
class VulkanReplay : public IReplayDriver
{
public:
@@ -494,15 +506,6 @@ private:
WrappedVulkan *m_pDriver = NULL;
VkDevice m_Device = VK_NULL_HANDLE;
enum TexDisplayFlags
{
eTexDisplay_F16Render = 0x1,
eTexDisplay_F32Render = 0x2,
eTexDisplay_BlendAlpha = 0x4,
eTexDisplay_MipShift = 0x8,
eTexDisplay_GreenOnly = 0x10,
};
// General use/misc items that are used in many places
struct GeneralMisc
{
@@ -536,6 +539,8 @@ private:
VkPipeline BlendPipeline = VK_NULL_HANDLE;
VkPipeline F16Pipeline = VK_NULL_HANDLE;
VkPipeline F32Pipeline = VK_NULL_HANDLE;
// for each of 8-bit, 16-bit, 32-bit and float, uint, sint, and for normal/green-only
VkPipeline RemapPipeline[3][3][2] = {};
VkPipeline PipelineGreenOnly = VK_NULL_HANDLE;
VkPipeline F16PipelineGreenOnly = VK_NULL_HANDLE;
+17 -2
View File
@@ -85,6 +85,12 @@ static const BuiltinShaderConfig builtinShaders[] = {
rdcspv::ShaderStage::Fragment, FeatureCheck::NonMetalBackend, true},
{BuiltinShader::DepthArray2MSFS, EmbeddedResource(glsl_deptharr2ms_frag),
rdcspv::ShaderStage::Fragment, FeatureCheck::NonMetalBackend, true},
{BuiltinShader::TexRemapFloat, EmbeddedResource(glsl_texremap_frag),
rdcspv::ShaderStage::Fragment, FeatureCheck::NoCheck, true},
{BuiltinShader::TexRemapUInt, EmbeddedResource(glsl_texremap_frag),
rdcspv::ShaderStage::Fragment, FeatureCheck::NoCheck, true},
{BuiltinShader::TexRemapSInt, EmbeddedResource(glsl_texremap_frag),
rdcspv::ShaderStage::Fragment, FeatureCheck::NoCheck, true},
};
RDCCOMPILE_ASSERT(ARRAY_COUNT(builtinShaders) == arraydim<BuiltinShader>(),
@@ -179,8 +185,17 @@ VulkanShaderCache::VulkanShaderCache(WrappedVulkan *driver)
if(config.stage == rdcspv::ShaderStage::Geometry && !features.geometryShader)
continue;
src = GenerateGLSLShader(GetDynamicEmbeddedResource(config.resource), eShaderVulkan, 430,
m_GlobalDefines);
std::string defines = m_GlobalDefines;
if(config.builtin == BuiltinShader::TexRemapFloat)
defines += std::string("#define UINT_TEX 0\n#define SINT_TEX 0\n");
else if(config.builtin == BuiltinShader::TexRemapUInt)
defines += std::string("#define UINT_TEX 1\n#define SINT_TEX 0\n");
else if(config.builtin == BuiltinShader::TexRemapSInt)
defines += std::string("#define UINT_TEX 0\n#define SINT_TEX 1\n");
src =
GenerateGLSLShader(GetDynamicEmbeddedResource(config.resource), eShaderVulkan, 430, defines);
compileSettings.stage = config.stage;
std::string err = GetSPIRVBlob(compileSettings, src, m_BuiltinShaderBlobs[i]);
@@ -52,6 +52,9 @@ enum class BuiltinShader
Array2MSCS,
DepthMS2ArrayFS,
DepthArray2MSFS,
TexRemapFloat,
TexRemapUInt,
TexRemapSInt,
Count,
};
+2
View File
@@ -575,6 +575,7 @@
<None Include="data\glsl\quadresolve.frag" />
<None Include="data\glsl\quadwrite.frag" />
<None Include="data\glsl\texdisplay.frag" />
<None Include="data\glsl\texremap.frag" />
<None Include="data\glsl\vktext.frag" />
<None Include="data\glsl\vktext.vert" />
<None Include="data\glsl\trisize.frag" />
@@ -590,6 +591,7 @@
<None Include="data\hlsl\texdisplay.hlsl" />
<None Include="os\win32\comexport.def" />
<None Include="replay\renderdoc_serialise.inl" />
<None Include="data\hlsl\texremap.hlsl" />
</ItemGroup>
<ItemGroup>
<Natvis Include="renderdoc.natvis" />
+4
View File
@@ -979,6 +979,10 @@
<None Include="data\hlsl\texdisplay.hlsl">
<Filter>Resources\hlsl</Filter>
</None>
<None Include="data\glsl\texremap.frag">
<Filter>Resources\glsl</Filter>
</None>
<None Include="data\hlsl\texremap.hlsl" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="data\renderdoc.rc">
-1
View File
@@ -35,7 +35,6 @@ rdcstr DoStringise(const RemapTexture &el)
STRINGISE_ENUM_CLASS(RGBA8)
STRINGISE_ENUM_CLASS(RGBA16)
STRINGISE_ENUM_CLASS(RGBA32)
STRINGISE_ENUM_CLASS(D32S8)
}
END_ENUM_STRINGISE();
}
+7 -18
View File
@@ -43,30 +43,19 @@ enum class RemapTexture : uint32_t
NoRemap,
RGBA8,
RGBA16,
RGBA32,
D32S8
RGBA32
};
DECLARE_REFLECTION_ENUM(RemapTexture);
struct GetTextureDataParams
{
bool forDiskSave;
CompType typeCast;
bool resolve;
RemapTexture remap;
float blackPoint;
float whitePoint;
GetTextureDataParams()
: forDiskSave(false),
typeCast(CompType::Typeless),
resolve(false),
remap(RemapTexture::NoRemap),
blackPoint(0.0f),
whitePoint(1.0f)
{
}
bool forDiskSave = false;
CompType typeCast = CompType::Typeless;
bool resolve = false;
RemapTexture remap = RemapTexture::NoRemap;
float blackPoint = 0.0f;
float whitePoint = 1.0f;
};
DECLARE_REFLECTION_STRUCT(GetTextureDataParams);