diff --git a/renderdoc/api/replay/control_types.h b/renderdoc/api/replay/control_types.h index f8e83ad1a..ba7e1c95d 100644 --- a/renderdoc/api/replay/control_types.h +++ b/renderdoc/api/replay/control_types.h @@ -93,6 +93,7 @@ struct MeshDisplay struct TextureDisplay { ResourceId texid; + FormatComponentType typeHint; float rangemin; float rangemax; float scale; @@ -118,6 +119,8 @@ struct TextureSave { ResourceId id; + FormatComponentType typeHint; + FileType destType; // mip == -1 writes out all mips where allowed by file format diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index fa77e577e..1d4dbb181 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -101,7 +101,7 @@ struct IReplayOutput virtual bool SetMeshDisplay(const MeshDisplay &o) = 0; virtual bool ClearThumbnails() = 0; - virtual bool AddThumbnail(void *wnd, ResourceId texID) = 0; + virtual bool AddThumbnail(void *wnd, ResourceId texID, FormatComponentType typeHint) = 0; virtual bool Display() = 0; @@ -136,7 +136,8 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_SetMeshDisplay(ReplayO extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_ClearThumbnails(ReplayOutput *output); extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_AddThumbnail(ReplayOutput *output, - void *wnd, ResourceId texID); + void *wnd, ResourceId texID, + FormatComponentType typeHint); extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_Display(ReplayOutput *output); @@ -203,7 +204,8 @@ struct IReplayRenderer virtual bool GetDebugMessages(rdctype::array *msgs) = 0; virtual bool PixelHistory(ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, - uint32_t sampleIdx, rdctype::array *history) = 0; + uint32_t sampleIdx, FormatComponentType typeHint, + rdctype::array *history) = 0; virtual bool DebugVertex(uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset, ShaderDebugTrace *trace) = 0; virtual bool DebugPixel(uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive, @@ -221,10 +223,10 @@ struct IReplayRenderer virtual bool GetPostVSData(uint32_t instID, MeshDataStage stage, MeshFormat *data) = 0; virtual bool GetMinMax(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, - PixelValue *minval, PixelValue *maxval) = 0; + FormatComponentType typeHint, PixelValue *minval, PixelValue *maxval) = 0; virtual bool GetHistogram(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, - float minval, float maxval, bool channels[4], - rdctype::array *histogram) = 0; + FormatComponentType typeHint, float minval, float maxval, + bool channels[4], rdctype::array *histogram) = 0; virtual bool GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, rdctype::array *data) = 0; @@ -316,7 +318,7 @@ ReplayRenderer_GetDebugMessages(ReplayRenderer *rend, rdctype::array *history); + uint32_t sampleIdx, FormatComponentType typeHint, rdctype::array *history); extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_DebugVertex(ReplayRenderer *rend, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset, ShaderDebugTrace *trace); @@ -346,12 +348,13 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetPostVSData(Replay MeshDataStage stage, MeshFormat *data); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC -ReplayRenderer_GetMinMax(ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, - uint32_t sample, PixelValue *minval, PixelValue *maxval); -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetHistogram( +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetMinMax( ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, - float minval, float maxval, bool32 channels[4], rdctype::array *histogram); + FormatComponentType typeHint, PixelValue *minval, PixelValue *maxval); +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetHistogram(ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, + uint32_t sample, FormatComponentType typeHint, float minval, + float maxval, bool32 channels[4], rdctype::array *histogram); extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetBufferData( ReplayRenderer *rend, ResourceId buff, uint64_t offset, uint64_t len, rdctype::array *data); diff --git a/renderdoc/core/image_viewer.cpp b/renderdoc/core/image_viewer.cpp index a35211653..68104e251 100644 --- a/renderdoc/core/image_viewer.cpp +++ b/renderdoc/core/image_viewer.cpp @@ -92,16 +92,17 @@ public: { m_Proxy->RenderHighlightBox(w, h, scale); } - bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, - float *maxval) + bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + FormatComponentType typeHint, float *minval, float *maxval) { - return m_Proxy->GetMinMax(m_TextureID, sliceFace, mip, sample, minval, maxval); + return m_Proxy->GetMinMax(m_TextureID, sliceFace, mip, sample, typeHint, minval, maxval); } bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, - float minval, float maxval, bool channels[4], vector &histogram) + FormatComponentType typeHint, float minval, float maxval, bool channels[4], + vector &histogram) { - return m_Proxy->GetHistogram(m_TextureID, sliceFace, mip, sample, minval, maxval, channels, - histogram); + return m_Proxy->GetHistogram(m_TextureID, sliceFace, mip, sample, typeHint, minval, maxval, + channels, histogram); } bool RenderTexture(TextureDisplay cfg) { @@ -109,9 +110,9 @@ public: return m_Proxy->RenderTexture(cfg); } void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, - uint32_t sample, float pixel[4]) + uint32_t sample, FormatComponentType typeHint, float pixel[4]) { - m_Proxy->PickPixel(m_TextureID, x, y, sliceFace, mip, sample, pixel); + m_Proxy->PickPixel(m_TextureID, x, y, sliceFace, mip, sample, typeHint, pixel); } uint32_t PickVertex(uint32_t eventID, const MeshDisplay &cfg, uint32_t x, uint32_t y) { @@ -123,17 +124,19 @@ public: m_Proxy->BuildCustomShader(source, entry, compileFlags, type, id, errors); } void FreeCustomShader(ResourceId id) { m_Proxy->FreeTargetResource(id); } - ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip) + ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip, + FormatComponentType typeHint) { - return m_Proxy->ApplyCustomShader(shader, m_TextureID, mip); + return m_Proxy->ApplyCustomShader(shader, m_TextureID, mip, typeHint); } vector GetTextures() { return m_Proxy->GetTextures(); } FetchTexture GetTexture(ResourceId id) { return m_Proxy->GetTexture(m_TextureID); } - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, - bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize) + byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + FormatComponentType typeHint, bool resolve, bool forceRGBA8unorm, + float blackPoint, float whitePoint, size_t &dataSize) { - return m_Proxy->GetTextureData(m_TextureID, arrayIdx, mip, resolve, forceRGBA8unorm, blackPoint, - whitePoint, dataSize); + return m_Proxy->GetTextureData(m_TextureID, arrayIdx, mip, typeHint, resolve, forceRGBA8unorm, + blackPoint, whitePoint, dataSize); } // handle a couple of operations ourselves to return a simple fake log @@ -185,7 +188,8 @@ public: RDCEraseEl(ret); return ret; } - ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, + ResourceId RenderOverlay(ResourceId texid, FormatComponentType typeHint, + TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents) { return ResourceId(); @@ -196,7 +200,8 @@ public: Callstack::StackResolver *GetCallstackResolver() { return NULL; } void FreeTargetResource(ResourceId id) {} vector PixelHistory(vector events, ResourceId target, uint32_t x, - uint32_t y, uint32_t slice, uint32_t mip, uint32_t sampleIdx) + uint32_t y, uint32_t slice, uint32_t mip, + uint32_t sampleIdx, FormatComponentType typeHint) { return vector(); } diff --git a/renderdoc/core/replay_proxy.cpp b/renderdoc/core/replay_proxy.cpp index 71684f9c7..4a3b5b7ae 100644 --- a/renderdoc/core/replay_proxy.cpp +++ b/renderdoc/core/replay_proxy.cpp @@ -1710,7 +1710,7 @@ void ProxySerialiser::EnsureTexCached(ResourceId texid, uint32_t arrayIdx, uint3 ResourceId proxyid = m_ProxyTextureIds[texid]; size_t size; - byte *data = GetTextureData(texid, arrayIdx, mip, false, false, 0.0f, 0.0f, size); + byte *data = GetTextureData(texid, arrayIdx, mip, eCompType_None, false, false, 0.0f, 0.0f, size); if(data) m_Proxy->SetProxyTextureData(proxyid, arrayIdx, mip, data, size); @@ -1809,7 +1809,7 @@ bool ProxySerialiser::Tick() case eCommand_GetTextureData: { size_t dummy; - GetTextureData(ResourceId(), 0, 0, false, false, 0.0f, 0.0f, dummy); + GetTextureData(ResourceId(), 0, 0, eCompType_None, false, false, 0.0f, 0.0f, dummy); break; } case eCommand_InitPostVS: InitPostVSBuffers(0); break; @@ -1826,10 +1826,10 @@ bool ProxySerialiser::Tick() case eCommand_ReplaceResource: ReplaceResource(ResourceId(), ResourceId()); break; case eCommand_RemoveReplacement: RemoveReplacement(ResourceId()); break; case eCommand_RenderOverlay: - RenderOverlay(ResourceId(), eTexOverlay_None, 0, vector()); + RenderOverlay(ResourceId(), eCompType_None, eTexOverlay_None, 0, vector()); break; case eCommand_PixelHistory: - PixelHistory(vector(), ResourceId(), 0, 0, 0, 0, 0); + PixelHistory(vector(), ResourceId(), 0, 0, 0, 0, 0, eCompType_None); break; case eCommand_DebugVertex: DebugVertex(0, 0, 0, 0, 0, 0); break; case eCommand_DebugPixel: DebugPixel(0, 0, 0, 0, 0); break; @@ -2284,13 +2284,15 @@ void ProxySerialiser::GetBufferData(ResourceId buff, uint64_t offset, uint64_t l } } -byte *ProxySerialiser::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, +byte *ProxySerialiser::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + FormatComponentType typeHint, bool resolve, bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize) { m_ToReplaySerialiser->Serialise("", tex); m_ToReplaySerialiser->Serialise("", arrayIdx); m_ToReplaySerialiser->Serialise("", mip); + m_ToReplaySerialiser->Serialise("", typeHint); m_ToReplaySerialiser->Serialise("", resolve); m_ToReplaySerialiser->Serialise("", forceRGBA8unorm); m_ToReplaySerialiser->Serialise("", blackPoint); @@ -2298,8 +2300,8 @@ byte *ProxySerialiser::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_ if(m_ReplayHost) { - byte *data = m_Remote->GetTextureData(tex, arrayIdx, mip, resolve, forceRGBA8unorm, blackPoint, - whitePoint, dataSize); + byte *data = m_Remote->GetTextureData(tex, arrayIdx, mip, typeHint, resolve, forceRGBA8unorm, + blackPoint, whitePoint, dataSize); byte *compressed = new byte[dataSize + 512]; @@ -2388,21 +2390,23 @@ MeshFormat ProxySerialiser::GetPostVSBuffers(uint32_t eventID, uint32_t instID, return ret; } -ResourceId ProxySerialiser::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, - uint32_t eventID, const vector &passEvents) +ResourceId ProxySerialiser::RenderOverlay(ResourceId texid, FormatComponentType typeHint, + TextureDisplayOverlay overlay, uint32_t eventID, + const vector &passEvents) { ResourceId ret; vector events = passEvents; m_ToReplaySerialiser->Serialise("", texid); + m_ToReplaySerialiser->Serialise("", typeHint); m_ToReplaySerialiser->Serialise("", overlay); m_ToReplaySerialiser->Serialise("", eventID); m_ToReplaySerialiser->Serialise("", events); if(m_ReplayHost) { - ret = m_Remote->RenderOverlay(texid, overlay, eventID, events); + ret = m_Remote->RenderOverlay(texid, typeHint, overlay, eventID, events); } else { @@ -2609,7 +2613,8 @@ void ProxySerialiser::RemoveReplacement(ResourceId id) vector ProxySerialiser::PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, - uint32_t mip, uint32_t sampleIdx) + uint32_t mip, uint32_t sampleIdx, + FormatComponentType typeHint) { vector ret; @@ -2620,10 +2625,11 @@ vector ProxySerialiser::PixelHistory(vector event m_ToReplaySerialiser->Serialise("", slice); m_ToReplaySerialiser->Serialise("", mip); m_ToReplaySerialiser->Serialise("", sampleIdx); + m_ToReplaySerialiser->Serialise("", typeHint); if(m_ReplayHost) { - ret = m_Remote->PixelHistory(events, target, x, y, slice, mip, sampleIdx); + ret = m_Remote->PixelHistory(events, target, x, y, slice, mip, sampleIdx, typeHint); } else { diff --git a/renderdoc/core/replay_proxy.h b/renderdoc/core/replay_proxy.h index 4f162137d..edeaea793 100644 --- a/renderdoc/core/replay_proxy.h +++ b/renderdoc/core/replay_proxy.h @@ -175,26 +175,28 @@ public: return m_Proxy->RenderHighlightBox(w, h, scale); } - bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, - float *maxval) + bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + FormatComponentType typeHint, float *minval, float *maxval) { if(m_Proxy) { EnsureTexCached(texid, sliceFace, mip); - return m_Proxy->GetMinMax(m_ProxyTextureIds[texid], sliceFace, mip, sample, minval, maxval); + return m_Proxy->GetMinMax(m_ProxyTextureIds[texid], sliceFace, mip, sample, typeHint, minval, + maxval); } return false; } bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, - float minval, float maxval, bool channels[4], vector &histogram) + FormatComponentType typeHint, float minval, float maxval, bool channels[4], + vector &histogram) { if(m_Proxy) { EnsureTexCached(texid, sliceFace, mip); - return m_Proxy->GetHistogram(m_ProxyTextureIds[texid], sliceFace, mip, sample, minval, maxval, - channels, histogram); + return m_Proxy->GetHistogram(m_ProxyTextureIds[texid], sliceFace, mip, sample, typeHint, + minval, maxval, channels, histogram); } return false; @@ -213,12 +215,12 @@ public: } void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, - uint32_t sample, float pixel[4]) + uint32_t sample, FormatComponentType typeHint, float pixel[4]) { if(m_Proxy) { EnsureTexCached(texture, sliceFace, mip); - m_Proxy->PickPixel(m_ProxyTextureIds[texture], x, y, sliceFace, mip, sample, pixel); + m_Proxy->PickPixel(m_ProxyTextureIds[texture], x, y, sliceFace, mip, sample, typeHint, pixel); } } @@ -312,13 +314,14 @@ public: m_Proxy->FreeTargetResource(id); } - ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip) + ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip, + FormatComponentType typeHint) { if(m_Proxy) { EnsureTexCached(texid, 0, mip); texid = m_ProxyTextureIds[texid]; - ResourceId customResourceId = m_Proxy->ApplyCustomShader(shader, texid, mip); + ResourceId customResourceId = m_Proxy->ApplyCustomShader(shader, texid, mip, typeHint); m_LocalTextures.insert(customResourceId); m_ProxyTextureIds[customResourceId] = customResourceId; return customResourceId; @@ -363,14 +366,16 @@ public: vector &outvars, const vector &data); void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData); - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, - bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize); + byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + FormatComponentType typeHint, bool resolve, bool forceRGBA8unorm, + float blackPoint, float whitePoint, size_t &dataSize); void InitPostVSBuffers(uint32_t eventID); void InitPostVSBuffers(const vector &passEvents); MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); - ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, + ResourceId RenderOverlay(ResourceId texid, FormatComponentType typeHint, + TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents); ShaderReflection *GetShader(ResourceId shader, string entryPoint); @@ -385,7 +390,7 @@ public: vector PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, - uint32_t sampleIdx); + uint32_t sampleIdx, FormatComponentType typeHint); ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset); ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, diff --git a/renderdoc/driver/d3d11/d3d11_analyse.cpp b/renderdoc/driver/d3d11/d3d11_analyse.cpp index 653650d7f..c2af5d78a 100644 --- a/renderdoc/driver/d3d11/d3d11_analyse.cpp +++ b/renderdoc/driver/d3d11/d3d11_analyse.cpp @@ -2427,7 +2427,8 @@ uint32_t D3D11DebugManager::PickVertex(uint32_t eventID, const MeshDisplay &cfg, } void D3D11DebugManager::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, - uint32_t mip, uint32_t sample, float pixel[4]) + uint32_t mip, uint32_t sample, FormatComponentType typeHint, + float pixel[4]) { m_pImmediateContext->OMSetRenderTargets(1, &m_DebugRender.PickPixelRT, NULL); @@ -2464,6 +2465,7 @@ void D3D11DebugManager::PickPixel(ResourceId texture, uint32_t x, uint32_t y, ui texDisplay.rangemax = 1.0f; texDisplay.scale = 1.0f; texDisplay.texid = texture; + texDisplay.typeHint = typeHint; texDisplay.rawoutput = true; texDisplay.offx = -float(x); texDisplay.offy = -float(y); @@ -2517,8 +2519,9 @@ void D3D11DebugManager::PickPixel(ResourceId texture, uint32_t x, uint32_t y, ui } byte *D3D11DebugManager::GetTextureData(ResourceId id, uint32_t arrayIdx, uint32_t mip, - bool resolve, bool forceRGBA8unorm, float blackPoint, - float whitePoint, size_t &dataSize) + FormatComponentType typeHint, bool resolve, + bool forceRGBA8unorm, float blackPoint, float whitePoint, + size_t &dataSize) { ID3D11Resource *dummyTex = NULL; @@ -2631,6 +2634,7 @@ byte *D3D11DebugManager::GetTextureData(ResourceId id, uint32_t arrayIdx, uint32 texDisplay.rangemax = whitePoint; texDisplay.scale = 1.0f; texDisplay.texid = id; + texDisplay.typeHint = typeHint; texDisplay.rawoutput = false; texDisplay.offx = 0; texDisplay.offy = 0; @@ -2767,6 +2771,7 @@ byte *D3D11DebugManager::GetTextureData(ResourceId id, uint32_t arrayIdx, uint32 texDisplay.rangemax = whitePoint; texDisplay.scale = 1.0f; texDisplay.texid = id; + texDisplay.typeHint = typeHint; texDisplay.rawoutput = false; texDisplay.offx = 0; texDisplay.offy = 0; @@ -2922,6 +2927,7 @@ byte *D3D11DebugManager::GetTextureData(ResourceId id, uint32_t arrayIdx, uint32 texDisplay.rangemax = whitePoint; texDisplay.scale = 1.0f; texDisplay.texid = id; + texDisplay.typeHint = typeHint; texDisplay.rawoutput = false; texDisplay.offx = 0; texDisplay.offy = 0; @@ -2975,9 +2981,10 @@ byte *D3D11DebugManager::GetTextureData(ResourceId id, uint32_t arrayIdx, uint32 return ret; } -ResourceId D3D11DebugManager::ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip) +ResourceId D3D11DebugManager::ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip, + FormatComponentType typeHint) { - TextureShaderDetails details = GetShaderDetails(texid, false); + TextureShaderDetails details = GetShaderDetails(texid, typeHint, false); CreateCustomShaderTex(details.texWidth, details.texHeight); @@ -3003,6 +3010,7 @@ ResourceId D3D11DebugManager::ApplyCustomShader(ResourceId shader, ResourceId te disp.offy = 0.0f; disp.CustomShader = shader; disp.texid = texid; + disp.typeHint = typeHint; disp.lightBackgroundColour = disp.darkBackgroundColour = FloatVector(0, 0, 0, 0); disp.HDRMul = -1.0f; disp.linearDisplayAsGamma = true; @@ -3070,10 +3078,11 @@ void D3D11DebugManager::CreateCustomShaderTex(uint32_t w, uint32_t h) #include "data/hlsl/debugcbuffers.h" -ResourceId D3D11DebugManager::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, - uint32_t eventID, const vector &passEvents) +ResourceId D3D11DebugManager::RenderOverlay(ResourceId texid, FormatComponentType typeHint, + TextureDisplayOverlay overlay, uint32_t eventID, + const vector &passEvents) { - TextureShaderDetails details = GetShaderDetails(texid, false); + TextureShaderDetails details = GetShaderDetails(texid, typeHint, false); ResourceId id = texid; @@ -4176,7 +4185,8 @@ void D3D11DebugManager::PixelHistoryCopyPixel(CopyPixelParams &p, uint32_t x, ui vector D3D11DebugManager::PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, - uint32_t sampleIdx) + uint32_t sampleIdx, + FormatComponentType typeHint) { vector history; @@ -4185,13 +4195,13 @@ vector D3D11DebugManager::PixelHistory(vector eve if(events.empty()) return history; - TextureShaderDetails details = GetShaderDetails(target, true); + TextureShaderDetails details = GetShaderDetails(target, typeHint, true); if(details.texFmt == DXGI_FORMAT_UNKNOWN) return history; details.texFmt = GetNonSRGBFormat(details.texFmt); - details.texFmt = GetTypedFormat(details.texFmt); + details.texFmt = GetTypedFormat(details.texFmt, typeHint); SCOPED_TIMER("D3D11DebugManager::PixelHistory"); diff --git a/renderdoc/driver/d3d11/d3d11_debug.cpp b/renderdoc/driver/d3d11/d3d11_debug.cpp index f70756773..22528cbb0 100644 --- a/renderdoc/driver/d3d11/d3d11_debug.cpp +++ b/renderdoc/driver/d3d11/d3d11_debug.cpp @@ -38,39 +38,6 @@ #include "d3d11_manager.h" #include "d3d11_renderstate.h" -// used for serialising out ms textures - converts typeless to uint typed where possible, -// or float/unorm if necessary. Only typeless formats are converted. -DXGI_FORMAT GetTypedFormatUIntPreferred(DXGI_FORMAT f) -{ - switch(f) - { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: return DXGI_FORMAT_R32G32B32A32_UINT; - case DXGI_FORMAT_R32G32B32_TYPELESS: return DXGI_FORMAT_R32G32B32_UINT; - case DXGI_FORMAT_R16G16B16A16_TYPELESS: return DXGI_FORMAT_R16G16B16A16_UINT; - case DXGI_FORMAT_R32G32_TYPELESS: return DXGI_FORMAT_R32G32_UINT; - case DXGI_FORMAT_R10G10B10A2_TYPELESS: return DXGI_FORMAT_R10G10B10A2_UINT; - case DXGI_FORMAT_R8G8B8A8_TYPELESS: return DXGI_FORMAT_R8G8B8A8_UINT; - case DXGI_FORMAT_R16G16_TYPELESS: return DXGI_FORMAT_R16G16_UINT; - case DXGI_FORMAT_R32_TYPELESS: return DXGI_FORMAT_R32_UINT; - case DXGI_FORMAT_R8G8_TYPELESS: return DXGI_FORMAT_R8G8_UINT; - case DXGI_FORMAT_R16_TYPELESS: return DXGI_FORMAT_R16_UINT; - case DXGI_FORMAT_R8_TYPELESS: return DXGI_FORMAT_R8_UINT; - case DXGI_FORMAT_BC1_TYPELESS: return DXGI_FORMAT_BC1_UNORM; - case DXGI_FORMAT_BC2_TYPELESS: return DXGI_FORMAT_BC2_UNORM; - case DXGI_FORMAT_BC3_TYPELESS: return DXGI_FORMAT_BC3_UNORM; - case DXGI_FORMAT_BC4_TYPELESS: return DXGI_FORMAT_BC4_UNORM; - case DXGI_FORMAT_BC5_TYPELESS: return DXGI_FORMAT_BC5_UNORM; - case DXGI_FORMAT_B8G8R8A8_TYPELESS: return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; - case DXGI_FORMAT_B8G8R8X8_TYPELESS: return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; - case DXGI_FORMAT_BC6H_TYPELESS: return DXGI_FORMAT_BC6H_UF16; - case DXGI_FORMAT_BC7_TYPELESS: return DXGI_FORMAT_BC7_UNORM; - - default: break; - } - - return f; -} - typedef HRESULT(WINAPI *pD3DCreateBlob)(SIZE_T Size, ID3DBlob **ppBlob); struct D3DBlobShaderCallbacks @@ -1854,13 +1821,13 @@ uint32_t D3D11DebugManager::GetStructCount(ID3D11UnorderedAccessView *uav) } bool D3D11DebugManager::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, - uint32_t sample, float minval, float maxval, bool channels[4], - vector &histogram) + uint32_t sample, FormatComponentType typeHint, float minval, + float maxval, bool channels[4], vector &histogram) { if(minval >= maxval) return false; - TextureShaderDetails details = GetShaderDetails(texid, true); + TextureShaderDetails details = GetShaderDetails(texid, typeHint, true); if(details.texFmt == DXGI_FORMAT_UNKNOWN) return false; @@ -1964,10 +1931,10 @@ bool D3D11DebugManager::GetHistogram(ResourceId texid, uint32_t sliceFace, uint3 return true; } -bool D3D11DebugManager::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, - uint32_t sample, float *minval, float *maxval) +bool D3D11DebugManager::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + FormatComponentType typeHint, float *minval, float *maxval) { - TextureShaderDetails details = GetShaderDetails(texid, true); + TextureShaderDetails details = GetShaderDetails(texid, typeHint, true); if(details.texFmt == DXGI_FORMAT_UNKNOWN) return false; @@ -2277,7 +2244,7 @@ void D3D11DebugManager::CopyArrayToTex2DMS(ID3D11Texture2D *destMS, ID3D11Textur D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; rtvDesc.Format = - depth ? GetUIntTypedFormat(descMS.Format) : GetTypedFormatUIntPreferred(descMS.Format); + depth ? GetUIntTypedFormat(descMS.Format) : GetTypedFormat(descMS.Format, eCompType_UInt); rtvDesc.Texture2DMSArray.ArraySize = descMS.ArraySize; rtvDesc.Texture2DMSArray.FirstArraySlice = 0; @@ -2291,7 +2258,7 @@ void D3D11DebugManager::CopyArrayToTex2DMS(ID3D11Texture2D *destMS, ID3D11Textur D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; srvDesc.Format = - depth ? GetUIntTypedFormat(descArr.Format) : GetTypedFormatUIntPreferred(descArr.Format); + depth ? GetUIntTypedFormat(descArr.Format) : GetTypedFormat(descArr.Format, eCompType_UInt); srvDesc.Texture2DArray.ArraySize = descArr.ArraySize; srvDesc.Texture2DArray.FirstArraySlice = 0; srvDesc.Texture2DArray.MipLevels = descArr.MipLevels; @@ -2566,7 +2533,7 @@ void D3D11DebugManager::CopyTex2DMSToArray(ID3D11Texture2D *destArray, ID3D11Tex D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; rtvDesc.Format = - depth ? GetUIntTypedFormat(descArr.Format) : GetTypedFormatUIntPreferred(descArr.Format); + depth ? GetUIntTypedFormat(descArr.Format) : GetTypedFormat(descArr.Format, eCompType_UInt); rtvDesc.Texture2DArray.FirstArraySlice = 0; rtvDesc.Texture2DArray.ArraySize = 1; rtvDesc.Texture2DArray.MipSlice = 0; @@ -2582,7 +2549,7 @@ void D3D11DebugManager::CopyTex2DMSToArray(ID3D11Texture2D *destArray, ID3D11Tex D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; srvDesc.Format = - depth ? GetUIntTypedFormat(descMS.Format) : GetTypedFormatUIntPreferred(descMS.Format); + depth ? GetUIntTypedFormat(descMS.Format) : GetTypedFormat(descMS.Format, eCompType_UInt); srvDesc.Texture2DMSArray.ArraySize = descMS.ArraySize; srvDesc.Texture2DMSArray.FirstArraySlice = 0; @@ -2761,11 +2728,12 @@ void D3D11DebugManager::CopyTex2DMSToArray(ID3D11Texture2D *destArray, ID3D11Tex SAFE_RELEASE(srvResource); } -D3D11DebugManager::CacheElem &D3D11DebugManager::GetCachedElem(ResourceId id, bool raw) +D3D11DebugManager::CacheElem &D3D11DebugManager::GetCachedElem(ResourceId id, + FormatComponentType typeHint, bool raw) { for(auto it = m_ShaderItemCache.begin(); it != m_ShaderItemCache.end(); ++it) { - if(it->id == id && it->raw == raw) + if(it->id == id && it->typeHint == typeHint && it->raw == raw) return *it; } @@ -2776,19 +2744,19 @@ D3D11DebugManager::CacheElem &D3D11DebugManager::GetCachedElem(ResourceId id, bo m_ShaderItemCache.pop_back(); } - m_ShaderItemCache.push_front(CacheElem(id, raw)); + m_ShaderItemCache.push_front(CacheElem(id, typeHint, raw)); return m_ShaderItemCache.front(); } -D3D11DebugManager::TextureShaderDetails D3D11DebugManager::GetShaderDetails(ResourceId id, - bool rawOutput) +D3D11DebugManager::TextureShaderDetails D3D11DebugManager::GetShaderDetails( + ResourceId id, FormatComponentType typeHint, bool rawOutput) { TextureShaderDetails details; HRESULT hr = S_OK; bool foundResource = false; - CacheElem &cache = GetCachedElem(id, rawOutput); + CacheElem &cache = GetCachedElem(id, typeHint, rawOutput); bool msaaDepth = false; @@ -2818,7 +2786,7 @@ D3D11DebugManager::TextureShaderDetails D3D11DebugManager::GetShaderDetails(Reso details.texArraySize = desc1d.ArraySize; details.texMips = desc1d.MipLevels; - srvFormat = GetTypedFormat(details.texFmt); + srvFormat = GetTypedFormat(details.texFmt, typeHint); details.srvResource = wrapTex1D->GetReal(); @@ -2886,7 +2854,7 @@ D3D11DebugManager::TextureShaderDetails D3D11DebugManager::GetShaderDetails(Reso if(mode == TEXDISPLAY_DEPTH_TARGET || IsDepthFormat(details.texFmt)) { details.texType = eTexType_Depth; - details.texFmt = GetTypedFormat(details.texFmt); + details.texFmt = GetTypedFormat(details.texFmt, typeHint); } // backbuffer is always interpreted as SRGB data regardless of format specified: @@ -2910,7 +2878,7 @@ D3D11DebugManager::TextureShaderDetails D3D11DebugManager::GetShaderDetails(Reso details.texFmt = GetSRGBFormat(wrapTex2D->m_RealDescriptor->Format); } - srvFormat = GetTypedFormat(details.texFmt); + srvFormat = GetTypedFormat(details.texFmt, typeHint); details.srvResource = wrapTex2D->GetReal(); @@ -2977,7 +2945,7 @@ D3D11DebugManager::TextureShaderDetails D3D11DebugManager::GetShaderDetails(Reso details.texArraySize = 1; details.texMips = desc3d.MipLevels; - srvFormat = GetTypedFormat(details.texFmt); + srvFormat = GetTypedFormat(details.texFmt, typeHint); details.srvResource = wrapTex3D->GetReal(); @@ -3325,7 +3293,8 @@ bool D3D11DebugManager::RenderTexture(TextureDisplay cfg, bool blendAlpha) pixelData.FlipY = cfg.FlipY ? 1 : 0; - TextureShaderDetails details = GetShaderDetails(cfg.texid, cfg.rawoutput ? true : false); + TextureShaderDetails details = + GetShaderDetails(cfg.texid, cfg.typeHint, cfg.rawoutput ? true : false); pixelData.SampleIdx = (int)RDCCLAMP(cfg.sampleIdx, 0U, details.sampleCount - 1); diff --git a/renderdoc/driver/d3d11/d3d11_debug.h b/renderdoc/driver/d3d11/d3d11_debug.h index bd0a1dc40..5274101ba 100644 --- a/renderdoc/driver/d3d11/d3d11_debug.h +++ b/renderdoc/driver/d3d11/d3d11_debug.h @@ -127,17 +127,19 @@ public: void GetBufferData(ID3D11Buffer *buff, uint64_t offset, uint64_t length, vector &retData, bool unwrap); - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, - bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize); + byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + FormatComponentType typeHint, bool resolve, bool forceRGBA8unorm, + float blackPoint, float whitePoint, size_t &dataSize); void FillCBufferVariables(const vector &invars, vector &outvars, bool flattenVec4s, const vector &data); - bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, - float *maxval); + bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + FormatComponentType typeHint, float *minval, float *maxval); bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, - float minval, float maxval, bool channels[4], vector &histogram); + FormatComponentType typeHint, float minval, float maxval, bool channels[4], + vector &histogram); void CopyArrayToTex2DMS(ID3D11Texture2D *destMS, ID3D11Texture2D *srcArray); void CopyTex2DMSToArray(ID3D11Texture2D *destArray, ID3D11Texture2D *srcMS); @@ -179,19 +181,21 @@ public: vector PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, - uint32_t sampleIdx); + uint32_t sampleIdx, FormatComponentType typeHint); ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset); ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive); ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]); void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, - uint32_t sample, float pixel[4]); + uint32_t sample, FormatComponentType typeHint, float pixel[4]); uint32_t PickVertex(uint32_t eventID, const MeshDisplay &cfg, uint32_t x, uint32_t y); - ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, + ResourceId RenderOverlay(ResourceId texid, FormatComponentType typeHint, + TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents); - ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip); + ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip, + FormatComponentType typeHint); // don't need to differentiate arrays as we treat everything // as an array (potentially with only one element). @@ -249,12 +253,13 @@ public: ID3D11ShaderResourceView *srv[eTexType_Max]; }; - TextureShaderDetails GetShaderDetails(ResourceId id, bool rawOutput); + TextureShaderDetails GetShaderDetails(ResourceId id, FormatComponentType typeHint, bool rawOutput); private: struct CacheElem { - CacheElem(ResourceId id_, bool raw_) : created(false), id(id_), raw(raw_), srvResource(NULL) + CacheElem(ResourceId id_, FormatComponentType typeHint_, bool raw_) + : created(false), id(id_), typeHint(typeHint_), raw(raw_), srvResource(NULL) { srv[0] = srv[1] = srv[2] = NULL; } @@ -269,6 +274,7 @@ private: bool created; ResourceId id; + FormatComponentType typeHint; bool raw; ID3D11Resource *srvResource; ID3D11ShaderResourceView *srv[3]; @@ -278,7 +284,7 @@ private: std::list m_ShaderItemCache; - CacheElem &GetCachedElem(ResourceId id, bool raw); + CacheElem &GetCachedElem(ResourceId id, FormatComponentType typeHint, bool raw); int m_width, m_height; float m_supersamplingX, m_supersamplingY; diff --git a/renderdoc/driver/d3d11/d3d11_replay.cpp b/renderdoc/driver/d3d11/d3d11_replay.cpp index 4502cd981..2ca307d50 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.cpp +++ b/renderdoc/driver/d3d11/d3d11_replay.cpp @@ -1411,17 +1411,18 @@ ResourceId D3D11Replay::GetLiveID(ResourceId id) } bool D3D11Replay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, - float *minval, float *maxval) + FormatComponentType typeHint, float *minval, float *maxval) { - return m_pDevice->GetDebugManager()->GetMinMax(texid, sliceFace, mip, sample, minval, maxval); + return m_pDevice->GetDebugManager()->GetMinMax(texid, sliceFace, mip, sample, typeHint, minval, + maxval); } bool D3D11Replay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, - float minval, float maxval, bool channels[4], - vector &histogram) + FormatComponentType typeHint, float minval, float maxval, + bool channels[4], vector &histogram) { - return m_pDevice->GetDebugManager()->GetHistogram(texid, sliceFace, mip, sample, minval, maxval, - channels, histogram); + return m_pDevice->GetDebugManager()->GetHistogram(texid, sliceFace, mip, sample, typeHint, minval, + maxval, channels, histogram); } MeshFormat D3D11Replay::GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage) @@ -1434,12 +1435,12 @@ void D3D11Replay::GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, m_pDevice->GetDebugManager()->GetBufferData(buff, offset, len, retData); } -byte *D3D11Replay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, - bool forceRGBA8unorm, float blackPoint, float whitePoint, - size_t &dataSize) +byte *D3D11Replay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + FormatComponentType typeHint, bool resolve, bool forceRGBA8unorm, + float blackPoint, float whitePoint, size_t &dataSize) { - return m_pDevice->GetDebugManager()->GetTextureData(tex, arrayIdx, mip, resolve, forceRGBA8unorm, - blackPoint, whitePoint, dataSize); + return m_pDevice->GetDebugManager()->GetTextureData( + tex, arrayIdx, mip, typeHint, resolve, forceRGBA8unorm, blackPoint, whitePoint, dataSize); } void D3D11Replay::ReplaceResource(ResourceId from, ResourceId to) @@ -1521,9 +1522,11 @@ void D3D11Replay::FillCBufferVariables(ResourceId shader, string entryPoint, uin vector D3D11Replay::PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, - uint32_t mip, uint32_t sampleIdx) + uint32_t mip, uint32_t sampleIdx, + FormatComponentType typeHint) { - return m_pDevice->GetDebugManager()->PixelHistory(events, target, x, y, slice, mip, sampleIdx); + return m_pDevice->GetDebugManager()->PixelHistory(events, target, x, y, slice, mip, sampleIdx, + typeHint); } ShaderDebugTrace D3D11Replay::DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, @@ -1550,20 +1553,23 @@ uint32_t D3D11Replay::PickVertex(uint32_t eventID, const MeshDisplay &cfg, uint3 } void D3D11Replay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, - uint32_t mip, uint32_t sample, float pixel[4]) + uint32_t mip, uint32_t sample, FormatComponentType typeHint, + float pixel[4]) { - m_pDevice->GetDebugManager()->PickPixel(texture, x, y, sliceFace, mip, sample, pixel); + m_pDevice->GetDebugManager()->PickPixel(texture, x, y, sliceFace, mip, sample, typeHint, pixel); } -ResourceId D3D11Replay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, - uint32_t eventID, const vector &passEvents) +ResourceId D3D11Replay::RenderOverlay(ResourceId texid, FormatComponentType typeHint, + TextureDisplayOverlay overlay, uint32_t eventID, + const vector &passEvents) { - return m_pDevice->GetDebugManager()->RenderOverlay(texid, overlay, eventID, passEvents); + return m_pDevice->GetDebugManager()->RenderOverlay(texid, typeHint, overlay, eventID, passEvents); } -ResourceId D3D11Replay::ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip) +ResourceId D3D11Replay::ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip, + FormatComponentType typeHint) { - return m_pDevice->GetDebugManager()->ApplyCustomShader(shader, texid, mip); + return m_pDevice->GetDebugManager()->ApplyCustomShader(shader, texid, mip, typeHint); } bool D3D11Replay::IsRenderOutput(ResourceId id) diff --git a/renderdoc/driver/d3d11/d3d11_replay.h b/renderdoc/driver/d3d11/d3d11_replay.h index 3da3254ff..386b21792 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.h +++ b/renderdoc/driver/d3d11/d3d11_replay.h @@ -90,16 +90,18 @@ public: ResourceId GetLiveID(ResourceId id); - bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, - float *maxval); + bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + FormatComponentType typeHint, float *minval, float *maxval); bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, - float minval, float maxval, bool channels[4], vector &histogram); + FormatComponentType typeHint, float minval, float maxval, bool channels[4], + vector &histogram); MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData); - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, - bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize); + byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + FormatComponentType typeHint, bool resolve, bool forceRGBA8unorm, + float blackPoint, float whitePoint, size_t &dataSize); void BuildTargetShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors); @@ -130,22 +132,24 @@ public: vector PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, - uint32_t sampleIdx); + uint32_t sampleIdx, FormatComponentType typeHint); ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset); ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive); ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]); void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, - uint32_t sample, float pixel[4]); + uint32_t sample, FormatComponentType typeHint, float pixel[4]); uint32_t PickVertex(uint32_t eventID, const MeshDisplay &cfg, uint32_t x, uint32_t y); - ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t eventID, + ResourceId RenderOverlay(ResourceId texid, FormatComponentType typeHint, + TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents); void BuildCustomShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors); - ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip); + ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip, + FormatComponentType typeHint); bool IsRenderOutput(ResourceId id); diff --git a/renderdoc/driver/d3d11/d3d11_resources.cpp b/renderdoc/driver/d3d11/d3d11_resources.cpp index 4886ec483..bf8396fb8 100644 --- a/renderdoc/driver/d3d11/d3d11_resources.cpp +++ b/renderdoc/driver/d3d11/d3d11_resources.cpp @@ -1148,6 +1148,169 @@ DXGI_FORMAT GetTypedFormat(DXGI_FORMAT f) return f; } +DXGI_FORMAT GetTypedFormat(DXGI_FORMAT f, FormatComponentType typeHint) +{ + switch(f) + { + // these formats have multiple typed formats - use the hint to decide which to use + + case DXGI_FORMAT_R8_TYPELESS: + { + if(typeHint == eCompType_UInt) + return DXGI_FORMAT_R8_UINT; + if(typeHint == eCompType_SInt) + return DXGI_FORMAT_R8_SINT; + if(typeHint == eCompType_SNorm) + return DXGI_FORMAT_R8_SNORM; + return DXGI_FORMAT_R8_UNORM; + } + + case DXGI_FORMAT_R8G8_TYPELESS: + { + if(typeHint == eCompType_UInt) + return DXGI_FORMAT_R8G8_UINT; + if(typeHint == eCompType_SInt) + return DXGI_FORMAT_R8G8_SINT; + if(typeHint == eCompType_SNorm) + return DXGI_FORMAT_R8G8_SNORM; + return DXGI_FORMAT_R8G8_UNORM; + } + + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + { + if(typeHint == eCompType_UInt) + return DXGI_FORMAT_R8G8B8A8_UINT; + if(typeHint == eCompType_SInt) + return DXGI_FORMAT_R8G8B8A8_SINT; + if(typeHint == eCompType_SNorm) + return DXGI_FORMAT_R8G8B8A8_SNORM; + return DXGI_FORMAT_R8G8B8A8_UNORM; + } + + case DXGI_FORMAT_R16_TYPELESS: + { + if(typeHint == eCompType_UInt) + return DXGI_FORMAT_R16_UINT; + if(typeHint == eCompType_SInt) + return DXGI_FORMAT_R16_SINT; + if(typeHint == eCompType_SNorm) + return DXGI_FORMAT_R16_SNORM; + if(typeHint == eCompType_Float) + return DXGI_FORMAT_R16_FLOAT; + if(typeHint == eCompType_Depth) + return DXGI_FORMAT_D16_UNORM; + return DXGI_FORMAT_R16_UNORM; + } + + case DXGI_FORMAT_R16G16_TYPELESS: + { + if(typeHint == eCompType_UInt) + return DXGI_FORMAT_R16G16_UINT; + if(typeHint == eCompType_SInt) + return DXGI_FORMAT_R16G16_SINT; + if(typeHint == eCompType_SNorm) + return DXGI_FORMAT_R16G16_SNORM; + if(typeHint == eCompType_Float) + return DXGI_FORMAT_R16G16_FLOAT; + return DXGI_FORMAT_R16G16_UNORM; + } + + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + { + if(typeHint == eCompType_UInt) + return DXGI_FORMAT_R16G16B16A16_UINT; + if(typeHint == eCompType_SInt) + return DXGI_FORMAT_R16G16B16A16_SINT; + if(typeHint == eCompType_SNorm) + return DXGI_FORMAT_R16G16B16A16_SNORM; + if(typeHint == eCompType_Float) + return DXGI_FORMAT_R16G16B16A16_FLOAT; + return DXGI_FORMAT_R16G16B16A16_UNORM; + } + + case DXGI_FORMAT_R32_TYPELESS: + { + if(typeHint == eCompType_UInt) + return DXGI_FORMAT_R32_UINT; + if(typeHint == eCompType_SInt) + return DXGI_FORMAT_R32_SINT; + if(typeHint == eCompType_Depth) + return DXGI_FORMAT_D32_FLOAT; + return DXGI_FORMAT_R32_FLOAT; + } + + case DXGI_FORMAT_R32G32_TYPELESS: + { + if(typeHint == eCompType_UInt) + return DXGI_FORMAT_R32G32_UINT; + if(typeHint == eCompType_SInt) + return DXGI_FORMAT_R32G32_SINT; + return DXGI_FORMAT_R32G32_FLOAT; + } + + case DXGI_FORMAT_R32G32B32_TYPELESS: + { + if(typeHint == eCompType_UInt) + return DXGI_FORMAT_R32G32B32_UINT; + if(typeHint == eCompType_SInt) + return DXGI_FORMAT_R32G32B32_SINT; + return DXGI_FORMAT_R32G32B32_FLOAT; + } + + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + { + if(typeHint == eCompType_UInt) + return DXGI_FORMAT_R32G32B32A32_UINT; + if(typeHint == eCompType_SInt) + return DXGI_FORMAT_R32G32B32A32_SINT; + return DXGI_FORMAT_R32G32B32A32_FLOAT; + } + + case DXGI_FORMAT_R32G8X24_TYPELESS: + { + if(typeHint == eCompType_UInt) + return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; + if(typeHint == eCompType_Depth) + return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; + } + + case DXGI_FORMAT_R24G8_TYPELESS: + { + if(typeHint == eCompType_UInt) + return DXGI_FORMAT_X24_TYPELESS_G8_UINT; + if(typeHint == eCompType_Depth) + return DXGI_FORMAT_D24_UNORM_S8_UINT; + return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + } + + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + return typeHint == eCompType_UInt ? DXGI_FORMAT_R10G10B10A2_UINT + : DXGI_FORMAT_R10G10B10A2_UNORM; + + case DXGI_FORMAT_BC4_TYPELESS: + return typeHint == eCompType_SNorm ? DXGI_FORMAT_BC4_SNORM : DXGI_FORMAT_BC4_UNORM; + + case DXGI_FORMAT_BC5_TYPELESS: + return typeHint == eCompType_SNorm ? DXGI_FORMAT_BC5_SNORM : DXGI_FORMAT_BC5_UNORM; + + case DXGI_FORMAT_BC6H_TYPELESS: + return typeHint == eCompType_SNorm ? DXGI_FORMAT_BC6H_SF16 : DXGI_FORMAT_BC6H_UF16; + + // these formats have only one valid non-typeless format (ignoring SRGB) + case DXGI_FORMAT_B8G8R8A8_TYPELESS: return DXGI_FORMAT_B8G8R8A8_UNORM; + case DXGI_FORMAT_B8G8R8X8_TYPELESS: return DXGI_FORMAT_B8G8R8X8_UNORM; + case DXGI_FORMAT_BC1_TYPELESS: return DXGI_FORMAT_BC1_UNORM; + case DXGI_FORMAT_BC2_TYPELESS: return DXGI_FORMAT_BC2_UNORM; + case DXGI_FORMAT_BC3_TYPELESS: return DXGI_FORMAT_BC3_UNORM; + case DXGI_FORMAT_BC7_TYPELESS: return DXGI_FORMAT_BC7_UNORM; + + default: break; + } + + return f; +} + DXGI_FORMAT GetTypelessFormat(DXGI_FORMAT f) { switch(f) diff --git a/renderdoc/driver/d3d11/d3d11_resources.h b/renderdoc/driver/d3d11/d3d11_resources.h index 52c946199..b0f7aa055 100644 --- a/renderdoc/driver/d3d11/d3d11_resources.h +++ b/renderdoc/driver/d3d11/d3d11_resources.h @@ -74,6 +74,7 @@ UINT GetFormatBPP(DXGI_FORMAT f); DXGI_FORMAT GetTypelessFormat(DXGI_FORMAT f); DXGI_FORMAT GetTypedFormat(DXGI_FORMAT f); +DXGI_FORMAT GetTypedFormat(DXGI_FORMAT f, FormatComponentType hint); DXGI_FORMAT GetDepthTypedFormat(DXGI_FORMAT f); DXGI_FORMAT GetFloatTypedFormat(DXGI_FORMAT f); DXGI_FORMAT GetUnormTypedFormat(DXGI_FORMAT f); diff --git a/renderdoc/driver/gl/gl_debug.cpp b/renderdoc/driver/gl/gl_debug.cpp index 7bce13748..7fad011e3 100644 --- a/renderdoc/driver/gl/gl_debug.cpp +++ b/renderdoc/driver/gl/gl_debug.cpp @@ -661,7 +661,7 @@ void GLReplay::DeleteDebugData() } bool GLReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, - float *minval, float *maxval) + FormatComponentType typeHint, float *minval, float *maxval) { if(m_pDriver->m_Textures.find(texid) == m_pDriver->m_Textures.end()) return false; @@ -826,7 +826,8 @@ bool GLReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uin } bool GLReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, - float minval, float maxval, bool channels[4], vector &histogram) + FormatComponentType typeHint, float minval, float maxval, + bool channels[4], vector &histogram) { if(minval >= maxval) return false; @@ -1203,7 +1204,7 @@ uint32_t GLReplay::PickVertex(uint32_t eventID, const MeshDisplay &cfg, uint32_t } void GLReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, - uint32_t mip, uint32_t sample, float pixel[4]) + uint32_t mip, uint32_t sample, FormatComponentType typeHint, float pixel[4]) { WrappedOpenGL &gl = *m_pDriver; @@ -1232,6 +1233,7 @@ void GLReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sl texDisplay.rangemax = 1.0f; texDisplay.scale = 1.0f; texDisplay.texid = texture; + texDisplay.typeHint = typeHint; texDisplay.rawoutput = true; texDisplay.offx = -float(x); texDisplay.offy = -float(y); @@ -1769,8 +1771,9 @@ void GLReplay::SetupOverlayPipeline(GLuint Program, GLuint Pipeline, GLuint frag gl.glUseProgramStages(DebugData.overlayPipe, eGL_FRAGMENT_SHADER_BIT, fragProgram); } -ResourceId GLReplay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, - uint32_t eventID, const vector &passEvents) +ResourceId GLReplay::RenderOverlay(ResourceId texid, FormatComponentType typeHint, + TextureDisplayOverlay overlay, uint32_t eventID, + const vector &passEvents) { WrappedOpenGL &gl = *m_pDriver; diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 1c59a580e..faee331ec 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -2202,9 +2202,9 @@ void GLReplay::FillCBufferVariables(ResourceId shader, string entryPoint, uint32 outvars, data); } -byte *GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, - bool forceRGBA8unorm, float blackPoint, float whitePoint, - size_t &dataSize) +byte *GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + FormatComponentType typeHint, bool resolve, bool forceRGBA8unorm, + float blackPoint, float whitePoint, size_t &dataSize) { WrappedOpenGL &gl = *m_pDriver; @@ -2319,6 +2319,7 @@ byte *GLReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, texDisplay.rangemax = whitePoint; texDisplay.scale = 1.0f; texDisplay.texid = tex; + texDisplay.typeHint = eCompType_None; texDisplay.rawoutput = false; texDisplay.offx = 0; texDisplay.offy = 0; @@ -2591,7 +2592,8 @@ void GLReplay::BuildCustomShader(string source, string entry, const uint32_t com *id = m_pDriver->GetResourceManager()->GetID(ProgramRes(m_pDriver->GetCtx(), shaderprog)); } -ResourceId GLReplay::ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip) +ResourceId GLReplay::ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip, + FormatComponentType typeHint) { if(shader == ResourceId() || texid == ResourceId()) return ResourceId(); @@ -2621,6 +2623,7 @@ ResourceId GLReplay::ApplyCustomShader(ResourceId shader, ResourceId texid, uint disp.offy = 0.0f; disp.CustomShader = shader; disp.texid = texid; + disp.typeHint = typeHint; disp.lightBackgroundColour = disp.darkBackgroundColour = FloatVector(0, 0, 0, 0); disp.HDRMul = -1.0f; disp.linearDisplayAsGamma = true; @@ -3017,8 +3020,8 @@ void GLReplay::SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t las } vector GLReplay::PixelHistory(vector events, ResourceId target, - uint32_t x, uint32_t y, uint32_t slice, - uint32_t mip, uint32_t sampleIdx) + uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, + uint32_t sampleIdx, FormatComponentType typeHint) { GLNOTIMP("GLReplay::PixelHistory"); return vector(); diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index 247d9d45b..a650b5c25 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -130,16 +130,18 @@ public: ResourceId GetLiveID(ResourceId id); - bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, - float *maxval); + bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + FormatComponentType typeHint, float *minval, float *maxval); bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, - float minval, float maxval, bool channels[4], vector &histogram); + FormatComponentType typeHint, float minval, float maxval, bool channels[4], + vector &histogram); MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &ret); - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, - bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize); + byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + FormatComponentType typeHint, bool resolve, bool forceRGBA8unorm, + float blackPoint, float whitePoint, size_t &dataSize); void ReplaceResource(ResourceId from, ResourceId to); void RemoveReplacement(ResourceId id); @@ -168,19 +170,20 @@ public: vector PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, - uint32_t sampleIdx); + uint32_t sampleIdx, FormatComponentType typeHint); ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset); ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive); ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]); void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, - uint32_t sample, float pixel[4]); + uint32_t sample, FormatComponentType typeHint, float pixel[4]); uint32_t PickVertex(uint32_t eventID, const MeshDisplay &cfg, uint32_t x, uint32_t y); - ResourceId RenderOverlay(ResourceId cfg, TextureDisplayOverlay overlay, uint32_t eventID, - const vector &passEvents); - ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip); + ResourceId RenderOverlay(ResourceId id, FormatComponentType typeHint, TextureDisplayOverlay overlay, + uint32_t eventID, const vector &passEvents); + ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip, + FormatComponentType typeHint); ResourceId CreateProxyTexture(const FetchTexture &templateTex); void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index 76261316a..371b136d8 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -905,7 +905,8 @@ ShaderReflection *VulkanReplay::GetShader(ResourceId shader, string entryPoint) } void VulkanReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, - uint32_t mip, uint32_t sample, float pixel[4]) + uint32_t mip, uint32_t sample, FormatComponentType typeHint, + float pixel[4]) { int oldW = m_DebugWidth, oldH = m_DebugHeight; @@ -935,6 +936,7 @@ void VulkanReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_ texDisplay.rangemax = 1.0f; texDisplay.scale = 1.0f; texDisplay.texid = texture; + texDisplay.typeHint = typeHint; texDisplay.rawoutput = true; texDisplay.offx = -float(x); texDisplay.offy = -float(y); @@ -1636,8 +1638,9 @@ void VulkanReplay::RenderHighlightBox(float w, float h, float scale) #endif } -ResourceId VulkanReplay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, - uint32_t eventID, const vector &passEvents) +ResourceId VulkanReplay::RenderOverlay(ResourceId texid, FormatComponentType typeHint, + TextureDisplayOverlay overlay, uint32_t eventID, + const vector &passEvents) { return GetDebugManager()->RenderOverlay(texid, overlay, eventID, passEvents); } @@ -3971,7 +3974,7 @@ void VulkanReplay::FillCBufferVariables(ResourceId shader, string entryPoint, ui } bool VulkanReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, - float *minval, float *maxval) + FormatComponentType typeHint, float *minval, float *maxval) { VkDevice dev = m_pDriver->GetDev(); VkCommandBuffer cmd = m_pDriver->GetNextCmd(); @@ -4218,8 +4221,8 @@ bool VulkanReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, } bool VulkanReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, - float minval, float maxval, bool channels[4], - vector &histogram) + FormatComponentType typeHint, float minval, float maxval, + bool channels[4], vector &histogram) { if(minval >= maxval) return false; @@ -4513,9 +4516,9 @@ MeshFormat VulkanReplay::GetPostVSBuffers(uint32_t eventID, uint32_t instID, Mes return GetDebugManager()->GetPostVSBuffers(eventID, instID, stage); } -byte *VulkanReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, - bool forceRGBA8unorm, float blackPoint, float whitePoint, - size_t &dataSize) +byte *VulkanReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + FormatComponentType typeHint, bool resolve, bool forceRGBA8unorm, + float blackPoint, float whitePoint, size_t &dataSize) { bool wasms = false; @@ -4699,6 +4702,7 @@ byte *VulkanReplay::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t m texDisplay.rangemax = whitePoint; texDisplay.scale = 1.0f; texDisplay.texid = tex; + texDisplay.typeHint = eCompType_None; texDisplay.rawoutput = true; texDisplay.offx = 0; texDisplay.offy = 0; @@ -5095,7 +5099,8 @@ void VulkanReplay::FreeCustomShader(ResourceId id) m_pDriver->ReleaseResource(GetResourceManager()->GetCurrentResource(id)); } -ResourceId VulkanReplay::ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip) +ResourceId VulkanReplay::ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip, + FormatComponentType typeHint) { if(shader == ResourceId() || texid == ResourceId()) return ResourceId(); @@ -5116,6 +5121,7 @@ ResourceId VulkanReplay::ApplyCustomShader(ResourceId shader, ResourceId texid, disp.offy = 0.0f; disp.CustomShader = shader; disp.texid = texid; + disp.typeHint = typeHint; disp.lightBackgroundColour = disp.darkBackgroundColour = FloatVector(0, 0, 0, 0); disp.HDRMul = -1.0f; disp.linearDisplayAsGamma = true; @@ -5217,7 +5223,8 @@ void VulkanReplay::FreeTargetResource(ResourceId id) vector VulkanReplay::PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, - uint32_t mip, uint32_t sampleIdx) + uint32_t mip, uint32_t sampleIdx, + FormatComponentType typeHint) { VULKANNOTIMP("PixelHistory"); return vector(); diff --git a/renderdoc/driver/vulkan/vk_replay.h b/renderdoc/driver/vulkan/vk_replay.h index 087369c4f..e3bdd14c3 100644 --- a/renderdoc/driver/vulkan/vk_replay.h +++ b/renderdoc/driver/vulkan/vk_replay.h @@ -138,16 +138,18 @@ public: void DescribeCounter(uint32_t counterID, CounterDescription &desc); vector FetchCounters(const vector &counters); - bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, - float *maxval); + bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, + FormatComponentType typeHint, float *minval, float *maxval); bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, - float minval, float maxval, bool channels[4], vector &histogram); + FormatComponentType typeHint, float minval, float maxval, bool channels[4], + vector &histogram); MeshFormat GetPostVSBuffers(uint32_t eventID, uint32_t instID, MeshDataStage stage); void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData); - byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, - bool forceRGBA8unorm, float blackPoint, float whitePoint, size_t &dataSize); + byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + FormatComponentType typeHint, bool resolve, bool forceRGBA8unorm, + float blackPoint, float whitePoint, size_t &dataSize); void ReplaceResource(ResourceId from, ResourceId to); void RemoveReplacement(ResourceId id); @@ -171,19 +173,21 @@ public: vector PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, - uint32_t sampleIdx); + uint32_t sampleIdx, FormatComponentType typeHint); ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset); ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive); ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]); void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, - uint32_t sample, float pixel[4]); + uint32_t sample, FormatComponentType typeHint, float pixel[4]); uint32_t PickVertex(uint32_t eventID, const MeshDisplay &cfg, uint32_t x, uint32_t y); - ResourceId RenderOverlay(ResourceId cfg, TextureDisplayOverlay overlay, uint32_t eventID, + ResourceId RenderOverlay(ResourceId cfg, FormatComponentType typeHint, + TextureDisplayOverlay overlay, uint32_t eventID, const vector &passEvents); - ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip); + ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip, + FormatComponentType typeHint); ResourceId CreateProxyTexture(const FetchTexture &templateTex); void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, diff --git a/renderdoc/replay/replay_driver.h b/renderdoc/replay/replay_driver.h index 2f065149e..f2ddaca1d 100644 --- a/renderdoc/replay/replay_driver.h +++ b/renderdoc/replay/replay_driver.h @@ -88,9 +88,9 @@ public: virtual void GetBufferData(ResourceId buff, uint64_t offset, uint64_t len, vector &retData) = 0; - virtual byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, bool resolve, - bool forceRGBA8unorm, float blackPoint, float whitePoint, - size_t &dataSize) = 0; + virtual byte *GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t mip, + FormatComponentType typeHint, bool resolve, bool forceRGBA8unorm, + float blackPoint, float whitePoint, size_t &dataSize) = 0; virtual void BuildTargetShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) = 0; @@ -107,7 +107,8 @@ public: virtual vector PixelHistory(vector events, ResourceId target, uint32_t x, uint32_t y, uint32_t slice, - uint32_t mip, uint32_t sampleIdx) = 0; + uint32_t mip, uint32_t sampleIdx, + FormatComponentType typeHint) = 0; virtual ShaderDebugTrace DebugVertex(uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset) = 0; virtual ShaderDebugTrace DebugPixel(uint32_t eventID, uint32_t x, uint32_t y, uint32_t sample, @@ -115,8 +116,9 @@ public: virtual ShaderDebugTrace DebugThread(uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]) = 0; - virtual ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, - uint32_t eventID, const vector &passEvents) = 0; + virtual ResourceId RenderOverlay(ResourceId texid, FormatComponentType typeHint, + TextureDisplayOverlay overlay, uint32_t eventID, + const vector &passEvents) = 0; virtual bool IsRenderOutput(ResourceId id) = 0; @@ -143,10 +145,10 @@ public: virtual void FlipOutputWindow(uint64_t id) = 0; virtual bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, - float *minval, float *maxval) = 0; + FormatComponentType typeHint, float *minval, float *maxval) = 0; virtual bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, - float minval, float maxval, bool channels[4], - vector &histogram) = 0; + FormatComponentType typeHint, float minval, float maxval, + bool channels[4], vector &histogram) = 0; virtual ResourceId CreateProxyTexture(const FetchTexture &templateTex) = 0; virtual void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, @@ -161,15 +163,16 @@ public: virtual void BuildCustomShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) = 0; - virtual ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip) = 0; + virtual ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip, + FormatComponentType typeHint) = 0; virtual void FreeCustomShader(ResourceId id) = 0; virtual void RenderCheckerboard(Vec3f light, Vec3f dark) = 0; virtual void RenderHighlightBox(float w, float h, float scale) = 0; - virtual void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, - uint32_t mip, uint32_t sample, float pixel[4]) = 0; + virtual void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, + uint32_t sample, FormatComponentType typeHint, float pixel[4]) = 0; virtual uint32_t PickVertex(uint32_t eventID, const MeshDisplay &cfg, uint32_t x, uint32_t y) = 0; }; diff --git a/renderdoc/replay/replay_output.cpp b/renderdoc/replay/replay_output.cpp index f72941709..376370afa 100644 --- a/renderdoc/replay/replay_output.cpp +++ b/renderdoc/replay/replay_output.cpp @@ -142,9 +142,9 @@ void ReplayOutput::RefreshOverlay() { if(draw && m_pDevice->IsRenderOutput(m_RenderData.texDisplay.texid)) { - m_OverlayResourceId = - m_pDevice->RenderOverlay(m_pDevice->GetLiveID(m_RenderData.texDisplay.texid), - m_RenderData.texDisplay.overlay, m_EventID, passEvents); + m_OverlayResourceId = m_pDevice->RenderOverlay( + m_pDevice->GetLiveID(m_RenderData.texDisplay.texid), m_RenderData.texDisplay.typeHint, + m_RenderData.texDisplay.overlay, m_EventID, passEvents); m_OverlayDirty = false; } } @@ -189,7 +189,7 @@ bool ReplayOutput::SetPixelContext(void *wnd) return true; } -bool ReplayOutput::AddThumbnail(void *wnd, ResourceId texID) +bool ReplayOutput::AddThumbnail(void *wnd, ResourceId texID, FormatComponentType typeHint) { OutputPair p; @@ -215,6 +215,8 @@ bool ReplayOutput::AddThumbnail(void *wnd, ResourceId texID) m_Thumbnails[i].depthMode = depthMode; + m_Thumbnails[i].typeHint = typeHint; + m_Thumbnails[i].dirty = true; return true; @@ -225,6 +227,7 @@ bool ReplayOutput::AddThumbnail(void *wnd, ResourceId texID) p.outputID = m_pDevice->MakeOutputWindow(p.wndHandle, false); p.texture = texID; p.depthMode = depthMode; + p.typeHint = typeHint; p.dirty = true; RDCASSERT(p.outputID > 0); @@ -244,10 +247,13 @@ bool ReplayOutput::PickPixel(ResourceId tex, bool customShader, uint32_t x, uint bool decodeRamp = false; + FormatComponentType typeHint = m_RenderData.texDisplay.typeHint; + if(customShader && m_RenderData.texDisplay.CustomShader != ResourceId() && m_CustomShaderResourceId != ResourceId()) { tex = m_CustomShaderResourceId; + typeHint = eCompType_None; } if((m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawDraw || m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawPass) && @@ -255,9 +261,11 @@ bool ReplayOutput::PickPixel(ResourceId tex, bool customShader, uint32_t x, uint { decodeRamp = true; tex = m_OverlayResourceId; + typeHint = eCompType_None; } - m_pDevice->PickPixel(m_pDevice->GetLiveID(tex), x, y, sliceFace, mip, sample, ret->value_f); + m_pDevice->PickPixel(m_pDevice->GetLiveID(tex), x, y, sliceFace, mip, sample, typeHint, + ret->value_f); if(decodeRamp) { @@ -425,12 +433,16 @@ bool ReplayOutput::Display() disp.sampleIdx = ~0U; disp.CustomShader = ResourceId(); disp.texid = m_pDevice->GetLiveID(m_Thumbnails[i].texture); + disp.typeHint = m_Thumbnails[i].typeHint; disp.scale = -1.0f; disp.rangemin = 0.0f; disp.rangemax = 1.0f; disp.sliceFace = 0; disp.rawoutput = false; + if(m_Thumbnails[i].typeHint == eCompType_SNorm) + disp.rangemin = -1.0f; + if(m_Thumbnails[i].depthMode) disp.Green = disp.Blue = false; @@ -506,10 +518,11 @@ void ReplayOutput::DisplayTex() if(m_RenderData.texDisplay.CustomShader != ResourceId()) { - m_CustomShaderResourceId = m_pDevice->ApplyCustomShader(m_RenderData.texDisplay.CustomShader, - texDisplay.texid, texDisplay.mip); + m_CustomShaderResourceId = m_pDevice->ApplyCustomShader( + m_RenderData.texDisplay.CustomShader, texDisplay.texid, texDisplay.mip, texDisplay.typeHint); texDisplay.texid = m_pDevice->GetLiveID(m_CustomShaderResourceId); + texDisplay.typeHint = eCompType_None; texDisplay.CustomShader = ResourceId(); texDisplay.sliceFace = 0; texDisplay.mip = 0; @@ -676,9 +689,10 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_ClearThumbnails(Replay return output->ClearThumbnails(); } extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_AddThumbnail(ReplayOutput *output, - void *wnd, ResourceId texID) + void *wnd, ResourceId texID, + FormatComponentType typeHint) { - return output->AddThumbnail(wnd, texID); + return output->AddThumbnail(wnd, texID, typeHint); } extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayOutput_Display(ReplayOutput *output) diff --git a/renderdoc/replay/replay_renderer.cpp b/renderdoc/replay/replay_renderer.cpp index ead9d1f1f..2a6e071e5 100644 --- a/renderdoc/replay/replay_renderer.cpp +++ b/renderdoc/replay/replay_renderer.cpp @@ -412,7 +412,7 @@ bool ReplayRenderer::GetPostVSData(uint32_t instID, MeshDataStage stage, MeshFor } bool ReplayRenderer::GetMinMax(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, - PixelValue *minval, PixelValue *maxval) + FormatComponentType typeHint, PixelValue *minval, PixelValue *maxval) { PixelValue *a = minval; PixelValue *b = maxval; @@ -424,21 +424,21 @@ bool ReplayRenderer::GetMinMax(ResourceId tex, uint32_t sliceFace, uint32_t mip, if(b == NULL) b = &dummy; - return m_pDevice->GetMinMax(m_pDevice->GetLiveID(tex), sliceFace, mip, sample, &a->value_f[0], - &b->value_f[0]); + return m_pDevice->GetMinMax(m_pDevice->GetLiveID(tex), sliceFace, mip, sample, typeHint, + &a->value_f[0], &b->value_f[0]); } bool ReplayRenderer::GetHistogram(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, - float minval, float maxval, bool channels[4], - rdctype::array *histogram) + FormatComponentType typeHint, float minval, float maxval, + bool channels[4], rdctype::array *histogram) { if(histogram == NULL) return false; vector hist; - bool ret = m_pDevice->GetHistogram(m_pDevice->GetLiveID(tex), sliceFace, mip, sample, minval, - maxval, channels, hist); + bool ret = m_pDevice->GetHistogram(m_pDevice->GetLiveID(tex), sliceFace, mip, sample, typeHint, + minval, maxval, channels, hist); if(ret) *histogram = hist; @@ -483,7 +483,8 @@ bool ReplayRenderer::GetTextureData(ResourceId tex, uint32_t arrayIdx, uint32_t } size_t sz; - byte *bytes = m_pDevice->GetTextureData(liveId, arrayIdx, mip, false, false, 0.0f, 0.0f, sz); + byte *bytes = + m_pDevice->GetTextureData(liveId, arrayIdx, mip, eCompType_None, false, false, 0.0f, 0.0f, sz); create_array_init(*data, sz, bytes); @@ -740,8 +741,9 @@ bool ReplayRenderer::SaveTexture(const TextureSave &saveData, const char *path) uint32_t mip = m + mipOffset; size_t datasize = 0; - byte *bytes = m_pDevice->GetTextureData(liveid, slice, mip, resolveSamples, downcast, - sd.comp.blackPoint, sd.comp.whitePoint, datasize); + byte *bytes = + m_pDevice->GetTextureData(liveid, slice, mip, sd.typeHint, resolveSamples, downcast, + sd.comp.blackPoint, sd.comp.whitePoint, datasize); if(bytes == NULL) { @@ -1258,7 +1260,7 @@ bool ReplayRenderer::SaveTexture(const TextureSave &saveData, const char *path) } bool ReplayRenderer::PixelHistory(ResourceId target, uint32_t x, uint32_t y, uint32_t slice, - uint32_t mip, uint32_t sampleIdx, + uint32_t mip, uint32_t sampleIdx, FormatComponentType typeHint, rdctype::array *history) { for(size_t t = 0; t < m_Textures.size(); t++) @@ -1347,8 +1349,8 @@ bool ReplayRenderer::PixelHistory(ResourceId target, uint32_t x, uint32_t y, uin return false; } - *history = - m_pDevice->PixelHistory(events, m_pDevice->GetLiveID(target), x, y, slice, mip, sampleIdx); + *history = m_pDevice->PixelHistory(events, m_pDevice->GetLiveID(target), x, y, slice, mip, + sampleIdx, typeHint); SetFrameEvent(m_EventID, true); @@ -1805,9 +1807,9 @@ ReplayRenderer_GetDebugMessages(ReplayRenderer *rend, rdctype::array *history) + uint32_t sampleIdx, FormatComponentType typeHint, rdctype::array *history) { - return rend->PixelHistory(target, x, y, slice, mip, sampleIdx, history); + return rend->PixelHistory(target, x, y, slice, mip, sampleIdx, typeHint, history); } extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_DebugVertex(ReplayRenderer *rend, uint32_t vertid, uint32_t instid, uint32_t idx, @@ -1859,18 +1861,19 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetPostVSData(Replay return rend->GetPostVSData(instID, stage, data); } -extern "C" RENDERDOC_API bool32 RENDERDOC_CC -ReplayRenderer_GetMinMax(ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, - uint32_t sample, PixelValue *minval, PixelValue *maxval) -{ - return rend->GetMinMax(tex, sliceFace, mip, sample, minval, maxval); -} -extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetHistogram( +extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetMinMax( ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, - float minval, float maxval, bool32 channels[4], rdctype::array *histogram) + FormatComponentType typeHint, PixelValue *minval, PixelValue *maxval) +{ + return rend->GetMinMax(tex, sliceFace, mip, sample, typeHint, minval, maxval); +} +extern "C" RENDERDOC_API bool32 RENDERDOC_CC +ReplayRenderer_GetHistogram(ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, + uint32_t sample, FormatComponentType typeHint, float minval, + float maxval, bool32 channels[4], rdctype::array *histogram) { bool chans[4] = {channels[0] != 0, channels[1] != 0, channels[2] != 0, channels[3] != 0}; - return rend->GetHistogram(tex, sliceFace, mip, sample, minval, maxval, chans, histogram); + return rend->GetHistogram(tex, sliceFace, mip, sample, typeHint, minval, maxval, chans, histogram); } extern "C" RENDERDOC_API bool32 RENDERDOC_CC ReplayRenderer_GetBufferData( diff --git a/renderdoc/replay/replay_renderer.h b/renderdoc/replay/replay_renderer.h index ba968c8d9..c33ded718 100644 --- a/renderdoc/replay/replay_renderer.h +++ b/renderdoc/replay/replay_renderer.h @@ -43,7 +43,7 @@ public: bool SetMeshDisplay(const MeshDisplay &o); bool ClearThumbnails(); - bool AddThumbnail(void *wnd, ResourceId texID); + bool AddThumbnail(void *wnd, ResourceId texID, FormatComponentType typeHint); bool Display(); @@ -86,6 +86,7 @@ private: ResourceId texture; bool depthMode; void *wndHandle; + FormatComponentType typeHint; uint64_t outputID; bool dirty; @@ -166,7 +167,8 @@ public: bool GetDebugMessages(rdctype::array *msgs); bool PixelHistory(ResourceId target, uint32_t x, uint32_t y, uint32_t slice, uint32_t mip, - uint32_t sampleIdx, rdctype::array *history); + uint32_t sampleIdx, FormatComponentType typeHint, + rdctype::array *history); bool DebugVertex(uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset, ShaderDebugTrace *trace); bool DebugPixel(uint32_t x, uint32_t y, uint32_t sample, uint32_t primitive, @@ -176,9 +178,10 @@ public: bool GetPostVSData(uint32_t instID, MeshDataStage stage, MeshFormat *data); bool GetMinMax(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, - PixelValue *minval, PixelValue *maxval); - bool GetHistogram(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, - float maxval, bool channels[4], rdctype::array *histogram); + FormatComponentType typeHint, PixelValue *minval, PixelValue *maxval); + bool GetHistogram(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, + FormatComponentType typeHint, float minval, float maxval, bool channels[4], + rdctype::array *histogram); bool GetUsage(ResourceId id, rdctype::array *usage); diff --git a/renderdocui/Code/CommonPipelineState.cs b/renderdocui/Code/CommonPipelineState.cs index f12db28d6..883dd23c0 100644 --- a/renderdocui/Code/CommonPipelineState.cs +++ b/renderdocui/Code/CommonPipelineState.cs @@ -34,13 +34,14 @@ namespace renderdocui.Code public class BoundResource { public BoundResource() - { Id = ResourceId.Null; HighestMip = -1; FirstSlice = -1; } + { Id = ResourceId.Null; HighestMip = -1; FirstSlice = -1; typeHint = FormatComponentType.None; } public BoundResource(ResourceId id) - { Id = id; HighestMip = -1; FirstSlice = -1; } + { Id = id; HighestMip = -1; FirstSlice = -1; typeHint = FormatComponentType.None; } public ResourceId Id; public int HighestMip; public int FirstSlice; + public FormatComponentType typeHint; }; public struct BoundVBuffer @@ -907,6 +908,7 @@ namespace renderdocui.Code val.Id = s.SRVs[i].Resource; val.HighestMip = (int)s.SRVs[i].HighestMip; val.FirstSlice = (int)s.SRVs[i].FirstArraySlice; + val.typeHint = s.SRVs[i].Format.compType; ret.Add(key, new BoundResource[] { val }); } @@ -923,6 +925,7 @@ namespace renderdocui.Code val.Id = m_GL.Textures[i].Resource; val.HighestMip = (int)m_GL.Textures[i].HighestMip; val.FirstSlice = (int)m_GL.Textures[i].FirstSlice; + val.typeHint = FormatComponentType.None; ret.Add(key, new BoundResource[] { val }); } @@ -959,6 +962,7 @@ namespace renderdocui.Code val[i].Id = bind.binds[i].res; val[i].HighestMip = (int)bind.binds[i].baseMip; val[i].FirstSlice = (int)bind.binds[i].baseLayer; + val[i].typeHint = bind.binds[i].viewfmt.compType; } ret.Add(key, val); @@ -991,6 +995,7 @@ namespace renderdocui.Code val.Id = m_D3D11.m_CS.UAVs[i].Resource; val.HighestMip = (int)m_D3D11.m_CS.UAVs[i].HighestMip; val.FirstSlice = (int)m_D3D11.m_CS.UAVs[i].FirstArraySlice; + val.typeHint = m_D3D11.m_CS.UAVs[i].Format.compType; ret.Add(key, new BoundResource[] { val }); } @@ -1005,6 +1010,7 @@ namespace renderdocui.Code val.Id = m_D3D11.m_OM.UAVs[i].Resource; val.HighestMip = (int)m_D3D11.m_OM.UAVs[i].HighestMip; val.FirstSlice = (int)m_D3D11.m_OM.UAVs[i].FirstArraySlice; + val.typeHint = FormatComponentType.None; ret.Add(key, new BoundResource[] { val }); } @@ -1022,6 +1028,7 @@ namespace renderdocui.Code val.Id = m_GL.Images[i].Resource; val.HighestMip = (int)m_GL.Images[i].Level; val.FirstSlice = (int)m_GL.Images[i].Layer; + val.typeHint = m_GL.Images[i].Format.compType; ret.Add(key, new BoundResource[] { val }); } @@ -1057,6 +1064,7 @@ namespace renderdocui.Code val[i].Id = bind.binds[i].res; val[i].HighestMip = (int)bind.binds[i].baseMip; val[i].FirstSlice = (int)bind.binds[i].baseLayer; + val[i].typeHint = bind.binds[i].viewfmt.compType; } ret.Add(key, val); @@ -1081,6 +1089,7 @@ namespace renderdocui.Code ret.Id = m_D3D11.m_OM.DepthTarget.Resource; ret.HighestMip = (int)m_D3D11.m_OM.DepthTarget.HighestMip; ret.FirstSlice = (int)m_D3D11.m_OM.DepthTarget.FirstArraySlice; + ret.typeHint = m_D3D11.m_OM.DepthTarget.Format.compType; return ret; } else if (IsLogGL) @@ -1089,6 +1098,7 @@ namespace renderdocui.Code ret.Id = m_GL.m_FB.m_DrawFBO.Depth.Obj; ret.HighestMip = (int)m_GL.m_FB.m_DrawFBO.Depth.Mip; ret.FirstSlice = (int)m_GL.m_FB.m_DrawFBO.Depth.Layer; + ret.typeHint = FormatComponentType.None; return ret; } else if (IsLogVK) @@ -1102,6 +1112,7 @@ namespace renderdocui.Code ret.Id = fb.attachments[rp.depthstencilAttachment].img; ret.HighestMip = (int)fb.attachments[rp.depthstencilAttachment].baseMip; ret.FirstSlice = (int)fb.attachments[rp.depthstencilAttachment].baseLayer; + ret.typeHint = fb.attachments[rp.depthstencilAttachment].viewfmt.compType; return ret; } @@ -1125,6 +1136,7 @@ namespace renderdocui.Code ret[i].Id = m_D3D11.m_OM.RenderTargets[i].Resource; ret[i].HighestMip = (int)m_D3D11.m_OM.RenderTargets[i].HighestMip; ret[i].FirstSlice = (int)m_D3D11.m_OM.RenderTargets[i].FirstArraySlice; + ret[i].typeHint = m_D3D11.m_OM.RenderTargets[i].Format.compType; } return ret; @@ -1143,6 +1155,7 @@ namespace renderdocui.Code ret[i].Id = m_GL.m_FB.m_DrawFBO.Color[db].Obj; ret[i].HighestMip = (int)m_GL.m_FB.m_DrawFBO.Color[db].Mip; ret[i].FirstSlice = (int)m_GL.m_FB.m_DrawFBO.Color[db].Layer; + ret[i].typeHint = FormatComponentType.None; } } @@ -1163,6 +1176,7 @@ namespace renderdocui.Code ret[i].Id = fb.attachments[rp.colorAttachments[i]].img; ret[i].HighestMip = (int)fb.attachments[rp.colorAttachments[i]].baseMip; ret[i].FirstSlice = (int)fb.attachments[rp.colorAttachments[i]].baseLayer; + ret[i].typeHint = fb.attachments[rp.colorAttachments[i]].viewfmt.compType; } } diff --git a/renderdocui/Interop/Enums.cs b/renderdocui/Interop/Enums.cs index b2f03d586..1ca9c3a78 100644 --- a/renderdocui/Interop/Enums.cs +++ b/renderdocui/Interop/Enums.cs @@ -814,5 +814,25 @@ namespace renderdoc return "Unknown"; } + + public static string Str(this FormatComponentType compType) + { + switch (compType) + { + case FormatComponentType.None: return "Typeless"; + case FormatComponentType.Float: return "Float"; + case FormatComponentType.UNorm: return "UNorm"; + case FormatComponentType.SNorm: return "SNorm"; + case FormatComponentType.UInt: return "UInt"; + case FormatComponentType.SInt: return "SInt"; + case FormatComponentType.UScaled: return "UScaled"; + case FormatComponentType.SScaled: return "SScaled"; + case FormatComponentType.Depth: return "Depth"; + case FormatComponentType.Double: return "Double"; + default: break; + } + + return "Unknown"; + } } } diff --git a/renderdocui/Interop/FetchInfo.cs b/renderdocui/Interop/FetchInfo.cs index ebae2f516..c0cdeaa3e 100644 --- a/renderdocui/Interop/FetchInfo.cs +++ b/renderdocui/Interop/FetchInfo.cs @@ -645,6 +645,7 @@ namespace renderdoc public class TextureDisplay { public ResourceId texid = ResourceId.Null; + public FormatComponentType typeHint = FormatComponentType.None; public float rangemin = 0.0f; public float rangemax = 1.0f; public float scale = 1.0f; @@ -671,6 +672,8 @@ namespace renderdoc { public ResourceId id = ResourceId.Null; + public FormatComponentType typeHint = FormatComponentType.None; + public FileType destType = FileType.DDS; public Int32 mip = -1; diff --git a/renderdocui/Interop/ReplayRenderer.cs b/renderdocui/Interop/ReplayRenderer.cs index ac567e1b8..5b0f18923 100644 --- a/renderdocui/Interop/ReplayRenderer.cs +++ b/renderdocui/Interop/ReplayRenderer.cs @@ -88,7 +88,7 @@ namespace renderdoc [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] private static extern bool ReplayOutput_ClearThumbnails(IntPtr real); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - private static extern bool ReplayOutput_AddThumbnail(IntPtr real, IntPtr wnd, ResourceId texID); + private static extern bool ReplayOutput_AddThumbnail(IntPtr real, IntPtr wnd, ResourceId texID, FormatComponentType typeHint); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] private static extern bool ReplayOutput_Display(IntPtr real); @@ -130,9 +130,9 @@ namespace renderdoc { return ReplayOutput_ClearThumbnails(m_Real); } - public bool AddThumbnail(IntPtr wnd, ResourceId texID) + public bool AddThumbnail(IntPtr wnd, ResourceId texID, FormatComponentType typeHint) { - return ReplayOutput_AddThumbnail(m_Real, wnd, texID); + return ReplayOutput_AddThumbnail(m_Real, wnd, texID, typeHint); } public bool Display() @@ -251,7 +251,7 @@ namespace renderdoc private static extern bool ReplayRenderer_GetDebugMessages(IntPtr real, IntPtr outmsgs); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - private static extern bool ReplayRenderer_PixelHistory(IntPtr real, ResourceId target, UInt32 x, UInt32 y, UInt32 slice, UInt32 mip, UInt32 sampleIdx, IntPtr history); + private static extern bool ReplayRenderer_PixelHistory(IntPtr real, ResourceId target, UInt32 x, UInt32 y, UInt32 slice, UInt32 mip, UInt32 sampleIdx, FormatComponentType typeHint, IntPtr history); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] private static extern bool ReplayRenderer_DebugVertex(IntPtr real, UInt32 vertid, UInt32 instid, UInt32 idx, UInt32 instOffset, UInt32 vertOffset, IntPtr outtrace); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] @@ -272,9 +272,9 @@ namespace renderdoc private static extern bool ReplayRenderer_GetPostVSData(IntPtr real, UInt32 instID, MeshDataStage stage, IntPtr outdata); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - private static extern bool ReplayRenderer_GetMinMax(IntPtr real, ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, IntPtr outminval, IntPtr outmaxval); + private static extern bool ReplayRenderer_GetMinMax(IntPtr real, ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, FormatComponentType typeHint, IntPtr outminval, IntPtr outmaxval); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] - private static extern bool ReplayRenderer_GetHistogram(IntPtr real, ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, float minval, float maxval, bool[] channels, IntPtr outhistogram); + private static extern bool ReplayRenderer_GetHistogram(IntPtr real, ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, FormatComponentType typeHint, float minval, float maxval, bool[] channels, IntPtr outhistogram); [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] private static extern bool ReplayRenderer_GetBufferData(IntPtr real, ResourceId buff, UInt64 offset, UInt64 len, IntPtr outdata); @@ -634,11 +634,11 @@ namespace renderdoc return ret; } - public PixelModification[] PixelHistory(ResourceId target, UInt32 x, UInt32 y, UInt32 slice, UInt32 mip, UInt32 sampleIdx) + public PixelModification[] PixelHistory(ResourceId target, UInt32 x, UInt32 y, UInt32 slice, UInt32 mip, UInt32 sampleIdx, FormatComponentType typeHint) { IntPtr mem = CustomMarshal.Alloc(typeof(templated_array)); - bool success = ReplayRenderer_PixelHistory(m_Real, target, x, y, slice, mip, sampleIdx, mem); + bool success = ReplayRenderer_PixelHistory(m_Real, target, x, y, slice, mip, sampleIdx, typeHint, mem); PixelModification[] ret = null; @@ -761,12 +761,12 @@ namespace renderdoc return ret; } - public bool GetMinMax(ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, out PixelValue minval, out PixelValue maxval) + public bool GetMinMax(ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, FormatComponentType typeHint, out PixelValue minval, out PixelValue maxval) { IntPtr mem1 = CustomMarshal.Alloc(typeof(PixelValue)); IntPtr mem2 = CustomMarshal.Alloc(typeof(PixelValue)); - bool success = ReplayRenderer_GetMinMax(m_Real, tex, sliceFace, mip, sample, mem1, mem2); + bool success = ReplayRenderer_GetMinMax(m_Real, tex, sliceFace, mip, sample, typeHint, mem1, mem2); if (success) { @@ -785,7 +785,7 @@ namespace renderdoc return success; } - public bool GetHistogram(ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, float minval, float maxval, + public bool GetHistogram(ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, FormatComponentType typeHint, float minval, float maxval, bool Red, bool Green, bool Blue, bool Alpha, out UInt32[] histogram) { @@ -793,7 +793,7 @@ namespace renderdoc bool[] channels = new bool[] { Red, Green, Blue, Alpha }; - bool success = ReplayRenderer_GetHistogram(m_Real, tex, sliceFace, mip, sample, minval, maxval, channels, mem); + bool success = ReplayRenderer_GetHistogram(m_Real, tex, sliceFace, mip, sample, typeHint, minval, maxval, channels, mem); histogram = null; diff --git a/renderdocui/Windows/TextureViewer.cs b/renderdocui/Windows/TextureViewer.cs index 989d57eed..4ba2e83cf 100644 --- a/renderdocui/Windows/TextureViewer.cs +++ b/renderdocui/Windows/TextureViewer.cs @@ -125,6 +125,18 @@ namespace renderdocui.Windows return GetBoundResource(core, arrayEl).FirstSlice; } + public FormatComponentType GetTypeHint(Core core) + { + var curDraw = core.CurDrawcall; + bool copy, compute; + GetDrawContext(core, out copy, out compute); + + if (copy || compute) + return FormatComponentType.None; + + return GetBoundResource(core, arrayEl).typeHint; + } + public ResourceId GetResourceId(Core core) { return GetBoundResource(core, arrayEl).Id; @@ -374,12 +386,19 @@ namespace renderdocui.Windows public class TexSettings { - public TexSettings() { r = g = b = true; a = false; mip = 0; slice = 0; minrange = 0.0f; maxrange = 1.0f; } + public TexSettings() + { + r = g = b = true; a = false; + mip = 0; slice = 0; + minrange = 0.0f; maxrange = 1.0f; + typeHint = FormatComponentType.None; + } public bool r, g, b, a; public bool depth, stencil; public int mip, slice; public float minrange, maxrange; + public FormatComponentType typeHint; } private Dictionary m_TextureSettings = new Dictionary(); @@ -1048,6 +1067,8 @@ namespace renderdocui.Windows m_TexDisplay.darkBackgroundColour = darkBack; m_TexDisplay.lightBackgroundColour = lightBack; + m_TexDisplay.typeHint = FormatComponentType.None; + m_Core.Renderer.BeginInvoke(RT_UpdateAndDisplay); } @@ -1086,6 +1107,8 @@ namespace renderdocui.Windows m_TexDisplay.darkBackgroundColour = darkBack; m_TexDisplay.lightBackgroundColour = lightBack; + m_TexDisplay.typeHint = FormatComponentType.None; + PixelPicked = false; statusLabel.Text = ""; @@ -1127,7 +1150,7 @@ namespace renderdocui.Windows UI_UpdateChannels(); } - private void InitResourcePreview(ResourcePreview prev, ResourceId id, bool force, Following follow, string bindName, string slotName) + private void InitResourcePreview(ResourcePreview prev, ResourceId id, FormatComponentType typeHint, bool force, Following follow, string bindName, string slotName) { if (id != ResourceId.Null || force) { @@ -1157,7 +1180,7 @@ namespace renderdocui.Windows IntPtr handle = prev.ThumbnailHandle; m_Core.Renderer.BeginInvoke((ReplayRenderer rep) => { - m_Output.AddThumbnail(handle, id); + m_Output.AddThumbnail(handle, id, typeHint); }); } else if (buf != null) @@ -1176,7 +1199,7 @@ namespace renderdocui.Windows IntPtr handle = prev.ThumbnailHandle; m_Core.Renderer.BeginInvoke((ReplayRenderer rep) => { - m_Output.AddThumbnail(handle, ResourceId.Null); + m_Output.AddThumbnail(handle, ResourceId.Null, FormatComponentType.None); }); } else @@ -1185,7 +1208,7 @@ namespace renderdocui.Windows IntPtr handle = prev.ThumbnailHandle; m_Core.Renderer.BeginInvoke((ReplayRenderer rep) => { - m_Output.AddThumbnail(handle, ResourceId.Null); + m_Output.AddThumbnail(handle, ResourceId.Null, FormatComponentType.None); }); } @@ -1209,7 +1232,7 @@ namespace renderdocui.Windows prev.Init("Unused", tex.width, tex.height, tex.depth, tex.mips); m_Core.Renderer.BeginInvoke((ReplayRenderer rep) => { - m_Output.AddThumbnail(handle, ResourceId.Null); + m_Output.AddThumbnail(handle, ResourceId.Null, FormatComponentType.None); }); } else @@ -1238,6 +1261,7 @@ namespace renderdocui.Windows for (int arrayIdx = 0; arrayIdx < arrayLen; arrayIdx++) { ResourceId id = resArray != null ? resArray[arrayIdx].Id : ResourceId.Null; + FormatComponentType typeHint = resArray != null ? resArray[arrayIdx].typeHint : FormatComponentType.None; bool used = key.used; bool skip = false; @@ -1294,7 +1318,7 @@ namespace renderdocui.Windows prevIndex++; - InitResourcePreview(prev, show ? id : ResourceId.Null, show, follow, bindName, slotName); + InitResourcePreview(prev, show ? id : ResourceId.Null, typeHint, show, follow, bindName, slotName); } } } @@ -1334,7 +1358,7 @@ namespace renderdocui.Windows string bindName = copy ? "Destination" : ""; string slotName = copy ? "DST" : String.Format("{0}{1}", m_Core.CurPipelineState.OutputAbbrev(), rt); - InitResourcePreview(prev, RTs[rt].Id, false, follow, bindName, slotName); + InitResourcePreview(prev, RTs[rt].Id, RTs[rt].typeHint, false, follow, bindName, slotName); } // depth @@ -1350,7 +1374,7 @@ namespace renderdocui.Windows Following follow = new Following(FollowType.OutputDepth, ShaderStageType.Pixel, 0, 0); - InitResourcePreview(prev, Depth.Id, false, follow, "", "DS"); + InitResourcePreview(prev, Depth.Id, Depth.typeHint, false, follow, "", "DS"); } ShaderStageType[] stages = new ShaderStageType[] { @@ -1449,9 +1473,9 @@ namespace renderdocui.Windows private PointF m_PrevSize = PointF.Empty; - private void UI_SetHistogramRange(FetchTexture tex) + private void UI_SetHistogramRange(FetchTexture tex, FormatComponentType typeHint) { - if (tex != null && tex.format.compType == FormatComponentType.SNorm) + if (tex != null && (tex.format.compType == FormatComponentType.SNorm || typeHint == FormatComponentType.SNorm)) rangeHistogram.SetRange(-1.0f, 1.0f); else rangeHistogram.SetRange(0.0f, 1.0f); @@ -1487,10 +1511,19 @@ namespace renderdocui.Windows m_TextureSettings[m_TexDisplay.texid].minrange = rangeHistogram.BlackPoint; m_TextureSettings[m_TexDisplay.texid].maxrange = rangeHistogram.WhitePoint; + + m_TextureSettings[m_TexDisplay.texid].typeHint = m_Following.GetTypeHint(m_Core); } m_TexDisplay.texid = tex.ID; + // interpret the texture according to the currently following type. + m_TexDisplay.typeHint = m_Following.GetTypeHint(m_Core); + + // if there is no such type or it isn't being followed, use the last seen interpretation + if (m_TexDisplay.typeHint == FormatComponentType.None) + m_TexDisplay.typeHint = m_TextureSettings[m_TexDisplay.texid].typeHint; + m_CurPixelValue = null; m_CurRealValue = null; @@ -1678,14 +1711,14 @@ namespace renderdocui.Windows depthDisplay.Checked = true; norangePaint = true; - UI_SetHistogramRange(tex); + UI_SetHistogramRange(tex, m_TexDisplay.typeHint); norangePaint = false; } // reset the range if desired if (m_Core.Config.TextureViewer_ResetRange) { - UI_SetHistogramRange(tex); + UI_SetHistogramRange(tex, m_TexDisplay.typeHint); } } @@ -1868,6 +1901,12 @@ namespace renderdocui.Windows texStatusDim.Text += " " + current.mips + " mips"; texStatusDim.Text += " - " + current.format.ToString(); + + if (current.format.compType != m_TexDisplay.typeHint && + m_TexDisplay.typeHint != FormatComponentType.None) + { + texStatusDim.Text += " Viewed as type " + m_TexDisplay.typeHint.Str(); + } } private bool PixelPicked @@ -3083,7 +3122,7 @@ namespace renderdocui.Windows private void reset01_Click(object sender, EventArgs e) { - UI_SetHistogramRange(CurrentTexture); + UI_SetHistogramRange(CurrentTexture, m_TexDisplay.typeHint); autoFit.Checked = false; @@ -3115,7 +3154,10 @@ namespace renderdocui.Windows m_Core.Renderer.BeginInvoke((ReplayRenderer r) => { PixelValue min, max; - bool success = r.GetMinMax(m_TexDisplay.texid, m_TexDisplay.sliceFace, m_TexDisplay.mip, m_TexDisplay.sampleIdx, out min, out max); + bool success = r.GetMinMax(m_TexDisplay.texid, + m_TexDisplay.sliceFace, m_TexDisplay.mip, m_TexDisplay.sampleIdx, + m_TexDisplay.typeHint, + out min, out max); if (success) { @@ -3206,7 +3248,9 @@ namespace renderdocui.Windows bool success = true; uint[] histogram; - success = r.GetHistogram(m_TexDisplay.texid, m_TexDisplay.sliceFace, m_TexDisplay.mip, m_TexDisplay.sampleIdx, + success = r.GetHistogram(m_TexDisplay.texid, + m_TexDisplay.sliceFace, m_TexDisplay.mip, m_TexDisplay.sampleIdx, + m_TexDisplay.typeHint, rangeHistogram.RangeMin, rangeHistogram.RangeMax, m_TexDisplay.Red, m_TexDisplay.Green && fmt.compCount > 1, @@ -3356,7 +3400,10 @@ namespace renderdocui.Windows Thread.Sleep(100); m_Core.Renderer.BeginInvoke((ReplayRenderer r) => { - history = r.PixelHistory(CurrentTexture.ID, (UInt32)x, (UInt32)y, m_TexDisplay.sliceFace, m_TexDisplay.mip, m_TexDisplay.sampleIdx); + history = r.PixelHistory(CurrentTexture.ID, + (UInt32)x, (UInt32)y, + m_TexDisplay.sliceFace, m_TexDisplay.mip, m_TexDisplay.sampleIdx, + m_TexDisplay.typeHint); this.BeginInvoke(new Action(() => { @@ -3419,6 +3466,7 @@ namespace renderdocui.Windows m_SaveDialog = new TextureSaveDialog(m_Core); m_SaveDialog.saveData.id = m_TexDisplay.texid; + m_SaveDialog.saveData.typeHint = m_TexDisplay.typeHint; m_SaveDialog.saveData.slice.sliceIndex = (int)m_TexDisplay.sliceFace; m_SaveDialog.saveData.mip = (int)m_TexDisplay.mip;