From 1c8e72a2526d1b9c601e380373ee49d3efbec814 Mon Sep 17 00:00:00 2001 From: William Pearson Date: Fri, 28 Jul 2023 15:13:35 -0700 Subject: [PATCH 01/10] Create pixel history shader out 2 variable Currently, no backend sets this, and it is not displayed. --- renderdoc/api/replay/data_types.h | 19 +++++++++++++------ renderdoc/driver/d3d11/d3d11_pixelhistory.cpp | 2 ++ renderdoc/driver/gl/gl_pixelhistory.cpp | 2 ++ renderdoc/driver/vulkan/vk_pixelhistory.cpp | 4 ++++ renderdoc/replay/renderdoc_serialise.inl | 3 ++- 5 files changed, 23 insertions(+), 7 deletions(-) diff --git a/renderdoc/api/replay/data_types.h b/renderdoc/api/replay/data_types.h index 3dbb1f1b7f..4ad92db0d9 100644 --- a/renderdoc/api/replay/data_types.h +++ b/renderdoc/api/replay/data_types.h @@ -2100,12 +2100,12 @@ struct PixelModification { return eventId == o.eventId && directShaderWrite == o.directShaderWrite && unboundPS == o.unboundPS && fragIndex == o.fragIndex && primitiveID == o.primitiveID && - preMod == o.preMod && shaderOut == o.shaderOut && postMod == o.postMod && - sampleMasked == o.sampleMasked && backfaceCulled == o.backfaceCulled && - depthClipped == o.depthClipped && depthBoundsFailed == o.depthBoundsFailed && - viewClipped == o.viewClipped && scissorClipped == o.scissorClipped && - shaderDiscarded == o.shaderDiscarded && depthTestFailed == o.depthTestFailed && - stencilTestFailed == o.stencilTestFailed; + preMod == o.preMod && shaderOut == o.shaderOut && shaderOutDualSrc == o.shaderOutDualSrc && + postMod == o.postMod && sampleMasked == o.sampleMasked && + backfaceCulled == o.backfaceCulled && depthClipped == o.depthClipped && + depthBoundsFailed == o.depthBoundsFailed && viewClipped == o.viewClipped && + scissorClipped == o.scissorClipped && shaderDiscarded == o.shaderDiscarded && + depthTestFailed == o.depthTestFailed && stencilTestFailed == o.stencilTestFailed; } bool operator<(const PixelModification &o) const { @@ -2123,6 +2123,8 @@ struct PixelModification return preMod < o.preMod; if(!(shaderOut == o.shaderOut)) return shaderOut < o.shaderOut; + if(!(shaderOutDualSrc == o.shaderOutDualSrc)) + return shaderOutDualSrc < o.shaderOutDualSrc; if(!(postMod == o.postMod)) return postMod < o.postMod; if(!(sampleMasked == o.sampleMasked)) @@ -2175,6 +2177,11 @@ pixel. :type: ModificationValue )"); ModificationValue shaderOut; + DOCUMENT(R"(The value that this fragment wrote from the pixel shader to the second output. + +:type: ModificationValue +)"); + ModificationValue shaderOutDualSrc; DOCUMENT(R"(The value of the texture after this fragment ran. :type: ModificationValue diff --git a/renderdoc/driver/d3d11/d3d11_pixelhistory.cpp b/renderdoc/driver/d3d11/d3d11_pixelhistory.cpp index 77f436b73f..4cb6c49d8c 100644 --- a/renderdoc/driver/d3d11/d3d11_pixelhistory.cpp +++ b/renderdoc/driver/d3d11/d3d11_pixelhistory.cpp @@ -1940,6 +1940,7 @@ rdcarray D3D11Replay::PixelHistory(rdcarray event // data[3].x (depth) unused // fragments writing to the pixel in this event with original shader mod.shaderOut.col.intValue[1] = int32_t(data[3].y); + mod.shaderOutDualSrc.SetInvalid(); } } @@ -2316,6 +2317,7 @@ rdcarray D3D11Replay::PixelHistory(rdcarray event byte *data = shadoutStoreData + sizeof(Vec4f) * pixstoreStride * offsettedSlot; memcpy(&history[h].shaderOut.col.uintValue[0], data, 4 * sizeof(float)); + history[h].shaderOutDualSrc.SetInvalid(); // primitive ID is in the next slot after that memcpy(&history[h].primitiveID, data + sizeof(Vec4f), sizeof(uint32_t)); diff --git a/renderdoc/driver/gl/gl_pixelhistory.cpp b/renderdoc/driver/gl/gl_pixelhistory.cpp index 515608be3e..2dfe4c6906 100644 --- a/renderdoc/driver/gl/gl_pixelhistory.cpp +++ b/renderdoc/driver/gl/gl_pixelhistory.cpp @@ -1303,6 +1303,7 @@ std::map QueryNumFragmentsByEvent( numFragments = history[i].shaderOut.stencil; history[i].shaderOut.stencil = history[i].postMod.stencil; } + history[i].shaderOutDualSrc.SetInvalid(); eventFragments.emplace(modEvents[i].eventId, numFragments); @@ -1587,6 +1588,7 @@ void QueryShaderOutPerFragment(WrappedOpenGL *driver, GLReplay *replay, int(historyIndex - history.begin())); historyIndex->shaderOut.stencil = oldStencil; } + historyIndex->shaderOutDualSrc.SetInvalid(); historyIndex++; } diff --git a/renderdoc/driver/vulkan/vk_pixelhistory.cpp b/renderdoc/driver/vulkan/vk_pixelhistory.cpp index 500ef7b28a..db81a43490 100644 --- a/renderdoc/driver/vulkan/vk_pixelhistory.cpp +++ b/renderdoc/driver/vulkan/vk_pixelhistory.cpp @@ -3972,6 +3972,7 @@ rdcarray VulkanReplay::PixelHistory(rdcarray even mod.preMod.SetInvalid(); mod.postMod.SetInvalid(); mod.shaderOut.SetInvalid(); + mod.shaderOutDualSrc.SetInvalid(); h++; continue; } @@ -3999,6 +4000,7 @@ rdcarray VulkanReplay::PixelHistory(rdcarray even int32_t fragsClipped = int32_t(ei.dsWithShaderDiscard[4]); mod.shaderOut.col.intValue[0] = frags; mod.shaderOut.col.intValue[1] = fragsClipped; + mod.shaderOutDualSrc.SetInvalid(); bool someFragsClipped = (fragsClipped < frags); mod.primitiveID = someFragsClipped; // Draws in secondary command buffers will fail this check, @@ -4145,6 +4147,8 @@ rdcarray VulkanReplay::PixelHistory(rdcarray even { history[h].preMod = history[h - 1].postMod; } + + history[h].shaderOutDualSrc.SetInvalid(); } // check the depth value between premod/shaderout against the known test if we have valid diff --git a/renderdoc/replay/renderdoc_serialise.inl b/renderdoc/replay/renderdoc_serialise.inl index 058149e3bb..ec8f3e060b 100644 --- a/renderdoc/replay/renderdoc_serialise.inl +++ b/renderdoc/replay/renderdoc_serialise.inl @@ -893,6 +893,7 @@ void DoSerialise(SerialiserType &ser, PixelModification &el) SERIALISE_MEMBER(preMod); SERIALISE_MEMBER(shaderOut); + SERIALISE_MEMBER(shaderOutDualSrc); SERIALISE_MEMBER(postMod); SERIALISE_MEMBER(sampleMasked); @@ -906,7 +907,7 @@ void DoSerialise(SerialiserType &ser, PixelModification &el) SERIALISE_MEMBER(stencilTestFailed); SERIALISE_MEMBER(predicationSkipped); - SIZE_CHECK(100); + SIZE_CHECK(124); } template From 3cb021713405767c0ad4f7f99a9722841858c763 Mon Sep 17 00:00:00 2001 From: William Pearson Date: Fri, 28 Jul 2023 15:21:34 -0700 Subject: [PATCH 02/10] Create pixel history blend source and blend dest variables Currently, no backend sets them, and they are not displayed. --- renderdoc/api/replay/data_types.h | 19 +++++++++++++++++-- renderdoc/driver/d3d11/d3d11_pixelhistory.cpp | 4 ++++ renderdoc/driver/gl/gl_pixelhistory.cpp | 4 ++++ renderdoc/driver/vulkan/vk_pixelhistory.cpp | 7 +++++++ renderdoc/replay/renderdoc_serialise.inl | 4 +++- 5 files changed, 35 insertions(+), 3 deletions(-) diff --git a/renderdoc/api/replay/data_types.h b/renderdoc/api/replay/data_types.h index 4ad92db0d9..2423a486d1 100644 --- a/renderdoc/api/replay/data_types.h +++ b/renderdoc/api/replay/data_types.h @@ -2100,8 +2100,9 @@ struct PixelModification { return eventId == o.eventId && directShaderWrite == o.directShaderWrite && unboundPS == o.unboundPS && fragIndex == o.fragIndex && primitiveID == o.primitiveID && - preMod == o.preMod && shaderOut == o.shaderOut && shaderOutDualSrc == o.shaderOutDualSrc && - postMod == o.postMod && sampleMasked == o.sampleMasked && + preMod == o.preMod && shaderOut == o.shaderOut && + shaderOutDualSrc == o.shaderOutDualSrc && blendSrc == o.blendSrc && + blendDst == o.blendDst && postMod == o.postMod && sampleMasked == o.sampleMasked && backfaceCulled == o.backfaceCulled && depthClipped == o.depthClipped && depthBoundsFailed == o.depthBoundsFailed && viewClipped == o.viewClipped && scissorClipped == o.scissorClipped && shaderDiscarded == o.shaderDiscarded && @@ -2125,6 +2126,10 @@ struct PixelModification return shaderOut < o.shaderOut; if(!(shaderOutDualSrc == o.shaderOutDualSrc)) return shaderOutDualSrc < o.shaderOutDualSrc; + if(!(blendSrc == o.blendSrc)) + return blendSrc < o.blendSrc; + if(!(blendDst == o.blendDst)) + return blendDst < o.blendDst; if(!(postMod == o.postMod)) return postMod < o.postMod; if(!(sampleMasked == o.sampleMasked)) @@ -2182,6 +2187,16 @@ pixel. :type: ModificationValue )"); ModificationValue shaderOutDualSrc; + DOCUMENT(R"(The source component in the blend equation for this fragment. + +:type: ModificationValue +)"); + ModificationValue blendSrc; + DOCUMENT(R"(The destination component in the blend equation for this fragment. + +:type: ModificationValue +)"); + ModificationValue blendDst; DOCUMENT(R"(The value of the texture after this fragment ran. :type: ModificationValue diff --git a/renderdoc/driver/d3d11/d3d11_pixelhistory.cpp b/renderdoc/driver/d3d11/d3d11_pixelhistory.cpp index 4cb6c49d8c..efa940f10b 100644 --- a/renderdoc/driver/d3d11/d3d11_pixelhistory.cpp +++ b/renderdoc/driver/d3d11/d3d11_pixelhistory.cpp @@ -1941,6 +1941,8 @@ rdcarray D3D11Replay::PixelHistory(rdcarray event // fragments writing to the pixel in this event with original shader mod.shaderOut.col.intValue[1] = int32_t(data[3].y); mod.shaderOutDualSrc.SetInvalid(); + mod.blendSrc.SetInvalid(); + mod.blendDst.SetInvalid(); } } @@ -2318,6 +2320,8 @@ rdcarray D3D11Replay::PixelHistory(rdcarray event memcpy(&history[h].shaderOut.col.uintValue[0], data, 4 * sizeof(float)); history[h].shaderOutDualSrc.SetInvalid(); + history[h].blendSrc.SetInvalid(); + history[h].blendDst.SetInvalid(); // primitive ID is in the next slot after that memcpy(&history[h].primitiveID, data + sizeof(Vec4f), sizeof(uint32_t)); diff --git a/renderdoc/driver/gl/gl_pixelhistory.cpp b/renderdoc/driver/gl/gl_pixelhistory.cpp index 2dfe4c6906..648f81805a 100644 --- a/renderdoc/driver/gl/gl_pixelhistory.cpp +++ b/renderdoc/driver/gl/gl_pixelhistory.cpp @@ -1304,6 +1304,8 @@ std::map QueryNumFragmentsByEvent( history[i].shaderOut.stencil = history[i].postMod.stencil; } history[i].shaderOutDualSrc.SetInvalid(); + history[i].blendSrc.SetInvalid(); + history[i].blendDst.SetInvalid(); eventFragments.emplace(modEvents[i].eventId, numFragments); @@ -1589,6 +1591,8 @@ void QueryShaderOutPerFragment(WrappedOpenGL *driver, GLReplay *replay, historyIndex->shaderOut.stencil = oldStencil; } historyIndex->shaderOutDualSrc.SetInvalid(); + historyIndex->blendSrc.SetInvalid(); + historyIndex->blendDst.SetInvalid(); historyIndex++; } diff --git a/renderdoc/driver/vulkan/vk_pixelhistory.cpp b/renderdoc/driver/vulkan/vk_pixelhistory.cpp index db81a43490..dfbe367477 100644 --- a/renderdoc/driver/vulkan/vk_pixelhistory.cpp +++ b/renderdoc/driver/vulkan/vk_pixelhistory.cpp @@ -3973,6 +3973,8 @@ rdcarray VulkanReplay::PixelHistory(rdcarray even mod.postMod.SetInvalid(); mod.shaderOut.SetInvalid(); mod.shaderOutDualSrc.SetInvalid(); + mod.blendSrc.SetInvalid(); + mod.blendDst.SetInvalid(); h++; continue; } @@ -4001,6 +4003,8 @@ rdcarray VulkanReplay::PixelHistory(rdcarray even mod.shaderOut.col.intValue[0] = frags; mod.shaderOut.col.intValue[1] = fragsClipped; mod.shaderOutDualSrc.SetInvalid(); + mod.blendSrc.SetInvalid(); + mod.blendDst.SetInvalid(); bool someFragsClipped = (fragsClipped < frags); mod.primitiveID = someFragsClipped; // Draws in secondary command buffers will fail this check, @@ -4149,6 +4153,9 @@ rdcarray VulkanReplay::PixelHistory(rdcarray even } history[h].shaderOutDualSrc.SetInvalid(); + + history[h].blendSrc.SetInvalid(); + history[h].blendDst.SetInvalid(); } // check the depth value between premod/shaderout against the known test if we have valid diff --git a/renderdoc/replay/renderdoc_serialise.inl b/renderdoc/replay/renderdoc_serialise.inl index ec8f3e060b..4fd593c975 100644 --- a/renderdoc/replay/renderdoc_serialise.inl +++ b/renderdoc/replay/renderdoc_serialise.inl @@ -894,6 +894,8 @@ void DoSerialise(SerialiserType &ser, PixelModification &el) SERIALISE_MEMBER(preMod); SERIALISE_MEMBER(shaderOut); SERIALISE_MEMBER(shaderOutDualSrc); + SERIALISE_MEMBER(blendSrc); + SERIALISE_MEMBER(blendDst); SERIALISE_MEMBER(postMod); SERIALISE_MEMBER(sampleMasked); @@ -907,7 +909,7 @@ void DoSerialise(SerialiserType &ser, PixelModification &el) SERIALISE_MEMBER(stencilTestFailed); SERIALISE_MEMBER(predicationSkipped); - SIZE_CHECK(124); + SIZE_CHECK(172); } template From 664c52ff90eae2acfa603cf78bdcacfc63d45261 Mon Sep 17 00:00:00 2001 From: William Pearson Date: Fri, 28 Jul 2023 15:30:37 -0700 Subject: [PATCH 03/10] Blend pixel history widget background color with selection color Before, if a row was selected, the color was completely replaced, which makes the color preview column completely useless for that row. This change also fixes some inconsistencies with how the selection hover works on tree widgets; previously part of the row was not highlighted. --- qrenderdoc/Styles/RDStyle/RDStyle.cpp | 22 +++++++++++++++++++--- qrenderdoc/Widgets/Extended/RDTreeView.cpp | 17 +++++------------ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/qrenderdoc/Styles/RDStyle/RDStyle.cpp b/qrenderdoc/Styles/RDStyle/RDStyle.cpp index bab9903fd5..cc0a707539 100644 --- a/qrenderdoc/Styles/RDStyle/RDStyle.cpp +++ b/qrenderdoc/Styles/RDStyle/RDStyle.cpp @@ -1551,9 +1551,25 @@ void RDStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *opt, Q group = QPalette::Inactive; if(viewitem->state & QStyle::State_Selected) - p->fillRect(viewitem->rect, viewitem->palette.brush(group, QPalette::Highlight)); - else if(viewitem->backgroundBrush.style() != Qt::NoBrush) - p->fillRect(viewitem->rect, viewitem->backgroundBrush); + { + if(viewitem->backgroundBrush.style() != Qt::NoBrush) + { + p->fillRect(viewitem->rect, viewitem->backgroundBrush); + // If we have a custom color, use the selection color at half opacity over the custom color + QColor col = viewitem->palette.color(group, QPalette::Highlight); + col.setAlphaF(0.5f); + p->fillRect(viewitem->rect, QBrush(col)); + } + else + { + p->fillRect(viewitem->rect, viewitem->palette.brush(group, QPalette::Highlight)); + } + } + else + { + if(viewitem->backgroundBrush.style() != Qt::NoBrush) + p->fillRect(viewitem->rect, viewitem->backgroundBrush); + } return; } diff --git a/qrenderdoc/Widgets/Extended/RDTreeView.cpp b/qrenderdoc/Widgets/Extended/RDTreeView.cpp index 5715a25b8e..31c1ffdb0e 100644 --- a/qrenderdoc/Widgets/Extended/RDTreeView.cpp +++ b/qrenderdoc/Widgets/Extended/RDTreeView.cpp @@ -771,18 +771,11 @@ void RDTreeView::drawBranches(QPainter *painter, const QRect &rect, const QModel idx = idx.parent(); } - opt.rect = rect; - opt.rect.setWidth(depth * indentation()); + opt.rect = allLinesRect; opt.showDecorationSelected = true; + opt.backgroundBrush = index.data(Qt::BackgroundRole).value(); style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, this); - QBrush back = index.data(Qt::BackgroundRole).value(); - - if(!selectionModel()->isSelected(index) && back.style() != Qt::NoBrush) - { - painter->fillRect(allLinesRect, back); - } - if(m_VisibleBranches) { QTreeView::drawBranches(painter, rect, index); @@ -821,12 +814,12 @@ void RDTreeView::drawBranches(QPainter *painter, const QRect &rect, const QModel { parent = parents.pop(); - back = parent.data(RDTreeView::TreeLineColorRole).value(); + QBrush line = parent.data(RDTreeView::TreeLineColorRole).value(); - if(back.style() != Qt::NoBrush) + if(line.style() != Qt::NoBrush) { // draw a centred pen vertically down the middle of branchRect - painter->setPen(QPen(QBrush(back), m_treeColorLineWidth)); + painter->setPen(QPen(line, m_treeColorLineWidth)); QPoint topCentre = QRect(branchRect).center(); QPoint bottomCentre = topCentre; From a7f885f814b9dbc89d36e5b11ec7ab9afd03d600 Mon Sep 17 00:00:00 2001 From: William Pearson Date: Fri, 28 Jul 2023 15:34:10 -0700 Subject: [PATCH 04/10] Fix debug pixel at primitive and event message mixing parameter order up --- qrenderdoc/Windows/PixelHistoryView.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qrenderdoc/Windows/PixelHistoryView.cpp b/qrenderdoc/Windows/PixelHistoryView.cpp index 64a7c23540..d54d549580 100644 --- a/qrenderdoc/Windows/PixelHistoryView.cpp +++ b/qrenderdoc/Windows/PixelHistoryView.cpp @@ -848,8 +848,8 @@ void PixelHistoryView::on_events_customContextMenuRequested(const QPoint &pos) debugText = tr("&Debug Pixel (%1, %2) primitive %3 at Event %4") .arg(m_Pixel.x()) .arg(m_Pixel.y()) - .arg(tag.eventId) - .arg(tag.primitive); + .arg(tag.primitive) + .arg(tag.eventId); contextMenu.addAction(&jumpAction); } From c0d34af63551b470aa80790fb43bbfbcb5c46c25 Mon Sep 17 00:00:00 2001 From: William Pearson Date: Fri, 28 Jul 2023 15:35:16 -0700 Subject: [PATCH 05/10] Use an enum for pixel history column ids instead of magic numbers --- qrenderdoc/Windows/PixelHistoryView.cpp | 54 +++++++++++++++++-------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/qrenderdoc/Windows/PixelHistoryView.cpp b/qrenderdoc/Windows/PixelHistoryView.cpp index d54d549580..2305dad978 100644 --- a/qrenderdoc/Windows/PixelHistoryView.cpp +++ b/qrenderdoc/Windows/PixelHistoryView.cpp @@ -39,6 +39,16 @@ struct EventTag Q_DECLARE_METATYPE(EventTag); +enum +{ + COL_EVENT, + COL_SHADER_OUT, + COL_SHADER_OUT_COLOR, + COL_TEX_AFTER, + COL_TEX_AFTER_COLOR, + COL_COUNT, +}; + class PixelHistoryItemModel : public QAbstractItemModel { public: @@ -71,6 +81,16 @@ class PixelHistoryItemModel : public QAbstractItemModel } } + static bool isColorColumn(int column) + { + switch(column) + { + case COL_SHADER_OUT_COLOR: + case COL_TEX_AFTER_COLOR: return true; + default: return false; + } + } + void setHistory(const rdcarray &history) { m_ModList.reserve(history.count()); @@ -144,7 +164,7 @@ class PixelHistoryItemModel : public QAbstractItemModel return 0; } - int columnCount(const QModelIndex &parent = QModelIndex()) const override { return 5; } + int columnCount(const QModelIndex &parent = QModelIndex()) const override { return COL_COUNT; } Qt::ItemFlags flags(const QModelIndex &index) const override { if(!index.isValid()) @@ -155,11 +175,11 @@ class PixelHistoryItemModel : public QAbstractItemModel QVariant headerData(int section, Qt::Orientation orientation, int role) const override { - if(orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0) + if(orientation == Qt::Horizontal && role == Qt::DisplayRole && section == COL_EVENT) return lit("Event"); // sizes for the colour previews - if(orientation == Qt::Horizontal && role == Qt::SizeHintRole && (section == 2 || section == 4)) + if(orientation == Qt::Horizontal && role == Qt::SizeHintRole && isColorColumn(section)) return QSize(18, 0); return QVariant(); @@ -172,7 +192,7 @@ class PixelHistoryItemModel : public QAbstractItemModel int col = index.column(); // preview columns - if(col == 2 || col == 4) + if(isColorColumn(col)) { if(role == Qt::SizeHintRole) return QSize(16, 0); @@ -180,7 +200,7 @@ class PixelHistoryItemModel : public QAbstractItemModel if(m_Loading) { - if(role == Qt::DisplayRole && col == 0) + if(role == Qt::DisplayRole && col == COL_EVENT) return tr("Loading..."); return QVariant(); @@ -190,7 +210,7 @@ class PixelHistoryItemModel : public QAbstractItemModel { QString uavName = IsD3D(m_Ctx.APIProps().pipelineType) ? lit("UAV") : lit("Storage"); // main text - if(col == 0) + if(col == COL_EVENT) { if(isEvent(index)) { @@ -292,7 +312,7 @@ class PixelHistoryItemModel : public QAbstractItemModel } // pre mod/shader out text - if(col == 1) + if(col == COL_SHADER_OUT) { if(isEvent(index)) { @@ -310,7 +330,7 @@ class PixelHistoryItemModel : public QAbstractItemModel } // post mod text - if(col == 3) + if(col == COL_TEX_AFTER) { if(isEvent(index)) return tr("Tex After\n\n") + modString(getMods(index).last().postMod); @@ -322,7 +342,7 @@ class PixelHistoryItemModel : public QAbstractItemModel if(role == Qt::BackgroundRole && (m_IsDepth || m_IsFloat)) { // pre mod color - if(col == 2) + if(col == COL_SHADER_OUT_COLOR) { if(isEvent(index)) { @@ -336,7 +356,7 @@ class PixelHistoryItemModel : public QAbstractItemModel return backgroundBrush(mod.shaderOut); } } - else if(col == 4) + else if(col == COL_TEX_AFTER_COLOR) { if(isEvent(index)) return backgroundBrush(getMods(index).last().postMod); @@ -346,7 +366,7 @@ class PixelHistoryItemModel : public QAbstractItemModel } // text backgrounds marking pass/fail - if(role == Qt::BackgroundRole && (col == 0 || col == 1 || col == 3)) + if(role == Qt::BackgroundRole && !isColorColumn(col)) { // rest if(isEvent(index)) @@ -373,7 +393,7 @@ class PixelHistoryItemModel : public QAbstractItemModel // Since we change the background color for some cells, also change the foreground color to // ensure contrast with all UI themes - if(role == Qt::ForegroundRole && (col == 0 || col == 1 || col == 3)) + if(role == Qt::ForegroundRole && !isColorColumn(col)) { QColor textColor = contrastingColor(QColor::fromRgb(235, 235, 235), m_Palette.color(QPalette::Text)); @@ -639,11 +659,11 @@ PixelHistoryView::PixelHistoryView(ICaptureContext &ctx, ResourceId id, QPoint p ui->events->hideBranches(); - ui->events->header()->setSectionResizeMode(0, QHeaderView::Stretch); - ui->events->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); - ui->events->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents); - ui->events->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents); - ui->events->header()->setSectionResizeMode(4, QHeaderView::ResizeToContents); + ui->events->header()->setSectionResizeMode(COL_EVENT, QHeaderView::Stretch); + ui->events->header()->setSectionResizeMode(COL_SHADER_OUT, QHeaderView::ResizeToContents); + ui->events->header()->setSectionResizeMode(COL_SHADER_OUT_COLOR, QHeaderView::ResizeToContents); + ui->events->header()->setSectionResizeMode(COL_TEX_AFTER, QHeaderView::ResizeToContents); + ui->events->header()->setSectionResizeMode(COL_TEX_AFTER_COLOR, QHeaderView::ResizeToContents); m_Ctx.AddCaptureViewer(this); } From e0cad1eabc422a0443c2974e21ae919f44bd854d Mon Sep 17 00:00:00 2001 From: William Pearson Date: Fri, 28 Jul 2023 15:37:03 -0700 Subject: [PATCH 06/10] Allow changing the columns for pixel history --- qrenderdoc/Windows/PixelHistoryView.cpp | 48 +++++++++++++++++++++++-- qrenderdoc/Windows/PixelHistoryView.h | 5 ++- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/qrenderdoc/Windows/PixelHistoryView.cpp b/qrenderdoc/Windows/PixelHistoryView.cpp index 2305dad978..e7cc17533c 100644 --- a/qrenderdoc/Windows/PixelHistoryView.cpp +++ b/qrenderdoc/Windows/PixelHistoryView.cpp @@ -175,8 +175,25 @@ class PixelHistoryItemModel : public QAbstractItemModel QVariant headerData(int section, Qt::Orientation orientation, int role) const override { - if(orientation == Qt::Horizontal && role == Qt::DisplayRole && section == COL_EVENT) - return lit("Event"); + if(orientation == Qt::Horizontal && role == Qt::DisplayRole) + { + QString result; + switch(section) + { + case COL_EVENT: result = lit("Event"); break; + case COL_SHADER_OUT: + case COL_SHADER_OUT_COLOR: result = lit("Shader Out"); break; + case COL_TEX_AFTER: + case COL_TEX_AFTER_COLOR: result = lit("Tex After"); break; + } + if(isColorColumn(section)) + { + // Pad with spaces so that the text isn't visible in the headers, only on the column chooser + // (it wouldn't fit anyways) + result = lit(" ") + result + lit(" color"); + } + return result; + } // sizes for the colour previews if(orientation == Qt::Horizontal && role == Qt::SizeHintRole && isColorColumn(section)) @@ -665,6 +682,13 @@ PixelHistoryView::PixelHistoryView(ICaptureContext &ctx, ResourceId id, QPoint p ui->events->header()->setSectionResizeMode(COL_TEX_AFTER, QHeaderView::ResizeToContents); ui->events->header()->setSectionResizeMode(COL_TEX_AFTER_COLOR, QHeaderView::ResizeToContents); + QObject::connect(ui->events, &RDTreeView::customContextMenuRequested, this, + &PixelHistoryView::events_contextMenu); + + ui->events->header()->setContextMenuPolicy(Qt::CustomContextMenu); + QObject::connect(ui->events->header(), &QHeaderView::customContextMenuRequested, this, + &PixelHistoryView::events_contextMenu); + m_Ctx.AddCaptureViewer(this); } @@ -822,8 +846,19 @@ void PixelHistoryView::jumpToPrimitive(EventTag tag) } } -void PixelHistoryView::on_events_customContextMenuRequested(const QPoint &pos) +void PixelHistoryView::colSelect_clicked() +{ + QStringList headers; + for(int i = 0; i < ui->events->model()->columnCount(); i++) + headers << ui->events->model()->headerData(i, Qt::Horizontal).toString(); + UpdateVisibleColumns(tr("Select Pixel History Columns"), COL_COUNT, ui->events->header(), headers); +} + +void PixelHistoryView::events_contextMenu(const QPoint &pos) { + // TODO: this uses coordinates that are supposed to be relative to the header as coordinates in + // the table, so right-clicking the header uses the first entry instead (same applies to + // EventBrowser.cpp) QModelIndex index = ui->events->indexAt(pos); QMenu contextMenu(this); @@ -839,6 +874,13 @@ void PixelHistoryView::on_events_customContextMenuRequested(const QPoint &pos) ui->eventsHidden->setVisible(!m_ShowFailures); }); + QAction selectCols(tr("&Select Columns..."), this); + + contextMenu.addAction(&selectCols); + selectCols.setIcon(Icons::timeline_marker()); + + QObject::connect(&selectCols, &QAction::triggered, this, &PixelHistoryView::colSelect_clicked); + if(!index.isValid()) { RDDialog::show(&contextMenu, ui->events->viewport()->mapToGlobal(pos)); diff --git a/qrenderdoc/Windows/PixelHistoryView.h b/qrenderdoc/Windows/PixelHistoryView.h index e468c65b2a..a11b6a57f1 100644 --- a/qrenderdoc/Windows/PixelHistoryView.h +++ b/qrenderdoc/Windows/PixelHistoryView.h @@ -55,9 +55,12 @@ class PixelHistoryView : public QFrame, public IPixelHistoryView, public ICaptur void OnEventChanged(uint32_t eventId) override; private slots: // automatic slots - void on_events_customContextMenuRequested(const QPoint &pos); void on_events_doubleClicked(const QModelIndex &index); + // manual slots + void colSelect_clicked(); + void events_contextMenu(const QPoint &pos); + protected: void enterEvent(QEvent *event) override; void leaveEvent(QEvent *event) override; From c62b453a52996ebb35b1f6e80b1bedd6a741be29 Mon Sep 17 00:00:00 2001 From: William Pearson Date: Fri, 28 Jul 2023 15:38:16 -0700 Subject: [PATCH 07/10] Create pixel history tex before column This is already implemented by all backends, but did not get displayed beforehand. This column is not visible by default. --- qrenderdoc/Windows/PixelHistoryView.cpp | 71 +++++++++++++++++-------- 1 file changed, 49 insertions(+), 22 deletions(-) diff --git a/qrenderdoc/Windows/PixelHistoryView.cpp b/qrenderdoc/Windows/PixelHistoryView.cpp index e7cc17533c..733e2090d9 100644 --- a/qrenderdoc/Windows/PixelHistoryView.cpp +++ b/qrenderdoc/Windows/PixelHistoryView.cpp @@ -42,6 +42,8 @@ Q_DECLARE_METATYPE(EventTag); enum { COL_EVENT, + COL_TEX_BEFORE, + COL_TEX_BEFORE_COLOR, COL_SHADER_OUT, COL_SHADER_OUT_COLOR, COL_TEX_AFTER, @@ -85,6 +87,7 @@ class PixelHistoryItemModel : public QAbstractItemModel { switch(column) { + case COL_TEX_BEFORE_COLOR: case COL_SHADER_OUT_COLOR: case COL_TEX_AFTER_COLOR: return true; default: return false; @@ -181,6 +184,8 @@ class PixelHistoryItemModel : public QAbstractItemModel switch(section) { case COL_EVENT: result = lit("Event"); break; + case COL_TEX_BEFORE: + case COL_TEX_BEFORE_COLOR: result = lit("Tex Before"); break; case COL_SHADER_OUT: case COL_SHADER_OUT_COLOR: result = lit("Shader Out"); break; case COL_TEX_AFTER: @@ -328,57 +333,73 @@ class PixelHistoryItemModel : public QAbstractItemModel } } - // pre mod/shader out text - if(col == COL_SHADER_OUT) + if(isEvent(index)) { - if(isEvent(index)) + // We can't provide meaningful shader out messages for events, only individual primitives. + // So, use the Tex Before value for all of them. + if(col == COL_TEX_BEFORE || col == COL_SHADER_OUT) { return tr("Tex Before\n\n") + modString(getMods(index).first().preMod); } - else + else if(col == COL_TEX_AFTER) + { + return tr("Tex After\n\n") + modString(getMods(index).last().postMod); + } + } + else + { + if(col == COL_TEX_BEFORE) + { + return tr("Tex Before\n\n") + modString(getMod(index).preMod); + } + else if(col == COL_SHADER_OUT) { const PixelModification &mod = getMod(index); if(mod.unboundPS) return tr("No Pixel\nShader\nBound"); if(mod.directShaderWrite) return tr("Tex Before\n\n") + modString(mod.preMod); + return tr("Shader Out\n\n") + modString(mod.shaderOut, 4); } - } - - // post mod text - if(col == COL_TEX_AFTER) - { - if(isEvent(index)) - return tr("Tex After\n\n") + modString(getMods(index).last().postMod); - else + else if(col == COL_TEX_AFTER) + { return tr("Tex After\n\n") + modString(getMod(index).postMod); + } } } if(role == Qt::BackgroundRole && (m_IsDepth || m_IsFloat)) { - // pre mod color - if(col == COL_SHADER_OUT_COLOR) + if(isEvent(index)) { - if(isEvent(index)) + if(col == COL_TEX_BEFORE_COLOR || col == COL_SHADER_OUT_COLOR) { return backgroundBrush(getMods(index).first().preMod); } - else + else if(col == COL_TEX_AFTER_COLOR) + { + return backgroundBrush(getMods(index).last().postMod); + } + } + else + { + if(col == COL_TEX_BEFORE_COLOR) + { + return backgroundBrush(getMod(index).preMod); + } + else if(col == COL_SHADER_OUT_COLOR) { const PixelModification &mod = getMod(index); if(mod.directShaderWrite) return backgroundBrush(mod.preMod); + return backgroundBrush(mod.shaderOut); } - } - else if(col == COL_TEX_AFTER_COLOR) - { - if(isEvent(index)) - return backgroundBrush(getMods(index).last().postMod); - else + else if(col == COL_TEX_AFTER_COLOR) + { return backgroundBrush(getMod(index).postMod); + } } } @@ -677,11 +698,17 @@ PixelHistoryView::PixelHistoryView(ICaptureContext &ctx, ResourceId id, QPoint p ui->events->hideBranches(); ui->events->header()->setSectionResizeMode(COL_EVENT, QHeaderView::Stretch); + ui->events->header()->setSectionResizeMode(COL_TEX_BEFORE, QHeaderView::ResizeToContents); + ui->events->header()->setSectionResizeMode(COL_TEX_BEFORE_COLOR, QHeaderView::ResizeToContents); ui->events->header()->setSectionResizeMode(COL_SHADER_OUT, QHeaderView::ResizeToContents); ui->events->header()->setSectionResizeMode(COL_SHADER_OUT_COLOR, QHeaderView::ResizeToContents); ui->events->header()->setSectionResizeMode(COL_TEX_AFTER, QHeaderView::ResizeToContents); ui->events->header()->setSectionResizeMode(COL_TEX_AFTER_COLOR, QHeaderView::ResizeToContents); + // Hide these by default; only shader out and tex after are visible by default + ui->events->header()->hideSection(COL_TEX_BEFORE); + ui->events->header()->hideSection(COL_TEX_BEFORE_COLOR); + QObject::connect(ui->events, &RDTreeView::customContextMenuRequested, this, &PixelHistoryView::events_contextMenu); From de2db79a193331b4ebb1e2f3cd591705a55d4e49 Mon Sep 17 00:00:00 2001 From: William Pearson Date: Fri, 28 Jul 2023 15:40:01 -0700 Subject: [PATCH 08/10] Create pixel history shader out 2 column This has not yet been implemented by any backends, not is the column visible by default. --- qrenderdoc/Windows/PixelHistoryView.cpp | 28 +++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/qrenderdoc/Windows/PixelHistoryView.cpp b/qrenderdoc/Windows/PixelHistoryView.cpp index 733e2090d9..0c821fa993 100644 --- a/qrenderdoc/Windows/PixelHistoryView.cpp +++ b/qrenderdoc/Windows/PixelHistoryView.cpp @@ -46,6 +46,8 @@ enum COL_TEX_BEFORE_COLOR, COL_SHADER_OUT, COL_SHADER_OUT_COLOR, + COL_SHADER_OUT_2, + COL_SHADER_OUT_2_COLOR, COL_TEX_AFTER, COL_TEX_AFTER_COLOR, COL_COUNT, @@ -89,6 +91,7 @@ class PixelHistoryItemModel : public QAbstractItemModel { case COL_TEX_BEFORE_COLOR: case COL_SHADER_OUT_COLOR: + case COL_SHADER_OUT_2_COLOR: case COL_TEX_AFTER_COLOR: return true; default: return false; } @@ -188,6 +191,8 @@ class PixelHistoryItemModel : public QAbstractItemModel case COL_TEX_BEFORE_COLOR: result = lit("Tex Before"); break; case COL_SHADER_OUT: case COL_SHADER_OUT_COLOR: result = lit("Shader Out"); break; + case COL_SHADER_OUT_2: + case COL_SHADER_OUT_2_COLOR: result = lit("Shader Out 2"); break; case COL_TEX_AFTER: case COL_TEX_AFTER_COLOR: result = lit("Tex After"); break; } @@ -337,7 +342,7 @@ class PixelHistoryItemModel : public QAbstractItemModel { // We can't provide meaningful shader out messages for events, only individual primitives. // So, use the Tex Before value for all of them. - if(col == COL_TEX_BEFORE || col == COL_SHADER_OUT) + if(col == COL_TEX_BEFORE || col == COL_SHADER_OUT || col == COL_SHADER_OUT_2) { return tr("Tex Before\n\n") + modString(getMods(index).first().preMod); } @@ -352,7 +357,7 @@ class PixelHistoryItemModel : public QAbstractItemModel { return tr("Tex Before\n\n") + modString(getMod(index).preMod); } - else if(col == COL_SHADER_OUT) + else if(col == COL_SHADER_OUT || col == COL_SHADER_OUT_2) { const PixelModification &mod = getMod(index); if(mod.unboundPS) @@ -360,7 +365,10 @@ class PixelHistoryItemModel : public QAbstractItemModel if(mod.directShaderWrite) return tr("Tex Before\n\n") + modString(mod.preMod); - return tr("Shader Out\n\n") + modString(mod.shaderOut, 4); + if(col == COL_SHADER_OUT) + return tr("Shader Out\n\n") + modString(mod.shaderOut, 4); + else + return tr("Shader Out 2\n\n") + modString(mod.shaderOutDualSrc, 4); } else if(col == COL_TEX_AFTER) { @@ -373,7 +381,8 @@ class PixelHistoryItemModel : public QAbstractItemModel { if(isEvent(index)) { - if(col == COL_TEX_BEFORE_COLOR || col == COL_SHADER_OUT_COLOR) + if(col == COL_TEX_BEFORE_COLOR || col == COL_SHADER_OUT_COLOR || + col == COL_SHADER_OUT_2_COLOR) { return backgroundBrush(getMods(index).first().preMod); } @@ -388,13 +397,16 @@ class PixelHistoryItemModel : public QAbstractItemModel { return backgroundBrush(getMod(index).preMod); } - else if(col == COL_SHADER_OUT_COLOR) + else if(col == COL_SHADER_OUT_COLOR || col == COL_SHADER_OUT_2_COLOR) { const PixelModification &mod = getMod(index); if(mod.directShaderWrite) return backgroundBrush(mod.preMod); - return backgroundBrush(mod.shaderOut); + if(col == COL_SHADER_OUT_COLOR) + return backgroundBrush(mod.shaderOut); + else + return backgroundBrush(mod.shaderOutDualSrc); } else if(col == COL_TEX_AFTER_COLOR) { @@ -702,12 +714,16 @@ PixelHistoryView::PixelHistoryView(ICaptureContext &ctx, ResourceId id, QPoint p ui->events->header()->setSectionResizeMode(COL_TEX_BEFORE_COLOR, QHeaderView::ResizeToContents); ui->events->header()->setSectionResizeMode(COL_SHADER_OUT, QHeaderView::ResizeToContents); ui->events->header()->setSectionResizeMode(COL_SHADER_OUT_COLOR, QHeaderView::ResizeToContents); + ui->events->header()->setSectionResizeMode(COL_SHADER_OUT_2, QHeaderView::ResizeToContents); + ui->events->header()->setSectionResizeMode(COL_SHADER_OUT_2_COLOR, QHeaderView::ResizeToContents); ui->events->header()->setSectionResizeMode(COL_TEX_AFTER, QHeaderView::ResizeToContents); ui->events->header()->setSectionResizeMode(COL_TEX_AFTER_COLOR, QHeaderView::ResizeToContents); // Hide these by default; only shader out and tex after are visible by default ui->events->header()->hideSection(COL_TEX_BEFORE); ui->events->header()->hideSection(COL_TEX_BEFORE_COLOR); + ui->events->header()->hideSection(COL_SHADER_OUT_2); + ui->events->header()->hideSection(COL_SHADER_OUT_2_COLOR); QObject::connect(ui->events, &RDTreeView::customContextMenuRequested, this, &PixelHistoryView::events_contextMenu); From d19013d3006589bf5bf00d632b4a4a6bda3328cc Mon Sep 17 00:00:00 2001 From: William Pearson Date: Fri, 28 Jul 2023 15:41:05 -0700 Subject: [PATCH 09/10] Create pixel history blend source and blend dest columns They have not yet been implemented by any backends, not are the columns visible by default. --- qrenderdoc/Windows/PixelHistoryView.cpp | 43 ++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/qrenderdoc/Windows/PixelHistoryView.cpp b/qrenderdoc/Windows/PixelHistoryView.cpp index 0c821fa993..9db98d5420 100644 --- a/qrenderdoc/Windows/PixelHistoryView.cpp +++ b/qrenderdoc/Windows/PixelHistoryView.cpp @@ -48,6 +48,10 @@ enum COL_SHADER_OUT_COLOR, COL_SHADER_OUT_2, COL_SHADER_OUT_2_COLOR, + COL_BLEND_SRC, + COL_BLEND_SRC_COLOR, + COL_BLEND_DST, + COL_BLEND_DST_COLOR, COL_TEX_AFTER, COL_TEX_AFTER_COLOR, COL_COUNT, @@ -92,6 +96,8 @@ class PixelHistoryItemModel : public QAbstractItemModel case COL_TEX_BEFORE_COLOR: case COL_SHADER_OUT_COLOR: case COL_SHADER_OUT_2_COLOR: + case COL_BLEND_SRC_COLOR: + case COL_BLEND_DST_COLOR: case COL_TEX_AFTER_COLOR: return true; default: return false; } @@ -193,6 +199,10 @@ class PixelHistoryItemModel : public QAbstractItemModel case COL_SHADER_OUT_COLOR: result = lit("Shader Out"); break; case COL_SHADER_OUT_2: case COL_SHADER_OUT_2_COLOR: result = lit("Shader Out 2"); break; + case COL_BLEND_SRC: + case COL_BLEND_SRC_COLOR: result = lit("Blend Source"); break; + case COL_BLEND_DST: + case COL_BLEND_DST_COLOR: result = lit("Blend Dest"); break; case COL_TEX_AFTER: case COL_TEX_AFTER_COLOR: result = lit("Tex After"); break; } @@ -342,11 +352,12 @@ class PixelHistoryItemModel : public QAbstractItemModel { // We can't provide meaningful shader out messages for events, only individual primitives. // So, use the Tex Before value for all of them. - if(col == COL_TEX_BEFORE || col == COL_SHADER_OUT || col == COL_SHADER_OUT_2) + if(col == COL_TEX_BEFORE || col == COL_SHADER_OUT || col == COL_SHADER_OUT_2 || + col == COL_BLEND_SRC) { return tr("Tex Before\n\n") + modString(getMods(index).first().preMod); } - else if(col == COL_TEX_AFTER) + else if(col == COL_TEX_AFTER || col == COL_BLEND_DST) { return tr("Tex After\n\n") + modString(getMods(index).last().postMod); } @@ -370,6 +381,14 @@ class PixelHistoryItemModel : public QAbstractItemModel else return tr("Shader Out 2\n\n") + modString(mod.shaderOutDualSrc, 4); } + else if(col == COL_BLEND_SRC) + { + return tr("Blend Source\n\n") + modString(getMod(index).blendSrc); + } + else if(col == COL_BLEND_DST) + { + return tr("Blend Dest\n\n") + modString(getMod(index).blendDst); + } else if(col == COL_TEX_AFTER) { return tr("Tex After\n\n") + modString(getMod(index).postMod); @@ -382,11 +401,11 @@ class PixelHistoryItemModel : public QAbstractItemModel if(isEvent(index)) { if(col == COL_TEX_BEFORE_COLOR || col == COL_SHADER_OUT_COLOR || - col == COL_SHADER_OUT_2_COLOR) + col == COL_SHADER_OUT_2_COLOR || col == COL_BLEND_SRC_COLOR) { return backgroundBrush(getMods(index).first().preMod); } - else if(col == COL_TEX_AFTER_COLOR) + else if(col == COL_TEX_AFTER_COLOR || col == COL_BLEND_DST_COLOR) { return backgroundBrush(getMods(index).last().postMod); } @@ -408,6 +427,14 @@ class PixelHistoryItemModel : public QAbstractItemModel else return backgroundBrush(mod.shaderOutDualSrc); } + else if(col == COL_BLEND_SRC_COLOR) + { + return backgroundBrush(getMod(index).blendSrc); + } + else if(col == COL_BLEND_DST_COLOR) + { + return backgroundBrush(getMod(index).blendDst); + } else if(col == COL_TEX_AFTER_COLOR) { return backgroundBrush(getMod(index).postMod); @@ -716,6 +743,10 @@ PixelHistoryView::PixelHistoryView(ICaptureContext &ctx, ResourceId id, QPoint p ui->events->header()->setSectionResizeMode(COL_SHADER_OUT_COLOR, QHeaderView::ResizeToContents); ui->events->header()->setSectionResizeMode(COL_SHADER_OUT_2, QHeaderView::ResizeToContents); ui->events->header()->setSectionResizeMode(COL_SHADER_OUT_2_COLOR, QHeaderView::ResizeToContents); + ui->events->header()->setSectionResizeMode(COL_BLEND_SRC, QHeaderView::ResizeToContents); + ui->events->header()->setSectionResizeMode(COL_BLEND_SRC_COLOR, QHeaderView::ResizeToContents); + ui->events->header()->setSectionResizeMode(COL_BLEND_DST, QHeaderView::ResizeToContents); + ui->events->header()->setSectionResizeMode(COL_BLEND_DST_COLOR, QHeaderView::ResizeToContents); ui->events->header()->setSectionResizeMode(COL_TEX_AFTER, QHeaderView::ResizeToContents); ui->events->header()->setSectionResizeMode(COL_TEX_AFTER_COLOR, QHeaderView::ResizeToContents); @@ -724,6 +755,10 @@ PixelHistoryView::PixelHistoryView(ICaptureContext &ctx, ResourceId id, QPoint p ui->events->header()->hideSection(COL_TEX_BEFORE_COLOR); ui->events->header()->hideSection(COL_SHADER_OUT_2); ui->events->header()->hideSection(COL_SHADER_OUT_2_COLOR); + ui->events->header()->hideSection(COL_BLEND_SRC); + ui->events->header()->hideSection(COL_BLEND_SRC_COLOR); + ui->events->header()->hideSection(COL_BLEND_DST); + ui->events->header()->hideSection(COL_BLEND_DST_COLOR); QObject::connect(ui->events, &RDTreeView::customContextMenuRequested, this, &PixelHistoryView::events_contextMenu); From b5517f591accf6fd17060da9182da2973b5de21d Mon Sep 17 00:00:00 2001 From: William Pearson Date: Fri, 28 Jul 2023 15:42:18 -0700 Subject: [PATCH 10/10] Add constants for pixel history colors --- qrenderdoc/Windows/PixelHistoryView.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/qrenderdoc/Windows/PixelHistoryView.cpp b/qrenderdoc/Windows/PixelHistoryView.cpp index 9db98d5420..d719974285 100644 --- a/qrenderdoc/Windows/PixelHistoryView.cpp +++ b/qrenderdoc/Windows/PixelHistoryView.cpp @@ -442,6 +442,10 @@ class PixelHistoryItemModel : public QAbstractItemModel } } + const QColor GRAY_BACKGROUND = QColor::fromRgb(235, 235, 235); + const QColor GREEN_BACKGROUND = QColor::fromRgb(235, 255, 235); + const QColor RED_BACKGROUND = QColor::fromRgb(255, 235, 235); + // text backgrounds marking pass/fail if(role == Qt::BackgroundRole && !isColorColumn(col)) { @@ -456,15 +460,14 @@ class PixelHistoryItemModel : public QAbstractItemModel if(mods[0].directShaderWrite && mods[0].preMod.col.uintValue == mods[0].postMod.col.uintValue) - return QBrush(QColor::fromRgb(235, 235, 235)); + return QBrush(GRAY_BACKGROUND); - return passed ? QBrush(QColor::fromRgb(235, 255, 235)) - : QBrush(QColor::fromRgb(255, 235, 235)); + return passed ? QBrush(GREEN_BACKGROUND) : QBrush(RED_BACKGROUND); } else { if(!getMod(index).Passed()) - return QBrush(QColor::fromRgb(255, 235, 235)); + return QBrush(RED_BACKGROUND); } } @@ -472,8 +475,7 @@ class PixelHistoryItemModel : public QAbstractItemModel // ensure contrast with all UI themes if(role == Qt::ForegroundRole && !isColorColumn(col)) { - QColor textColor = - contrastingColor(QColor::fromRgb(235, 235, 235), m_Palette.color(QPalette::Text)); + QColor textColor = contrastingColor(GRAY_BACKGROUND, m_Palette.color(QPalette::Text)); if(isEvent(index)) { return QBrush(textColor);