From 28b63fe56c9f56b873c68781ff37e45af1b7506e Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 28 Oct 2022 11:41:43 +0100 Subject: [PATCH] Protect against invalid values in view desc for number of mips * This is mostly relevant for D3D12, where the desc comes from the user and so may not be normalised and contain values like 0xffffffff to indicate 'all mips' or 'all slices' in the view. --- renderdoc/driver/d3d11/d3d11_shaderdebug.cpp | 42 ++++++++++++++++++++ renderdoc/driver/d3d12/d3d12_shaderdebug.cpp | 34 ++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/renderdoc/driver/d3d11/d3d11_shaderdebug.cpp b/renderdoc/driver/d3d11/d3d11_shaderdebug.cpp index ec7592866..4a9eedc90 100644 --- a/renderdoc/driver/d3d11/d3d11_shaderdebug.cpp +++ b/renderdoc/driver/d3d11/d3d11_shaderdebug.cpp @@ -756,6 +756,14 @@ ShaderVariable D3D11DebugAPIWrapper::GetResourceInfo(DXBCBytecode::OperandType t result.value.u32v[3] = isarray ? srvDesc.Texture1DArray.MipLevels : srvDesc.Texture1D.MipLevels; + if(isarray && (result.value.u32v[2] == 0 || result.value.u32v[2] == ~0U)) + result.value.u32v[2] = desc.ArraySize; + + if(result.value.u32v[3] == 0 || result.value.u32v[3] == ~0U) + result.value.u32v[3] = desc.MipLevels; + if(result.value.u32v[3] == 0 || result.value.u32v[3] == ~0U) + result.value.u32v[3] = CalcNumMips(desc.Width, 1, 1); + if(mipLevel >= result.value.u32v[3]) result.value.u32v[0] = result.value.u32v[1] = 0; @@ -789,6 +797,9 @@ ShaderVariable D3D11DebugAPIWrapper::GetResourceInfo(DXBCBytecode::OperandType t { result.value.u32v[2] = srvDesc.Texture2DArray.ArraySize; result.value.u32v[3] = srvDesc.Texture2DArray.MipLevels; + + if(result.value.u32v[2] == 0 || result.value.u32v[2] == ~0U) + result.value.u32v[2] = desc.ArraySize; } else if(srvDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DMS) { @@ -799,8 +810,16 @@ ShaderVariable D3D11DebugAPIWrapper::GetResourceInfo(DXBCBytecode::OperandType t { result.value.u32v[2] = srvDesc.Texture2DMSArray.ArraySize; result.value.u32v[3] = 1; + + if(result.value.u32v[2] == 0 || result.value.u32v[2] == ~0U) + result.value.u32v[2] = desc.ArraySize; } + if(result.value.u32v[3] == 0 || result.value.u32v[3] == ~0U) + result.value.u32v[3] = desc.MipLevels; + if(result.value.u32v[3] == 0 || result.value.u32v[3] == ~0U) + result.value.u32v[3] = CalcNumMips(desc.Width, desc.Height, 1); + if(mipLevel >= result.value.u32v[3]) result.value.u32v[0] = result.value.u32v[1] = result.value.u32v[2] = 0; @@ -824,6 +843,11 @@ ShaderVariable D3D11DebugAPIWrapper::GetResourceInfo(DXBCBytecode::OperandType t result.value.u32v[2] = RDCMAX(1U, desc.Depth >> mipLevel); result.value.u32v[3] = srvDesc.Texture3D.MipLevels; + if(result.value.u32v[3] == 0 || result.value.u32v[3] == ~0U) + result.value.u32v[3] = desc.MipLevels; + if(result.value.u32v[3] == 0 || result.value.u32v[3] == ~0U) + result.value.u32v[3] = CalcNumMips(desc.Width, desc.Height, desc.Depth); + if(mipLevel >= result.value.u32v[3]) result.value.u32v[0] = result.value.u32v[1] = result.value.u32v[2] = 0; @@ -855,6 +879,14 @@ ShaderVariable D3D11DebugAPIWrapper::GetResourceInfo(DXBCBytecode::OperandType t result.value.u32v[3] = isarray ? srvDesc.TextureCubeArray.MipLevels : srvDesc.TextureCube.MipLevels; + if(isarray && (result.value.u32v[2] == 0 || result.value.u32v[2] == ~0U)) + result.value.u32v[2] = desc.ArraySize; + + if(result.value.u32v[3] == 0 || result.value.u32v[3] == ~0U) + result.value.u32v[3] = desc.MipLevels; + if(result.value.u32v[3] == 0 || result.value.u32v[3] == ~0U) + result.value.u32v[3] = CalcNumMips(desc.Width, desc.Height, 1); + if(mipLevel >= result.value.u32v[3]) result.value.u32v[0] = result.value.u32v[1] = result.value.u32v[2] = 0; @@ -916,6 +948,9 @@ ShaderVariable D3D11DebugAPIWrapper::GetResourceInfo(DXBCBytecode::OperandType t result.value.u32v[1] = isarray ? uavDesc.Texture1DArray.ArraySize : 0; result.value.u32v[2] = 0; + if(isarray && (result.value.u32v[2] == 0 || result.value.u32v[2] == ~0U)) + result.value.u32v[2] = desc.ArraySize; + // spec says "For UAVs (u#), the number of mip levels is always 1." result.value.u32v[3] = 1; @@ -942,10 +977,17 @@ ShaderVariable D3D11DebugAPIWrapper::GetResourceInfo(DXBCBytecode::OperandType t result.value.u32v[1] = RDCMAX(1U, desc.Height >> mipLevel); if(uavDesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2D) + { result.value.u32v[2] = 0; + } else if(uavDesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2DARRAY) + { result.value.u32v[2] = uavDesc.Texture2DArray.ArraySize; + if(result.value.u32v[2] == 0 || result.value.u32v[2] == ~0U) + result.value.u32v[2] = desc.ArraySize; + } + // spec says "For UAVs (u#), the number of mip levels is always 1." result.value.u32v[3] = 1; diff --git a/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp b/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp index 63e1b317a..7531a06fa 100644 --- a/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp +++ b/renderdoc/driver/d3d12/d3d12_shaderdebug.cpp @@ -962,6 +962,14 @@ ShaderVariable D3D12DebugAPIWrapper::GetResourceInfo(DXBCBytecode::OperandType t result.value.u32v[3] = isarray ? srvDesc.Texture1DArray.MipLevels : srvDesc.Texture1D.MipLevels; + if(isarray && (result.value.u32v[1] == 0 || result.value.u32v[1] == ~0U)) + result.value.u32v[1] = resDesc.DepthOrArraySize; + + if(result.value.u32v[3] == 0 || result.value.u32v[3] == ~0U) + result.value.u32v[3] = resDesc.MipLevels; + if(result.value.u32v[3] == 0 || result.value.u32v[3] == ~0U) + result.value.u32v[3] = CalcNumMips((int)resDesc.Width, resDesc.Height, 1); + if(mipLevel >= result.value.u32v[3]) result.value.u32v[0] = result.value.u32v[1] = 0; @@ -985,6 +993,9 @@ ShaderVariable D3D12DebugAPIWrapper::GetResourceInfo(DXBCBytecode::OperandType t { result.value.u32v[2] = srvDesc.Texture2DArray.ArraySize; result.value.u32v[3] = srvDesc.Texture2DArray.MipLevels; + + if(result.value.u32v[2] == 0 || result.value.u32v[2] == ~0U) + result.value.u32v[2] = resDesc.DepthOrArraySize; } else if(srvDesc.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE2DMS) { @@ -995,7 +1006,16 @@ ShaderVariable D3D12DebugAPIWrapper::GetResourceInfo(DXBCBytecode::OperandType t { result.value.u32v[2] = srvDesc.Texture2DMSArray.ArraySize; result.value.u32v[3] = 1; + + if(result.value.u32v[2] == 0 || result.value.u32v[2] == ~0U) + result.value.u32v[2] = resDesc.DepthOrArraySize; } + + if(result.value.u32v[3] == 0 || result.value.u32v[3] == ~0U) + result.value.u32v[3] = resDesc.MipLevels; + if(result.value.u32v[3] == 0 || result.value.u32v[3] == ~0U) + result.value.u32v[3] = CalcNumMips((int)resDesc.Width, resDesc.Height, 1); + if(mipLevel >= result.value.u32v[3]) result.value.u32v[0] = result.value.u32v[1] = result.value.u32v[2] = 0; @@ -1010,6 +1030,12 @@ ShaderVariable D3D12DebugAPIWrapper::GetResourceInfo(DXBCBytecode::OperandType t result.value.u32v[2] = RDCMAX(1U, (uint32_t)(resDesc.DepthOrArraySize >> mipLevel)); result.value.u32v[3] = srvDesc.Texture3D.MipLevels; + if(result.value.u32v[3] == 0 || result.value.u32v[3] == ~0U) + result.value.u32v[3] = resDesc.MipLevels; + if(result.value.u32v[3] == 0 || result.value.u32v[3] == ~0U) + result.value.u32v[3] = + CalcNumMips((int)resDesc.Width, resDesc.Height, resDesc.DepthOrArraySize); + if(mipLevel >= result.value.u32v[3]) result.value.u32v[0] = result.value.u32v[1] = result.value.u32v[2] = 0; @@ -1034,6 +1060,14 @@ ShaderVariable D3D12DebugAPIWrapper::GetResourceInfo(DXBCBytecode::OperandType t result.value.u32v[3] = isarray ? srvDesc.TextureCubeArray.MipLevels : srvDesc.TextureCube.MipLevels; + if(result.value.u32v[2] == 0 || result.value.u32v[2] == ~0U) + result.value.u32v[2] = resDesc.DepthOrArraySize / 6; + + if(result.value.u32v[3] == 0 || result.value.u32v[3] == ~0U) + result.value.u32v[3] = resDesc.MipLevels; + if(result.value.u32v[3] == 0 || result.value.u32v[3] == ~0U) + result.value.u32v[3] = CalcNumMips((int)resDesc.Width, resDesc.Height, 1); + if(mipLevel >= result.value.u32v[3]) result.value.u32v[0] = result.value.u32v[1] = result.value.u32v[2] = 0;