diff --git a/renderdoc/core/replay_proxy.h b/renderdoc/core/replay_proxy.h index c4ae87dd3..7707a9e2f 100644 --- a/renderdoc/core/replay_proxy.h +++ b/renderdoc/core/replay_proxy.h @@ -170,23 +170,23 @@ class ProxySerialiser : public IReplayDriver, Callstack::StackResolver return m_Proxy->RenderHighlightBox(w, h, scale); } - bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, float *minval, float *maxval) + bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval) { if(m_Proxy) { EnsureCached(texid, sliceFace, mip); - return m_Proxy->GetMinMax(m_ProxyTextureIds[texid], sliceFace, mip, minval, maxval); + return m_Proxy->GetMinMax(m_ProxyTextureIds[texid], sliceFace, mip, sample, minval, maxval); } return false; } - bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, float minval, float maxval, bool channels[4], vector &histogram) + bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], vector &histogram) { if(m_Proxy) { EnsureCached(texid, sliceFace, mip); - return m_Proxy->GetHistogram(m_ProxyTextureIds[texid], sliceFace, mip, minval, maxval, channels, histogram); + return m_Proxy->GetHistogram(m_ProxyTextureIds[texid], sliceFace, mip, sample, minval, maxval, channels, histogram); } return false; @@ -215,12 +215,12 @@ class ProxySerialiser : public IReplayDriver, Callstack::StackResolver return false; } - void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, float pixel[4]) + void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]) { if(m_Proxy) { EnsureCached(texture, sliceFace, mip); - m_Proxy->PickPixel(m_ProxyTextureIds[texture], x, y, sliceFace, mip, pixel); + m_Proxy->PickPixel(m_ProxyTextureIds[texture], x, y, sliceFace, mip, sample, pixel); } } diff --git a/renderdoc/data/hlsl/debugcbuffers.h b/renderdoc/data/hlsl/debugcbuffers.h index 0e0fe5599..7c72ccfae 100644 --- a/renderdoc/data/hlsl/debugcbuffers.h +++ b/renderdoc/data/hlsl/debugcbuffers.h @@ -85,7 +85,8 @@ cbuffer DebugPixelCBufferData REG(b0) float Slice; float ScalePS; - float2 Padding; + int SampleIdx; + int Padding; int RawOutput; float3 TextureResolutionPS; @@ -100,7 +101,8 @@ cbuffer HistogramCBufferData REG(b0) float HistogramSlice; uint HistogramMip; - float2 Padding2; + int HistogramSample; + uint Padding2; float3 HistogramTextureResolution; float Padding3; @@ -121,6 +123,8 @@ cbuffer HistogramCBufferData REG(b0) #define RESTYPE_DEPTH_STENCIL 0x5 #define RESTYPE_DEPTH_MS 0x6 #define RESTYPE_DEPTH_STENCIL_MS 0x7 +#define RESTYPE_CUBE 0x8 +#define RESTYPE_TEX2D_MS 0x9 #define MESHDISPLAY_SOLID 0x1 #define MESHDISPLAY_FACELIT 0x2 diff --git a/renderdoc/data/hlsl/debugcommon.hlsl b/renderdoc/data/hlsl/debugcommon.hlsl index bdc65a0ba..5e76e2d9c 100644 --- a/renderdoc/data/hlsl/debugcommon.hlsl +++ b/renderdoc/data/hlsl/debugcommon.hlsl @@ -47,16 +47,19 @@ Texture2DArray texDisplayTexStencilArray : register(t5); Texture2DMSArray texDisplayTexDepthMSArray : register(t6); Texture2DMSArray texDisplayTexStencilMSArray : register(t7); Texture2DArray texDisplayTexCubeArray : register(t8); +Texture2DMSArray texDisplayTex2DMSArray : register(t9); Texture1DArray texDisplayUIntTex1DArray : register(t11); Texture2DArray texDisplayUIntTex2DArray : register(t12); Texture3D texDisplayUIntTex3D : register(t13); +Texture2DMSArray texDisplayUIntTex2DMSArray : register(t19); Texture1DArray texDisplayIntTex1DArray : register(t21); Texture2DArray texDisplayIntTex2DArray : register(t22); Texture3D texDisplayIntTex3D : register(t23); +Texture2DMSArray texDisplayIntTex2DMSArray : register(t29); -uint4 SampleTextureUInt4(uint type, float2 uv, float slice, float mip, float3 texRes) +uint4 SampleTextureUInt4(uint type, float2 uv, float slice, float mip, int sample, float3 texRes) { uint4 col = 0; @@ -66,11 +69,17 @@ uint4 SampleTextureUInt4(uint type, float2 uv, float slice, float mip, float3 te col = texDisplayUIntTex3D.Load(int4(uv.xy*texRes.xy, slice*texRes.z, mip)); else if(type == RESTYPE_TEX2D) col = texDisplayUIntTex2DArray.Load(int4(uv.xy*texRes.xy, slice, mip)); + else if(type == RESTYPE_TEX2D_MS) + { + if(sample < 0) + sample = 0; + col = texDisplayUIntTex2DMSArray.Load(int3(uv.xy*texRes.xy, slice), sample); + } return col; } -int4 SampleTextureInt4(uint type, float2 uv, float slice, float mip, float3 texRes) +int4 SampleTextureInt4(uint type, float2 uv, float slice, float mip, int sample, float3 texRes) { int4 col = 0; @@ -80,11 +89,17 @@ int4 SampleTextureInt4(uint type, float2 uv, float slice, float mip, float3 texR col = texDisplayIntTex3D.Load(int4(uv.xy*texRes.xy, slice*texRes.z, mip)); else if(type == RESTYPE_TEX2D) col = texDisplayIntTex2DArray.Load(int4(uv.xy*texRes.xy, slice, mip)); + else if(type == RESTYPE_TEX2D_MS) + { + if(sample < 0) + sample = 0; + col = texDisplayIntTex2DMSArray.Load(int3(uv.xy*texRes.xy, slice), sample); + } return col; } -float4 SampleTextureFloat4(uint type, bool linearSample, float2 uv, float slice, float mip, float3 texRes) +float4 SampleTextureFloat4(uint type, bool linearSample, float2 uv, float slice, float mip, int sample, float3 texRes) { float4 col = 0; @@ -115,15 +130,38 @@ float4 SampleTextureFloat4(uint type, bool linearSample, float2 uv, float slice, } else if(type == RESTYPE_DEPTH_MS) { - col.r = texDisplayTexDepthMSArray.Load(int3(uv.xy*texRes.xy, slice), 0).r; + if(sample < 0) + sample = 0; + + col.r = texDisplayTexDepthMSArray.Load(int3(uv.xy*texRes.xy, slice), sample).r; col.gba = float3(0, 0, 1); } else if(type == RESTYPE_DEPTH_STENCIL_MS) { - col.r = texDisplayTexDepthMSArray.Load(int3(uv.xy*texRes.xy, slice), 0).r; - col.g = texDisplayTexStencilMSArray.Load(int3(uv.xy*texRes.xy, slice), 0).g/255.0f; + if(sample < 0) + sample = 0; + + col.r = texDisplayTexDepthMSArray.Load(int3(uv.xy*texRes.xy, slice), sample).r; + col.g = texDisplayTexStencilMSArray.Load(int3(uv.xy*texRes.xy, slice), sample).g/255.0f; col.ba = float2(0, 1); } + else if(type == RESTYPE_TEX2D_MS) + { + if(sample < 0) + { + int sampleCount = -sample; + + // worst resolve you've seen in your life + for(int i=0; i < sampleCount; i++) + col += texDisplayTex2DMSArray.Load(int3(uv.xy*texRes.xy, slice), i); + + col /= float(sampleCount); + } + else + { + col = texDisplayTex2DMSArray.Load(int3(uv.xy*texRes.xy, slice), sample); + } + } else if(type == RESTYPE_TEX2D) { if(linearSample) diff --git a/renderdoc/data/hlsl/debugdisplay.hlsl b/renderdoc/data/hlsl/debugdisplay.hlsl index 4ed76c370..ff9a0803e 100644 --- a/renderdoc/data/hlsl/debugdisplay.hlsl +++ b/renderdoc/data/hlsl/debugdisplay.hlsl @@ -53,17 +53,17 @@ float4 RENDERDOC_TexDisplayPS(v2f IN) : SV_Target0 if(uintTex) { ucol = SampleTextureUInt4(OutputDisplayFormat & TEXDISPLAY_TYPEMASK, - uvTex, Slice, MipLevel, TextureResolutionPS); + uvTex, Slice, MipLevel, SampleIdx, TextureResolutionPS); } else if(sintTex) { scol = SampleTextureInt4 (OutputDisplayFormat & TEXDISPLAY_TYPEMASK, - uvTex, Slice, MipLevel, TextureResolutionPS); + uvTex, Slice, MipLevel, SampleIdx, TextureResolutionPS); } else { col = SampleTextureFloat4(OutputDisplayFormat & TEXDISPLAY_TYPEMASK, (ScalePS < 1 && MipLevel == 0), - uvTex, Slice, MipLevel, TextureResolutionPS); + uvTex, Slice, MipLevel, SampleIdx, TextureResolutionPS); } if(RawOutput) diff --git a/renderdoc/data/hlsl/histogram.hlsl b/renderdoc/data/hlsl/histogram.hlsl index bdbb64a9b..3850c35e5 100644 --- a/renderdoc/data/hlsl/histogram.hlsl +++ b/renderdoc/data/hlsl/histogram.hlsl @@ -55,7 +55,7 @@ void RENDERDOC_TileMinMaxCS(uint3 tid : SV_GroupThreadID, uint3 gid : SV_GroupID for(uint x=topleft.x; x < min(texDim.x, topleft.x + HGRAM_PIXELS_PER_TILE); x++) { uint4 data = SampleTextureUInt4(texType, float2(x, y)/float2(texDim.xy), - HistogramSlice, HistogramMip, texDim); + HistogramSlice, HistogramMip, HistogramSample, texDim); if(i == 0) { @@ -85,7 +85,7 @@ void RENDERDOC_TileMinMaxCS(uint3 tid : SV_GroupThreadID, uint3 gid : SV_GroupID for(uint x=topleft.x; x < min(texDim.x, topleft.x + HGRAM_PIXELS_PER_TILE); x++) { int4 data = SampleTextureInt4(texType, float2(x, y)/float2(texDim.xy), - HistogramSlice, HistogramMip, texDim); + HistogramSlice, HistogramMip, HistogramSample, texDim); if(i == 0) { @@ -115,7 +115,7 @@ void RENDERDOC_TileMinMaxCS(uint3 tid : SV_GroupThreadID, uint3 gid : SV_GroupID for(uint x=topleft.x; x < min(texDim.x, topleft.x + HGRAM_PIXELS_PER_TILE); x++) { float4 data = SampleTextureFloat4(texType, false, float2(x, y)/float2(texDim.xy), - HistogramSlice, HistogramMip, texDim); + HistogramSlice, HistogramMip, HistogramSample, texDim); if(i == 0) { @@ -228,7 +228,7 @@ void RENDERDOC_HistogramCS(uint3 tid : SV_GroupThreadID, uint3 gid : SV_GroupID) #if UINT_TEX { uint4 data = SampleTextureUInt4(texType, float2(x, y)/float2(texDim.xy), - HistogramSlice, HistogramMip, texDim); + HistogramSlice, HistogramMip, HistogramSample, texDim); float divisor = 0.0f; uint sum = 0; @@ -268,7 +268,7 @@ void RENDERDOC_HistogramCS(uint3 tid : SV_GroupThreadID, uint3 gid : SV_GroupID) #elif SINT_TEX { int4 data = SampleTextureInt4(texType, float2(x, y)/float2(texDim.xy), - HistogramSlice, HistogramMip, texDim); + HistogramSlice, HistogramMip, HistogramSample, texDim); float divisor = 0.0f; int sum = 0; @@ -308,7 +308,7 @@ void RENDERDOC_HistogramCS(uint3 tid : SV_GroupThreadID, uint3 gid : SV_GroupID) #else { float4 data = SampleTextureFloat4(texType, false, float2(x, y)/float2(texDim.xy), - HistogramSlice, HistogramMip, texDim); + HistogramSlice, HistogramMip, HistogramSample, texDim); float divisor = 0.0f; float sum = 0.0f; diff --git a/renderdoc/driver/d3d11/d3d11_analyse.cpp b/renderdoc/driver/d3d11/d3d11_analyse.cpp index a2916e7ab..68591729d 100644 --- a/renderdoc/driver/d3d11/d3d11_analyse.cpp +++ b/renderdoc/driver/d3d11/d3d11_analyse.cpp @@ -1424,7 +1424,7 @@ ShaderDebugTrace D3D11DebugManager::DebugThread(uint32_t frameID, uint32_t event return ret; } -void D3D11DebugManager::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, float pixel[4]) +void D3D11DebugManager::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]) { m_pImmediateContext->OMSetRenderTargets(1, &m_DebugRender.PickPixelRT, NULL); @@ -1454,6 +1454,7 @@ void D3D11DebugManager::PickPixel(ResourceId texture, uint32_t x, uint32_t y, ui texDisplay.linearDisplayAsGamma = true; texDisplay.FlipY = false; texDisplay.mip = mip; + texDisplay.sampleIdx = sample; texDisplay.CustomShader = ResourceId(); texDisplay.sliceFace = sliceFace; texDisplay.rangemin = 0.0f; @@ -2111,6 +2112,7 @@ ResourceId D3D11DebugManager::ApplyCustomShader(ResourceId shader, ResourceId te disp.HDRMul = -1.0f; disp.linearDisplayAsGamma = true; disp.mip = mip; + disp.sampleIdx = 0; disp.overlay = eTexOverlay_None; disp.rangemin = 0.0f; disp.rangemax = 1.0f; diff --git a/renderdoc/driver/d3d11/d3d11_debug.cpp b/renderdoc/driver/d3d11/d3d11_debug.cpp index 01ef85fd7..08e4e81a6 100644 --- a/renderdoc/driver/d3d11/d3d11_debug.cpp +++ b/renderdoc/driver/d3d11/d3d11_debug.cpp @@ -835,6 +835,7 @@ bool D3D11DebugManager::InitDebugRendering() RDCCOMPILE_ASSERT(eTexType_Stencil == RESTYPE_DEPTH_STENCIL, "Tex type enum doesn't match shader defines"); RDCCOMPILE_ASSERT(eTexType_DepthMS == RESTYPE_DEPTH_MS, "Tex type enum doesn't match shader defines"); RDCCOMPILE_ASSERT(eTexType_StencilMS == RESTYPE_DEPTH_STENCIL_MS, "Tex type enum doesn't match shader defines"); + RDCCOMPILE_ASSERT(eTexType_2DMS == RESTYPE_TEX2D_MS, "Tex type enum doesn't match shader defines"); D3D11_BLEND_DESC blendDesc; RDCEraseEl(blendDesc); @@ -1920,7 +1921,7 @@ uint32_t D3D11DebugManager::GetStructCount(ID3D11UnorderedAccessView *uav) return ret; } -bool D3D11DebugManager::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, float minval, float maxval, bool channels[4], vector &histogram) +bool D3D11DebugManager::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], vector &histogram) { if(minval >= maxval) return false; @@ -1937,6 +1938,8 @@ bool D3D11DebugManager::GetHistogram(ResourceId texid, uint32_t sliceFace, uint3 cdata.HistogramTextureResolution.z = (float)RDCMAX(details.texDepth>>mip, 1U); cdata.HistogramSlice = (float)sliceFace; cdata.HistogramMip = mip; + cdata.HistogramSample = (int)RDCCLAMP(sample, 0U, details.sampleCount-1); + if(sample == ~0U) cdata.HistogramSample = -int(details.sampleCount); cdata.HistogramMin = minval; cdata.HistogramMax = maxval; cdata.HistogramChannels = 0; @@ -2014,7 +2017,7 @@ bool D3D11DebugManager::GetHistogram(ResourceId texid, uint32_t sliceFace, uint3 return true; } -bool D3D11DebugManager::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, float *minval, float *maxval) +bool D3D11DebugManager::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval) { TextureShaderDetails details = GetShaderDetails(texid, true); @@ -2029,6 +2032,8 @@ bool D3D11DebugManager::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t cdata.HistogramTextureResolution.z = (float)RDCMAX(details.texDepth>>mip, 1U); cdata.HistogramSlice = (float)sliceFace; cdata.HistogramMip = mip; + cdata.HistogramSample = (int)RDCCLAMP(sample, 0U, details.sampleCount-1); + if(sample == ~0U) cdata.HistogramSample = -int(details.sampleCount); cdata.HistogramMin = 0.0f; cdata.HistogramMax = 1.0f; cdata.HistogramChannels = 0xf; @@ -2902,8 +2907,13 @@ D3D11DebugManager::TextureShaderDetails D3D11DebugManager::GetShaderDetails(Reso details.texDepth = 1; details.texArraySize = desc2d.ArraySize; details.texMips = desc2d.MipLevels; - details.sampleCount = desc2d.SampleDesc.Count; + details.sampleCount = RDCMAX(1U, desc2d.SampleDesc.Count); details.sampleQuality = desc2d.SampleDesc.Quality; + + if(desc2d.SampleDesc.Count > 1 || desc2d.SampleDesc.Quality > 0) + { + details.texType = eTexType_2DMS; + } if(mode == TEXDISPLAY_DEPTH_TARGET || IsDepthFormat(details.texFmt)) { @@ -2952,9 +2962,6 @@ D3D11DebugManager::TextureShaderDetails D3D11DebugManager::GetShaderDetails(Reso else { desc.Format = srvFormat; - - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; } if(!cache.created) @@ -2972,23 +2979,10 @@ D3D11DebugManager::TextureShaderDetails D3D11DebugManager::GetShaderDetails(Reso details.previewCopy = cache.srvResource; - if(desc2d.SampleDesc.Count > 1 || desc2d.SampleDesc.Quality > 0) - { - if(mode == TEXDISPLAY_DEPTH_TARGET) - { + if((desc2d.SampleDesc.Count > 1 || desc2d.SampleDesc.Quality > 0) && mode == TEXDISPLAY_DEPTH_TARGET) msaaDepth = true; - m_pImmediateContext->CopyResource(details.previewCopy, details.srvResource); - } - else - { - for(UINT sub=0; sub < desc.MipLevels*desc.ArraySize; sub++) - m_pImmediateContext->ResolveSubresource(details.previewCopy, sub, details.srvResource, sub, srvFormat); - } - } - else - { - m_pImmediateContext->CopyResource(details.previewCopy, details.srvResource); - } + + m_pImmediateContext->CopyResource(details.previewCopy, details.srvResource); details.srvResource = details.previewCopy; } @@ -3066,6 +3060,10 @@ D3D11DebugManager::TextureShaderDetails D3D11DebugManager::GetShaderDetails(Reso srvDesc[eTexType_2D].Texture2DArray.FirstArraySlice = 0; srvDesc[eTexType_2D].Texture2DArray.MipLevels = details.texMips; srvDesc[eTexType_2D].Texture2DArray.MostDetailedMip = 0; + + srvDesc[eTexType_2DMS].ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; + srvDesc[eTexType_2DMS].Texture2DMSArray.ArraySize = details.texArraySize; + srvDesc[eTexType_2DMS].Texture2DMSArray.FirstArraySlice = 0; srvDesc[eTexType_Stencil] = srvDesc[eTexType_Depth] = srvDesc[eTexType_2D]; @@ -3128,9 +3126,8 @@ D3D11DebugManager::TextureShaderDetails D3D11DebugManager::GetShaderDetails(Reso if(msaaDepth) { - srvDesc[eTexType_Stencil].ViewDimension = - srvDesc[eTexType_Depth].ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; - + srvDesc[eTexType_Stencil].ViewDimension = srvDesc[eTexType_Depth].ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; + srvDesc[eTexType_Depth].Texture2DMSArray.ArraySize = srvDesc[eTexType_2D].Texture2DArray.ArraySize; srvDesc[eTexType_Stencil].Texture2DMSArray.ArraySize = srvDesc[eTexType_2D].Texture2DArray.ArraySize; srvDesc[eTexType_Depth].Texture2DMSArray.FirstArraySlice = srvDesc[eTexType_2D].Texture2DArray.FirstArraySlice; @@ -3340,6 +3337,14 @@ bool D3D11DebugManager::RenderTexture(TextureDisplay cfg) pixelData.FlipY = cfg.FlipY ? 1 : 0; TextureShaderDetails details = GetShaderDetails(cfg.texid, cfg.rawoutput ? true : false); + + static int sampIdx = 0; + + pixelData.SampleIdx = (int)RDCCLAMP(cfg.sampleIdx, 0U, details.sampleCount-1); + + // hacky resolve + if(cfg.sampleIdx == ~0U) + pixelData.SampleIdx = -int(details.sampleCount); if(details.texFmt == DXGI_FORMAT_UNKNOWN) return false; @@ -3513,6 +3518,10 @@ bool D3D11DebugManager::RenderTexture(TextureDisplay cfg) { pixelData.OutputDisplayFormat = RESTYPE_DEPTH_STENCIL_MS; } + else if(details.texType == eTexType_2DMS) + { + pixelData.OutputDisplayFormat = RESTYPE_TEX2D_MS; + } if(cfg.overlay == eTexOverlay_NaN) { diff --git a/renderdoc/driver/d3d11/d3d11_debug.h b/renderdoc/driver/d3d11/d3d11_debug.h index 529ddc481..555d8ef16 100644 --- a/renderdoc/driver/d3d11/d3d11_debug.h +++ b/renderdoc/driver/d3d11/d3d11_debug.h @@ -119,8 +119,8 @@ class D3D11DebugManager void FillCBufferVariables(const vector &invars, vector &outvars, bool flattenVec4s, const vector &data); - bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, float *minval, float *maxval); - bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, float minval, float maxval, bool channels[4], vector &histogram); + bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, 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); void CopyArrayToTex2DMS(ID3D11Texture2D *destMS, ID3D11Texture2D *srcArray); void CopyTex2DMSToArray(ID3D11Texture2D *destArray, ID3D11Texture2D *srcMS); @@ -156,7 +156,7 @@ class D3D11DebugManager ShaderDebugTrace DebugVertex(uint32_t frameID, uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset); ShaderDebugTrace DebugPixel(uint32_t frameID, uint32_t eventID, uint32_t x, uint32_t y); ShaderDebugTrace DebugThread(uint32_t frameID, 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, float pixel[4]); + void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]); ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector &passEvents); ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip); @@ -173,6 +173,7 @@ class D3D11DebugManager eTexType_DepthMS, eTexType_StencilMS, eTexType_Cube, + eTexType_2DMS, eTexType_Max }; diff --git a/renderdoc/driver/d3d11/d3d11_replay.cpp b/renderdoc/driver/d3d11/d3d11_replay.cpp index a3353463c..94f6a6281 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.cpp +++ b/renderdoc/driver/d3d11/d3d11_replay.cpp @@ -1200,14 +1200,14 @@ ResourceId D3D11Replay::GetLiveID(ResourceId id) return m_pDevice->GetResourceManager()->GetLiveID(id); } -bool D3D11Replay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, float *minval, float *maxval) +bool D3D11Replay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval) { - return m_pDevice->GetDebugManager()->GetMinMax(texid, sliceFace, mip, minval, maxval); + return m_pDevice->GetDebugManager()->GetMinMax(texid, sliceFace, mip, sample, minval, maxval); } -bool D3D11Replay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, float minval, float maxval, bool channels[4], vector &histogram) +bool D3D11Replay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], vector &histogram) { - return m_pDevice->GetDebugManager()->GetHistogram(texid, sliceFace, mip, minval, maxval, channels, histogram); + return m_pDevice->GetDebugManager()->GetHistogram(texid, sliceFace, mip, sample, minval, maxval, channels, histogram); } PostVSMeshData D3D11Replay::GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage) @@ -1311,9 +1311,9 @@ ShaderDebugTrace D3D11Replay::DebugThread(uint32_t frameID, uint32_t eventID, ui return m_pDevice->GetDebugManager()->DebugThread(frameID, eventID, groupid, threadid); } -void D3D11Replay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, float pixel[4]) +void D3D11Replay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]) { - m_pDevice->GetDebugManager()->PickPixel(texture, x, y, sliceFace, mip, pixel); + m_pDevice->GetDebugManager()->PickPixel(texture, x, y, sliceFace, mip, sample, pixel); } ResourceId D3D11Replay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector &passEvents) diff --git a/renderdoc/driver/d3d11/d3d11_replay.h b/renderdoc/driver/d3d11/d3d11_replay.h index 458e6664d..563b51441 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.h +++ b/renderdoc/driver/d3d11/d3d11_replay.h @@ -82,8 +82,8 @@ class D3D11Replay : public IReplayDriver ResourceId GetLiveID(ResourceId id); - bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, float *minval, float *maxval); - bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, float minval, float maxval, bool channels[4], vector &histogram); + bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, 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); PostVSMeshData GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage); @@ -115,7 +115,7 @@ class D3D11Replay : public IReplayDriver ShaderDebugTrace DebugVertex(uint32_t frameID, uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset); ShaderDebugTrace DebugPixel(uint32_t frameID, uint32_t eventID, uint32_t x, uint32_t y); ShaderDebugTrace DebugThread(uint32_t frameID, 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, float pixel[4]); + void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]); ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector &passEvents); diff --git a/renderdoc/driver/gl/gl_debug.cpp b/renderdoc/driver/gl/gl_debug.cpp index bd353c6fc..9dc1c5c2a 100644 --- a/renderdoc/driver/gl/gl_debug.cpp +++ b/renderdoc/driver/gl/gl_debug.cpp @@ -178,7 +178,7 @@ void GLReplay::InitDebugData() gl.glBindVertexArray(DebugData.meshVAO); } -void GLReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, float pixel[4]) +void GLReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]) { WrappedOpenGL &gl = *m_pDriver; @@ -201,6 +201,7 @@ void GLReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sl texDisplay.HDRMul = -1.0f; texDisplay.linearDisplayAsGamma = true; texDisplay.mip = mip; + texDisplay.sampleIdx = sample; texDisplay.CustomShader = ResourceId(); texDisplay.sliceFace = sliceFace; texDisplay.rangemin = 0.0f; diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 7fd557b54..65c18d0a7 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -1334,13 +1334,13 @@ void GLReplay::FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, vector #pragma endregion -bool GLReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, float *minval, float *maxval) +bool GLReplay::GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float *minval, float *maxval) { RDCUNIMPLEMENTED("GetMinMax"); return false; } -bool GLReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, float minval, float maxval, bool channels[4], vector &histogram) +bool GLReplay::GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], vector &histogram) { RDCUNIMPLEMENTED("GetHistogram"); return false; diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index f24314882..d01dc5aac 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -82,8 +82,8 @@ class GLReplay : public IReplayDriver ResourceId GetLiveID(ResourceId id); - bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, float *minval, float *maxval); - bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, float minval, float maxval, bool channels[4], vector &histogram); + bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, 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); PostVSMeshData GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage); @@ -115,7 +115,7 @@ class GLReplay : public IReplayDriver ShaderDebugTrace DebugVertex(uint32_t frameID, uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset); ShaderDebugTrace DebugPixel(uint32_t frameID, uint32_t eventID, uint32_t x, uint32_t y); ShaderDebugTrace DebugThread(uint32_t frameID, 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, float pixel[4]); + void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, float pixel[4]); ResourceId RenderOverlay(ResourceId cfg, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector &passEvents); ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip); diff --git a/renderdoc/replay/control_types.h b/renderdoc/replay/control_types.h index 8fb011129..a71b94c01 100644 --- a/renderdoc/replay/control_types.h +++ b/renderdoc/replay/control_types.h @@ -65,6 +65,7 @@ struct TextureDisplay ResourceId CustomShader; uint32_t mip; uint32_t sliceFace; + uint32_t sampleIdx; bool32 rawoutput; float offx, offy; diff --git a/renderdoc/replay/renderdoc.h b/renderdoc/replay/renderdoc.h index 7f9054f0c..bdc4be7f1 100644 --- a/renderdoc/replay/renderdoc.h +++ b/renderdoc/replay/renderdoc.h @@ -86,7 +86,7 @@ extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayOutput_SetPixelContextLocation( extern "C" RENDERDOC_API void RENDERDOC_CC ReplayOutput_DisablePixelContext(ReplayOutput *output); extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayOutput_PickPixel(ReplayOutput *output, ResourceId texID, bool customShader, - uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, PixelValue *val); + uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *val); #ifdef RENDERDOC_EXPORTS struct ReplayRenderer; @@ -136,8 +136,8 @@ extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_SaveTexture(ReplayRend extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_GetPostVSData(ReplayRenderer *rend, MeshDataStage stage, PostVSMeshData *data); -extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_GetMinMax(ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, PixelValue *minval, PixelValue *maxval); -extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_GetHistogram(ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, float minval, float maxval, bool channels[4], rdctype::array *histogram); +extern "C" RENDERDOC_API bool 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 bool RENDERDOC_CC ReplayRenderer_GetHistogram(ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], rdctype::array *histogram); extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_GetBufferData(ReplayRenderer *rend, ResourceId buff, uint32_t offset, uint32_t len, rdctype::array *data); diff --git a/renderdoc/replay/replay_driver.h b/renderdoc/replay/replay_driver.h index fad54cd6d..a0d328322 100644 --- a/renderdoc/replay/replay_driver.h +++ b/renderdoc/replay/replay_driver.h @@ -122,8 +122,8 @@ class IReplayDriver : public IRemoteDriver virtual bool IsOutputWindowVisible(uint64_t id) = 0; virtual void FlipOutputWindow(uint64_t id) = 0; - virtual bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, float *minval, float *maxval) = 0; - virtual bool GetHistogram(ResourceId texid, uint32_t sliceFace, uint32_t mip, float minval, float maxval, bool channels[4], vector &histogram) = 0; + virtual bool GetMinMax(ResourceId texid, uint32_t sliceFace, uint32_t mip, uint32_t sample, 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; virtual ResourceId CreateProxyTexture(FetchTexture templateTex) = 0; virtual void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, size_t dataSize) = 0; @@ -141,5 +141,5 @@ class IReplayDriver : public IRemoteDriver 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, float pixel[4]) = 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; }; diff --git a/renderdoc/replay/replay_output.cpp b/renderdoc/replay/replay_output.cpp index 4a9659d83..5274d27f6 100644 --- a/renderdoc/replay/replay_output.cpp +++ b/renderdoc/replay/replay_output.cpp @@ -260,7 +260,7 @@ bool ReplayOutput::AddThumbnail(void *wnd, ResourceId texID) return true; } -bool ReplayOutput::PickPixel(ResourceId tex, bool customShader, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, PixelValue *ret) +bool ReplayOutput::PickPixel(ResourceId tex, bool customShader, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *ret) { if(ret == NULL || tex == ResourceId()) return false; @@ -280,7 +280,7 @@ bool ReplayOutput::PickPixel(ResourceId tex, bool customShader, uint32_t x, uint tex = m_OverlayResourceId; } - m_pDevice->PickPixel(m_pDevice->GetLiveID(tex), x, y, sliceFace, mip, ret->value_f); + m_pDevice->PickPixel(m_pDevice->GetLiveID(tex), x, y, sliceFace, mip, sample, ret->value_f); if(decodeRamp) { @@ -412,6 +412,7 @@ bool ReplayOutput::Display() disp.linearDisplayAsGamma = true; disp.FlipY = false; disp.mip = 0; + disp.sampleIdx = ~0U; disp.CustomShader = ResourceId(); disp.texid = m_pDevice->GetLiveID(m_Thumbnails[i].texture); disp.scale = -1.0f; @@ -590,5 +591,5 @@ extern "C" RENDERDOC_API void RENDERDOC_CC ReplayOutput_DisablePixelContext(Repl { output->DisablePixelContext(); } extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayOutput_PickPixel(ReplayOutput *output, ResourceId texID, bool customShader, - uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, PixelValue *val) -{ return output->PickPixel(texID, customShader, x, y, sliceFace, mip, val); } + uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *val) +{ return output->PickPixel(texID, customShader, x, y, sliceFace, mip, sample, val); } diff --git a/renderdoc/replay/replay_renderer.cpp b/renderdoc/replay/replay_renderer.cpp index 4e51f68d2..5013f9008 100644 --- a/renderdoc/replay/replay_renderer.cpp +++ b/renderdoc/replay/replay_renderer.cpp @@ -263,7 +263,7 @@ bool ReplayRenderer::GetPostVSData(MeshDataStage stage, PostVSMeshData *data) return true; } -bool ReplayRenderer::GetMinMax(ResourceId tex, uint32_t sliceFace, uint32_t mip, PixelValue *minval, PixelValue *maxval) +bool ReplayRenderer::GetMinMax(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *minval, PixelValue *maxval) { PixelValue *a = minval; PixelValue *b = maxval; @@ -273,16 +273,16 @@ bool ReplayRenderer::GetMinMax(ResourceId tex, uint32_t sliceFace, uint32_t mip, if(a == NULL) a = &dummy; if(b == NULL) b = &dummy; - return m_pDevice->GetMinMax(m_pDevice->GetLiveID(tex), sliceFace, mip, &a->value_f[0], &b->value_f[0]); + return m_pDevice->GetMinMax(m_pDevice->GetLiveID(tex), sliceFace, mip, sample, &a->value_f[0], &b->value_f[0]); } -bool ReplayRenderer::GetHistogram(ResourceId tex, uint32_t sliceFace, uint32_t mip, float minval, float maxval, bool channels[4], rdctype::array *histogram) +bool ReplayRenderer::GetHistogram(ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, 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, minval, maxval, channels, hist); + bool ret = m_pDevice->GetHistogram(m_pDevice->GetLiveID(tex), sliceFace, mip, sample, minval, maxval, channels, hist); if(ret) *histogram = hist; @@ -770,10 +770,10 @@ extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_SaveTexture(ReplayRend extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_GetPostVSData(ReplayRenderer *rend, MeshDataStage stage, PostVSMeshData *data) { return rend->GetPostVSData(stage, data); } -extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_GetMinMax(ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, PixelValue *minval, PixelValue *maxval) -{ return rend->GetMinMax(tex, sliceFace, mip, minval, maxval); } -extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_GetHistogram(ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, float minval, float maxval, bool channels[4], rdctype::array *histogram) -{ return rend->GetHistogram(tex, sliceFace, mip, minval, maxval, channels, histogram); } +extern "C" RENDERDOC_API bool 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 bool RENDERDOC_CC ReplayRenderer_GetHistogram(ReplayRenderer *rend, ResourceId tex, uint32_t sliceFace, uint32_t mip, uint32_t sample, float minval, float maxval, bool channels[4], rdctype::array *histogram) +{ return rend->GetHistogram(tex, sliceFace, mip, sample, minval, maxval, channels, histogram); } extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_GetBufferData(ReplayRenderer *rend, ResourceId buff, uint32_t offset, uint32_t len, rdctype::array *data) { return rend->GetBufferData(buff, offset, len, data); } diff --git a/renderdoc/replay/replay_renderer.h b/renderdoc/replay/replay_renderer.h index 62629fc80..e8043d7d0 100644 --- a/renderdoc/replay/replay_renderer.h +++ b/renderdoc/replay/replay_renderer.h @@ -56,7 +56,7 @@ public: void DisablePixelContext(); bool PickPixel(ResourceId texID, bool customShader, - uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, + uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, uint32_t sample, PixelValue *val); private: ReplayOutput(ReplayRenderer *parent, void *w); @@ -167,8 +167,8 @@ struct ReplayRenderer bool GetPostVSData(MeshDataStage stage, PostVSMeshData *data); - bool GetMinMax(ResourceId tex, uint32_t sliceFace, uint32_t mip, PixelValue *minval, PixelValue *maxval); - bool GetHistogram(ResourceId tex, uint32_t sliceFace, uint32_t mip, float minval, float maxval, bool channels[4], rdctype::array *histogram); + 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); bool GetUsage(ResourceId id, rdctype::array *usage); diff --git a/renderdoccmd/renderdoccmd_win32.cpp b/renderdoccmd/renderdoccmd_win32.cpp index 031e633a1..83a7f3e7f 100644 --- a/renderdoccmd/renderdoccmd_win32.cpp +++ b/renderdoccmd/renderdoccmd_win32.cpp @@ -239,6 +239,7 @@ void DisplayRendererPreview(ReplayRenderer *renderer) TextureDisplay d; d.texid = texs[i].ID; d.mip = 0; + d.sampleIdx = ~0U; d.overlay = eTexOverlay_None; d.CustomShader = ResourceId(); d.HDRMul = -1.0f; diff --git a/renderdocui/Interop/FetchInfo.cs b/renderdocui/Interop/FetchInfo.cs index 2c21f6917..f9758d3e2 100644 --- a/renderdocui/Interop/FetchInfo.cs +++ b/renderdocui/Interop/FetchInfo.cs @@ -419,6 +419,7 @@ namespace renderdoc public ResourceId CustomShader = ResourceId.Null; public UInt32 mip = 0; public UInt32 sliceFace = 0; + public UInt32 sampleIdx = 0; public bool rawoutput = false; public float offx = 0.0f, offy = 0.0f; diff --git a/renderdocui/Interop/ReplayRenderer.cs b/renderdocui/Interop/ReplayRenderer.cs index 3b4cf8666..ef75e2c70 100644 --- a/renderdocui/Interop/ReplayRenderer.cs +++ b/renderdocui/Interop/ReplayRenderer.cs @@ -92,7 +92,7 @@ namespace renderdoc [DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)] private static extern bool ReplayOutput_PickPixel(IntPtr real, ResourceId texID, bool customShader, - UInt32 x, UInt32 y, UInt32 sliceFace, UInt32 mip, IntPtr outval); + UInt32 x, UInt32 y, UInt32 sliceFace, UInt32 mip, UInt32 sample, IntPtr outval); private IntPtr m_Real = IntPtr.Zero; @@ -138,11 +138,11 @@ namespace renderdoc ReplayOutput_DisablePixelContext(m_Real); } - public PixelValue PickPixel(ResourceId texID, bool customShader, UInt32 x, UInt32 y, UInt32 sliceFace, UInt32 mip) + public PixelValue PickPixel(ResourceId texID, bool customShader, UInt32 x, UInt32 y, UInt32 sliceFace, UInt32 mip, UInt32 sample) { IntPtr mem = CustomMarshal.Alloc(typeof(PixelValue)); - bool success = ReplayOutput_PickPixel(m_Real, texID, customShader, x, y, sliceFace, mip, mem); + bool success = ReplayOutput_PickPixel(m_Real, texID, customShader, x, y, sliceFace, mip, sample, mem); PixelValue ret = null; @@ -232,9 +232,9 @@ namespace renderdoc private static extern bool ReplayRenderer_GetPostVSData(IntPtr real, 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, IntPtr outminval, IntPtr outmaxval); + private static extern bool ReplayRenderer_GetMinMax(IntPtr real, ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, 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, float minval, float maxval, bool[] channels, IntPtr outhistogram); + private static extern bool ReplayRenderer_GetHistogram(IntPtr real, ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, 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, UInt32 offset, UInt32 len, IntPtr outdata); @@ -605,12 +605,12 @@ namespace renderdoc return ret; } - public bool GetMinMax(ResourceId tex, UInt32 sliceFace, UInt32 mip, out PixelValue minval, out PixelValue maxval) + public bool GetMinMax(ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, 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, mem1, mem2); + bool success = ReplayRenderer_GetMinMax(m_Real, tex, sliceFace, mip, sample, mem1, mem2); if (success) { @@ -629,7 +629,7 @@ namespace renderdoc return success; } - public bool GetHistogram(ResourceId tex, UInt32 sliceFace, UInt32 mip, float minval, float maxval, + public bool GetHistogram(ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, float minval, float maxval, bool Red, bool Green, bool Blue, bool Alpha, out UInt32[] histogram) { @@ -637,7 +637,7 @@ namespace renderdoc bool[] channels = new bool[] { Red, Green, Blue, Alpha }; - bool success = ReplayRenderer_GetHistogram(m_Real, tex, sliceFace, mip, minval, maxval, channels, mem); + bool success = ReplayRenderer_GetHistogram(m_Real, tex, sliceFace, mip, sample, minval, maxval, channels, mem); histogram = null; diff --git a/renderdocui/Windows/TextureViewer.cs b/renderdocui/Windows/TextureViewer.cs index bd616d9c4..d7cbbeb8a 100644 --- a/renderdocui/Windows/TextureViewer.cs +++ b/renderdocui/Windows/TextureViewer.cs @@ -1089,14 +1089,34 @@ namespace renderdocui.Windows mipLevel.Items.Clear(); sliceFace.Items.Clear(); - for (int i = 0; i < tex.mips; i++) - mipLevel.Items.Add(i + " - " + Math.Max(1, tex.width >> i) + "x" + Math.Max(1, tex.height >> i)); + if (tex.msSamp > 1) + { + for (int i = 0; i < tex.msSamp; i++) + mipLevel.Items.Add(String.Format("Sample {0}", i)); + + // add an option to display unweighted average resolved value, + // to get an idea of how the samples average + if(tex.format.compType != FormatComponentType.UInt && + tex.format.compType != FormatComponentType.SInt && + tex.format.compType != FormatComponentType.Depth && + (tex.creationFlags & TextureCreationFlags.DSV) == 0) + mipLevel.Items.Add("Average val"); + + mipLevelLabel.Text = "Sample"; + } + else + { + for (int i = 0; i < tex.mips; i++) + mipLevel.Items.Add(i + " - " + Math.Max(1, tex.width >> i) + "x" + Math.Max(1, tex.height >> i)); + + mipLevelLabel.Text = "Mip"; + } mipLevel.SelectedIndex = 0; m_TexDisplay.mip = 0; m_TexDisplay.sliceFace = 0; - if (tex.mips == 1) + if (tex.mips == 1 && tex.msSamp <= 1) { mipLevel.Enabled = false; } @@ -1924,11 +1944,11 @@ namespace renderdocui.Windows y = (int)tex.height - y; var pickValue = m_Output.PickPixel(m_TexDisplay.texid, true, (UInt32)x, (UInt32)y, - m_TexDisplay.sliceFace, m_TexDisplay.mip); + m_TexDisplay.sliceFace, m_TexDisplay.mip, m_TexDisplay.sampleIdx); PixelValue realValue = null; if (m_TexDisplay.CustomShader != ResourceId.Null) realValue = m_Output.PickPixel(m_TexDisplay.texid, false, (UInt32)x, (UInt32)y, - m_TexDisplay.sliceFace, m_TexDisplay.mip); + m_TexDisplay.sliceFace, m_TexDisplay.mip, m_TexDisplay.sampleIdx); RT_UpdatePixelColour(pickValue, realValue, false); } @@ -2060,7 +2080,7 @@ namespace renderdocui.Windows if (m_TexDisplay.FlipY) y = tex.height - y; RT_UpdateHoverColour(m_Output.PickPixel(m_TexDisplay.texid, true, (UInt32)m_CurHoverPixel.X, y, - m_TexDisplay.sliceFace, m_TexDisplay.mip)); + m_TexDisplay.sliceFace, m_TexDisplay.mip, m_TexDisplay.sampleIdx)); } }); } @@ -2265,10 +2285,33 @@ namespace renderdocui.Windows } private void mipLevel_SelectedIndexChanged(object sender, EventArgs e) { - m_TexDisplay.mip = (UInt32)mipLevel.SelectedIndex; + if (CurrentTexture == null) return; + + if (CurrentTexture.mips > 1) + { + m_TexDisplay.mip = (UInt32)mipLevel.SelectedIndex; + m_TexDisplay.sampleIdx = 0; + } + else + { + m_TexDisplay.mip = 0; + m_TexDisplay.sampleIdx = (UInt32)mipLevel.SelectedIndex; + if (mipLevel.SelectedIndex == CurrentTexture.msSamp) + m_TexDisplay.sampleIdx = ~0U; + } + + m_Core.Renderer.BeginInvoke(RT_UpdateVisualRange); + + if (m_Output != null && m_PickedPoint != null && m_PickedPoint.X > 0 && m_PickedPoint.Y > 0) + { + m_Core.Renderer.BeginInvoke((ReplayRenderer r) => + { + if (m_Output != null) + RT_PickPixelsAndUpdate(m_PickedPoint.X, m_PickedPoint.Y, true); + }); + } m_Core.Renderer.BeginInvoke(RT_UpdateAndDisplay); - m_Core.Renderer.BeginInvoke(RT_UpdateVisualRange); } private void overlay_SelectedIndexChanged(object sender, EventArgs e) @@ -2285,8 +2328,18 @@ namespace renderdocui.Windows { m_TexDisplay.sliceFace = (UInt32)sliceFace.SelectedIndex; - m_Core.Renderer.BeginInvoke(RT_UpdateAndDisplay); m_Core.Renderer.BeginInvoke(RT_UpdateVisualRange); + + if (m_Output != null && m_PickedPoint != null && m_PickedPoint.X > 0 && m_PickedPoint.Y > 0) + { + m_Core.Renderer.BeginInvoke((ReplayRenderer r) => + { + if (m_Output != null) + RT_PickPixelsAndUpdate(m_PickedPoint.X, m_PickedPoint.Y, true); + }); + } + + m_Core.Renderer.BeginInvoke(RT_UpdateAndDisplay); } private void updateChannelsHandler(object sender, EventArgs e) @@ -2392,7 +2445,7 @@ 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, out min, out max); + bool success = r.GetMinMax(m_TexDisplay.texid, m_TexDisplay.sliceFace, m_TexDisplay.mip, m_TexDisplay.sampleIdx, out min, out max); if (success) { @@ -2483,7 +2536,7 @@ namespace renderdocui.Windows bool success = true; uint[] histogram; - success = r.GetHistogram(m_TexDisplay.texid, m_TexDisplay.sliceFace, m_TexDisplay.mip, + success = r.GetHistogram(m_TexDisplay.texid, m_TexDisplay.sliceFace, m_TexDisplay.mip, m_TexDisplay.sampleIdx, rangeHistogram.BlackPoint, rangeHistogram.WhitePoint, m_TexDisplay.Red, m_TexDisplay.Green && fmt.compCount > 1,