message: Improve iteration for large unused descriptor arrays in D3D12 pipeline
diff: @@ -1099,11 +1099,28 @@ void D3D12PipelineStateViewer::setShaderState(
  const bool srv = rootElements[i].type == BindType::ReadOnlyResource;
  RDTreeWidget *tree = srv ? resources : uavs;
  - const rdcarray<Bindpoint> &binds = srv ? stage.bindpointMapping.readOnlyResources
  + rdcarray<Bindpoint> binds = srv ? stage.bindpointMapping.readOnlyResources
  : stage.bindpointMapping.readWriteResources;
  - const rdcarray<ShaderResource> &res =
  + rdcarray<ShaderResource> res =
  srv ? stage.reflection->readOnlyResources : stage.reflection->readWriteResources;
  + // pre-filter binds/res by space
  + for(size_t bi = 0; bi < binds.size();)
  + {
  + if(binds[bi].bindset != tag.space)
  + {
  + binds.erase(bi);
  + res.erase(bi);
  + continue;
  + }
  +
  + bi++;
  + }
  +
  + // if there are no binds and we're not showing unused slots, skip now
  + if(binds.empty() && !showNode(false, true))
  + continue;
  +
  tag.type = srv ? D3D12ViewTag::SRV : D3D12ViewTag::UAV;
  const rdcarray<D3D12Pipe::View> &views = rootElements[i].views;
  @@ -1130,22 +1147,23 @@ void D3D12PipelineStateViewer::setShaderState(
  lastView = views.size() - 1;
  }
  + const Bindpoint *bind = NULL;
  + const ShaderResource *shaderInput = NULL;
  + bool usedSlot = false;
  + uint32_t arraySize = 1;
  +
  for(size_t j = firstView; j < views.size() && j <= lastView;)
  {
  int shaderReg = (int)views[j].bind;
  - // find the first matching bind for this element
  - const Bindpoint *bind = NULL;
  - const ShaderResource *shaderInput = NULL;
  -
  + // only look for a new bind if we don't have one that already matches
  + if(bind == NULL ||
  + (bind->arraySize != ~0U && bind->bind + (int)bind->arraySize < shaderReg))
  + {
  for(int k = 0; k < binds.count(); k++)
  {
  const Bindpoint &b = binds[k];
  - // ignore binds in other spaces
  - if(b.bindset != tag.space)
  - continue;
  -
  // if we find an exact reg match, it's a match
  bool regMatch = (b.bind == shaderReg);
  @@ -1163,9 +1181,8 @@ void D3D12PipelineStateViewer::setShaderState(
  }
  }
  - bool usedSlot = (bind && bind->used);
  -
  - uint32_t arraySize = bind ? qMax(1U, bind->arraySize) : 1;
  + usedSlot = (bind && bind->used) && rootElements[i].dynamicallyUsedCount > 0;
  + arraySize = bind ? qMax(1U, qMin((uint32_t)views.size(), bind->arraySize)) : 1;
  // if this bind isn't used, skip
  if(!showNode(usedSlot, true))
  @@ -1174,6 +1191,7 @@ void D3D12PipelineStateViewer::setShaderState(
  j += arraySize;
  continue;
  }
  + }
  if(arraySize > 1)
  {
  