diff --git a/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp index 762109a9a..318673375 100644 --- a/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp @@ -791,6 +791,7 @@ void D3D11PipelineStateViewer::clearShaderState(RDLabel *shader, RDTreeWidget *t void D3D11PipelineStateViewer::clearState() { m_VBNodes.clear(); + m_EmptyNodes.clear(); ui->iaLayouts->clear(); ui->iaBuffers->clear(); @@ -1324,6 +1325,9 @@ void D3D11PipelineStateViewer::setState() bool ibufferUsed = draw && (draw->flags & DrawFlags::Indexed); + m_VBNodes.clear(); + m_EmptyNodes.clear(); + vs = ui->iaBuffers->verticalScrollBar()->value(); ui->iaBuffers->beginUpdate(); ui->iaBuffers->clear(); @@ -1352,7 +1356,10 @@ void D3D11PipelineStateViewer::setState() setInactiveRow(node); if(state.inputAssembly.indexBuffer.resourceId == ResourceId()) + { setEmptyRow(node); + m_EmptyNodes.push_back(node); + } ui->iaBuffers->addTopLevelItem(node); } @@ -1370,6 +1377,7 @@ void D3D11PipelineStateViewer::setState() (draw ? draw->indexOffset * draw->indexByteWidth : 0)))); setEmptyRow(node); + m_EmptyNodes.push_back(node); if(!ibufferUsed) setInactiveRow(node); @@ -1378,8 +1386,6 @@ void D3D11PipelineStateViewer::setState() } } - m_VBNodes.clear(); - for(int i = 0; i < state.inputAssembly.vertexBuffers.count(); i++) { const D3D11Pipe::VertexBuffer &v = state.inputAssembly.vertexBuffers[i]; @@ -1406,7 +1412,10 @@ void D3D11PipelineStateViewer::setState() node->setTag(QVariant::fromValue(D3D11VBIBTag(v.resourceId, v.byteOffset))); if(!filledSlot) + { setEmptyRow(node); + m_EmptyNodes.push_back(node); + } if(!usedSlot) setInactiveRow(node); @@ -2184,8 +2193,11 @@ void D3D11PipelineStateViewer::highlightIABind(int slot) { RDTreeWidgetItem *item = m_VBNodes[(int)slot]; - item->setBackgroundColor(col); - item->setForegroundColor(contrastingColor(col, QColor(0, 0, 0))); + if(!m_EmptyNodes.contains(item)) + { + item->setBackgroundColor(col); + item->setForegroundColor(contrastingColor(col, QColor(0, 0, 0))); + } } for(int i = 0; i < ui->iaLayouts->topLevelItemCount(); i++) @@ -2248,8 +2260,11 @@ void D3D11PipelineStateViewer::on_iaBuffers_mouseMove(QMouseEvent *e) } else { - item->setBackground(ui->iaBuffers->palette().brush(QPalette::Window)); - item->setForeground(QBrush()); + if(!m_EmptyNodes.contains(item)) + { + item->setBackground(ui->iaBuffers->palette().brush(QPalette::Window)); + item->setForeground(QBrush()); + } } } } @@ -2276,6 +2291,9 @@ void D3D11PipelineStateViewer::vertex_leave(QEvent *e) { RDTreeWidgetItem *item = ui->iaBuffers->topLevelItem(i); + if(m_EmptyNodes.contains(item)) + continue; + item->setBackground(QBrush()); item->setForeground(QBrush()); } diff --git a/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.h b/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.h index f1e496610..3d1716901 100644 --- a/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.h +++ b/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.h @@ -117,4 +117,6 @@ private: // keep track of the VB nodes (we want to be able to highlight them easily on hover) QList m_VBNodes; + // list of empty VB nodes that shouldn't be highlighted on hover + QList m_EmptyNodes; }; diff --git a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp index 5912d6ed5..8abb3ca91 100644 --- a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp @@ -883,6 +883,7 @@ void D3D12PipelineStateViewer::clearShaderState(RDLabel *shader, RDLabel *rootSi void D3D12PipelineStateViewer::clearState() { m_VBNodes.clear(); + m_EmptyNodes.clear(); ui->iaLayouts->clear(); ui->iaBuffers->clear(); @@ -1341,6 +1342,9 @@ void D3D12PipelineStateViewer::setState() bool ibufferUsed = draw && (draw->flags & DrawFlags::Indexed); + m_VBNodes.clear(); + m_EmptyNodes.clear(); + vs = ui->iaBuffers->verticalScrollBar()->value(); ui->iaBuffers->beginUpdate(); ui->iaBuffers->clear(); @@ -1369,7 +1373,10 @@ void D3D12PipelineStateViewer::setState() setInactiveRow(node); if(state.inputAssembly.indexBuffer.resourceId == ResourceId()) + { setEmptyRow(node); + m_EmptyNodes.push_back(node); + } ui->iaBuffers->addTopLevelItem(node); } @@ -1387,6 +1394,7 @@ void D3D12PipelineStateViewer::setState() (draw ? draw->indexOffset * draw->indexByteWidth : 0)))); setEmptyRow(node); + m_EmptyNodes.push_back(node); if(!ibufferUsed) setInactiveRow(node); @@ -1395,10 +1403,28 @@ void D3D12PipelineStateViewer::setState() } } - m_VBNodes.clear(); - - for(int i = 0; i < state.inputAssembly.vertexBuffers.count(); i++) + for(int i = 0; i < 128; i++) { + if(i >= state.inputAssembly.vertexBuffers.count()) + { + // for vbuffers that are referenced but not bound, make sure we add an empty row + if(usedVBuffers[i]) + { + RDTreeWidgetItem *node = + new RDTreeWidgetItem({i, tr("No Buffer Set"), lit("-"), lit("-"), lit("-"), QString()}); + node->setTag(QVariant::fromValue(D3D12VBIBTag(ResourceId(), 0))); + + setEmptyRow(node); + m_EmptyNodes.push_back(node); + + m_VBNodes.push_back(node); + + ui->iaBuffers->addTopLevelItem(node); + } + + continue; + } + const D3D12Pipe::VertexBuffer &v = state.inputAssembly.vertexBuffers[i]; bool filledSlot = (v.resourceId != ResourceId()); @@ -1424,7 +1450,10 @@ void D3D12PipelineStateViewer::setState() node->setTag(QVariant::fromValue(D3D12VBIBTag(v.resourceId, v.byteOffset))); if(!filledSlot) + { setEmptyRow(node); + m_EmptyNodes.push_back(node); + } if(!usedSlot) setInactiveRow(node); @@ -2022,8 +2051,11 @@ void D3D12PipelineStateViewer::highlightIABind(int slot) if(slot < m_VBNodes.count()) { - m_VBNodes[slot]->setBackgroundColor(col); - m_VBNodes[slot]->setForegroundColor(contrastingColor(col, QColor(0, 0, 0))); + if(!m_EmptyNodes.contains(m_VBNodes[slot])) + { + m_VBNodes[slot]->setBackgroundColor(col); + m_VBNodes[slot]->setForegroundColor(contrastingColor(col, QColor(0, 0, 0))); + } } for(int i = 0; i < ui->iaLayouts->topLevelItemCount(); i++) @@ -2086,8 +2118,11 @@ void D3D12PipelineStateViewer::on_iaBuffers_mouseMove(QMouseEvent *e) } else { - item->setBackground(ui->iaBuffers->palette().brush(QPalette::Window)); - item->setForeground(ui->iaBuffers->palette().brush(QPalette::WindowText)); + if(!m_EmptyNodes.contains(item)) + { + item->setBackground(ui->iaBuffers->palette().brush(QPalette::Window)); + item->setForeground(ui->iaBuffers->palette().brush(QPalette::WindowText)); + } } } } @@ -2109,6 +2144,9 @@ void D3D12PipelineStateViewer::vertex_leave(QEvent *e) { RDTreeWidgetItem *item = ui->iaBuffers->topLevelItem(i); + if(m_EmptyNodes.contains(item)) + continue; + item->setBackground(QBrush()); item->setForeground(QBrush()); } diff --git a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.h b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.h index 861b1ef21..a06e7e98c 100644 --- a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.h +++ b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.h @@ -116,4 +116,6 @@ private: // keep track of the VB nodes (we want to be able to highlight them easily on hover) QList m_VBNodes; + // list of empty VB nodes that shouldn't be highlighted on hover + QList m_EmptyNodes; }; diff --git a/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.cpp index 245c5c0ab..0ae322903 100644 --- a/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.cpp @@ -520,6 +520,7 @@ void GLPipelineStateViewer::clearShaderState(RDLabel *shader, RDTreeWidget *tex, void GLPipelineStateViewer::clearState() { m_VBNodes.clear(); + m_EmptyNodes.clear(); ui->viAttrs->clear(); ui->viBuffers->clear(); @@ -1261,6 +1262,9 @@ void GLPipelineStateViewer::setState() ui->primRestart->setVisible(false); } + m_VBNodes.clear(); + m_EmptyNodes.clear(); + vs = ui->viBuffers->verticalScrollBar()->value(); ui->viBuffers->beginUpdate(); ui->viBuffers->clear(); @@ -1290,7 +1294,10 @@ void GLPipelineStateViewer::setState() setInactiveRow(node); if(state.vertexInput.indexBuffer == ResourceId()) + { setEmptyRow(node); + m_EmptyNodes.push_back(node); + } ui->viBuffers->addTopLevelItem(node); } @@ -1306,6 +1313,7 @@ void GLPipelineStateViewer::setState() state.vertexInput.indexBuffer, draw ? draw->indexOffset * draw->indexByteWidth : 0))); setEmptyRow(node); + m_EmptyNodes.push_back(node); if(!ibufferUsed) setInactiveRow(node); @@ -1314,8 +1322,6 @@ void GLPipelineStateViewer::setState() } } - m_VBNodes.clear(); - for(int i = 0; i < state.vertexInput.vertexBuffers.count(); i++) { const GLPipe::VertexBuffer &v = state.vertexInput.vertexBuffers[i]; @@ -1339,7 +1345,10 @@ void GLPipelineStateViewer::setState() node->setTag(QVariant::fromValue(GLVBIBTag(v.resourceId, v.byteOffset))); if(!filledSlot) + { setEmptyRow(node); + m_EmptyNodes.push_back(node); + } if(!usedSlot) setInactiveRow(node); @@ -2190,8 +2199,11 @@ void GLPipelineStateViewer::highlightIABind(int slot) if(slot < m_VBNodes.count()) { - m_VBNodes[slot]->setBackgroundColor(col); - m_VBNodes[slot]->setForegroundColor(contrastingColor(col, QColor(0, 0, 0))); + if(!m_EmptyNodes.contains(m_VBNodes[slot])) + { + m_VBNodes[slot]->setBackgroundColor(col); + m_VBNodes[slot]->setForegroundColor(contrastingColor(col, QColor(0, 0, 0))); + } } for(int i = 0; i < ui->viAttrs->topLevelItemCount(); i++) @@ -2254,8 +2266,11 @@ void GLPipelineStateViewer::on_viBuffers_mouseMove(QMouseEvent *e) } else { - item->setBackground(ui->viBuffers->palette().brush(QPalette::Window)); - item->setForeground(ui->viBuffers->palette().brush(QPalette::WindowText)); + if(!m_EmptyNodes.contains(item)) + { + item->setBackground(ui->viBuffers->palette().brush(QPalette::Window)); + item->setForeground(ui->viBuffers->palette().brush(QPalette::WindowText)); + } } } } @@ -2273,8 +2288,13 @@ void GLPipelineStateViewer::vertex_leave(QEvent *e) for(int i = 0; i < ui->viBuffers->topLevelItemCount(); i++) { - ui->viBuffers->topLevelItem(i)->setBackground(QBrush()); - ui->viBuffers->topLevelItem(i)->setForeground(QBrush()); + RDTreeWidgetItem *item = ui->viBuffers->topLevelItem(i); + + if(m_EmptyNodes.contains(item)) + continue; + + item->setBackground(QBrush()); + item->setForeground(QBrush()); } ui->viAttrs->endUpdate(); diff --git a/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.h b/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.h index 89cbdfd23..36703f102 100644 --- a/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.h +++ b/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.h @@ -113,4 +113,6 @@ private: // keep track of the VB nodes (we want to be able to highlight them easily on hover) QList m_VBNodes; + // list of empty VB nodes that shouldn't be highlighted on hover + QList m_EmptyNodes; }; diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp index c6a86af44..cce635283 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp @@ -546,6 +546,7 @@ void VulkanPipelineStateViewer::clearState() { m_VBNodes.clear(); m_BindNodes.clear(); + m_EmptyNodes.clear(); ui->viAttrs->clear(); ui->viBuffers->clear(); @@ -1570,6 +1571,8 @@ void VulkanPipelineStateViewer::setState() ui->viAttrs->verticalScrollBar()->setValue(vs); m_BindNodes.clear(); + m_VBNodes.clear(); + m_EmptyNodes.clear(); Topology topo = draw != NULL ? draw->topology : Topology::Unknown; @@ -1621,7 +1624,10 @@ void VulkanPipelineStateViewer::setState() setInactiveRow(node); if(state.inputAssembly.indexBuffer.resourceId == ResourceId()) + { setEmptyRow(node); + m_EmptyNodes.push_back(node); + } ui->viBuffers->addTopLevelItem(node); } @@ -1638,6 +1644,7 @@ void VulkanPipelineStateViewer::setState() draw != NULL ? draw->indexOffset * draw->indexByteWidth : 0))); setEmptyRow(node); + m_EmptyNodes.push_back(node); if(!ibufferUsed) setInactiveRow(node); @@ -1646,8 +1653,6 @@ void VulkanPipelineStateViewer::setState() } } - m_VBNodes.clear(); - { int i = 0; for(; i < qMax(state.vertexInput.vertexBuffers.count(), state.vertexInput.bindings.count()); i++) @@ -1707,7 +1712,10 @@ void VulkanPipelineStateViewer::setState() vbuff != NULL ? vbuff->resourceId : ResourceId(), vbuff != NULL ? vbuff->byteOffset : 0))); if(!filledSlot || bind == NULL || vbuff == NULL) + { setEmptyRow(node); + m_EmptyNodes.push_back(node); + } if(!usedSlot) setInactiveRow(node); @@ -1728,6 +1736,7 @@ void VulkanPipelineStateViewer::setState() node->setTag(QVariant::fromValue(VulkanVBIBTag(ResourceId(), 0))); setEmptyRow(node); + m_EmptyNodes.push_back(node); setInactiveRow(node); @@ -2291,8 +2300,11 @@ void VulkanPipelineStateViewer::highlightIABind(int slot) if(slot < m_VBNodes.count()) { - m_VBNodes[slot]->setBackgroundColor(col); - m_VBNodes[slot]->setForegroundColor(contrastingColor(col, QColor(0, 0, 0))); + if(!m_EmptyNodes.contains(m_VBNodes[slot])) + { + m_VBNodes[slot]->setBackgroundColor(col); + m_VBNodes[slot]->setForegroundColor(contrastingColor(col, QColor(0, 0, 0))); + } } if(slot < m_BindNodes.count()) @@ -2361,8 +2373,11 @@ void VulkanPipelineStateViewer::on_viBuffers_mouseMove(QMouseEvent *e) } else { - item->setBackground(ui->viBuffers->palette().brush(QPalette::Window)); - item->setForeground(ui->viBuffers->palette().brush(QPalette::WindowText)); + if(!m_EmptyNodes.contains(item)) + { + item->setBackground(ui->viBuffers->palette().brush(QPalette::Window)); + item->setForeground(ui->viBuffers->palette().brush(QPalette::WindowText)); + } } } } @@ -2380,8 +2395,13 @@ void VulkanPipelineStateViewer::vertex_leave(QEvent *e) for(int i = 0; i < ui->viBuffers->topLevelItemCount(); i++) { - ui->viBuffers->topLevelItem(i)->setBackground(QBrush()); - ui->viBuffers->topLevelItem(i)->setForeground(QBrush()); + RDTreeWidgetItem *item = ui->viBuffers->topLevelItem(i); + + if(m_EmptyNodes.contains(item)) + continue; + + item->setBackground(QBrush()); + item->setForeground(QBrush()); } ui->viAttrs->endUpdate(); diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h index 35faae3bd..751550bca 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h @@ -125,6 +125,8 @@ private: // keep track of the VB nodes (we want to be able to highlight them easily on hover) QList m_VBNodes; QList m_BindNodes; + // list of empty VB nodes that shouldn't be highlighted on hover + QList m_EmptyNodes; // from an combined image to its sampler (since we de-duplicate) QMap m_CombinedImageSamplers;