From 75a9bd4376ec4591ddf327f6fbae1d9639c4e220 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 4 Jun 2015 21:04:08 +0200 Subject: [PATCH] Expand out arrays of shader resources at lower priority than non-arrays * An array of resources like SamplerState foo[8]; or Texture2D blah[8]; show up as one entry in the reflection data, so need to be expanded out to several entries. * Normally it's OK to overlap two resources in the same bind, as long as only one gets used - this doesn't matter to us since only the used one will show up in the reflection data. Unless there's an array e.g: SamplerState foo[8] : register(s0); // [0] and [5] used; SamplerState bar : register(s3); in which case foo[] appears in the reflection data for the sake of [0] and [5], and bar will appear too (causing an overlap between foo[3] and bar. Since we know the reflection data is unambiguous, we prioritise individual entries over array entries by listing them first and using the first match for any bindpoint. --- .../driver/d3d11/shaders/dxbc_inspect.cpp | 33 +++++++++++++++++++ .../PipelineState/D3D11PipelineStateViewer.cs | 15 +++++++++ 2 files changed, 48 insertions(+) diff --git a/renderdoc/driver/d3d11/shaders/dxbc_inspect.cpp b/renderdoc/driver/d3d11/shaders/dxbc_inspect.cpp index c01cee2ed..5d2282d27 100644 --- a/renderdoc/driver/d3d11/shaders/dxbc_inspect.cpp +++ b/renderdoc/driver/d3d11/shaders/dxbc_inspect.cpp @@ -570,6 +570,39 @@ DXBCFile::DXBCFile(const void *ByteCode, size_t ByteCodeLength) m_Resources.push_back(desc); } + // Expand out any array resources. We deliberately place these at the end of the resources + // array, so that any non-array resources can be picked up first before any arrays. + // + // The reason for this is that an array element could refer to an un-used alias in a bind + // point, and an individual non-array resoruce will always refer to the used alias (an + // un-used individual resource will be omitted entirely from the reflection + for(size_t i=0; i < m_Resources.size(); ) + { + if(m_Resources[i].bindCount > 1) + { + ShaderInputBind desc = m_Resources[i]; + m_Resources.erase(m_Resources.begin()+i); + + string rname = desc.name; + uint32_t arraySize = desc.bindCount; + + desc.bindCount = 1; + + for(uint32_t i=0; i < arraySize; i++) + { + desc.name = StringFormat::Fmt("%s[%u]", rname.c_str(), i); + m_Resources.push_back(desc); + desc.bindPoint++; + } + + // continue from the i'th element again since + // we just removed it. + continue; + } + + i++; + } + cbuffernames.clear(); if(h->cbuffers.count > 0) diff --git a/renderdocui/Windows/PipelineState/D3D11PipelineStateViewer.cs b/renderdocui/Windows/PipelineState/D3D11PipelineStateViewer.cs index b7f55c099..e9fc9b614 100644 --- a/renderdocui/Windows/PipelineState/D3D11PipelineStateViewer.cs +++ b/renderdocui/Windows/PipelineState/D3D11PipelineStateViewer.cs @@ -259,7 +259,10 @@ namespace renderdocui.Windows.PipelineState foreach (var bind in shaderDetails.Resources) { if (bind.IsSRV && bind.bindPoint == i) + { shaderInput = bind; + break; + } } } @@ -380,7 +383,10 @@ namespace renderdocui.Windows.PipelineState foreach (var bind in shaderDetails.Resources) { if (bind.IsSampler && bind.bindPoint == i) + { shaderInput = bind; + break; + } } } @@ -891,7 +897,10 @@ namespace renderdocui.Windows.PipelineState foreach (var bind in state.m_CS.ShaderDetails.Resources) { if (bind.IsReadWrite && bind.bindPoint == i) + { shaderInput = bind; + break; + } } } @@ -1205,7 +1214,10 @@ namespace renderdocui.Windows.PipelineState foreach (var bind in state.m_PS.ShaderDetails.Resources) { if (bind.IsReadWrite && bind.bindPoint == i + state.m_OM.UAVStartSlot) + { shaderInput = bind; + break; + } } } @@ -2424,7 +2436,10 @@ namespace renderdocui.Windows.PipelineState foreach (var bind in refl.Resources) { if (bind.IsReadWrite && bind.bindPoint == i) + { shaderInput = bind; + break; + } } }