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; diff --git a/qrenderdoc/Windows/PixelHistoryView.cpp b/qrenderdoc/Windows/PixelHistoryView.cpp index 64a7c23540..d719974285 100644 --- a/qrenderdoc/Windows/PixelHistoryView.cpp +++ b/qrenderdoc/Windows/PixelHistoryView.cpp @@ -39,6 +39,24 @@ struct EventTag Q_DECLARE_METATYPE(EventTag); +enum +{ + COL_EVENT, + COL_TEX_BEFORE, + COL_TEX_BEFORE_COLOR, + COL_SHADER_OUT, + 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, +}; + class PixelHistoryItemModel : public QAbstractItemModel { public: @@ -71,6 +89,20 @@ class PixelHistoryItemModel : public QAbstractItemModel } } + static bool isColorColumn(int column) + { + switch(column) + { + 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; + } + } + void setHistory(const rdcarray &history) { m_ModList.reserve(history.count()); @@ -144,7 +176,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 +187,36 @@ class PixelHistoryItemModel : public QAbstractItemModel QVariant headerData(int section, Qt::Orientation orientation, int role) const override { - if(orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0) - return lit("Event"); + if(orientation == Qt::Horizontal && role == Qt::DisplayRole) + { + QString result; + 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_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; + } + 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 && (section == 2 || section == 4)) + if(orientation == Qt::Horizontal && role == Qt::SizeHintRole && isColorColumn(section)) return QSize(18, 0); return QVariant(); @@ -172,7 +229,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 +237,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 +247,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)) { @@ -291,62 +348,106 @@ class PixelHistoryItemModel : public QAbstractItemModel } } - // pre mod/shader out text - if(col == 1) + 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 || col == COL_SHADER_OUT_2 || + col == COL_BLEND_SRC) { return tr("Tex Before\n\n") + modString(getMods(index).first().preMod); } - else + else if(col == COL_TEX_AFTER || col == COL_BLEND_DST) + { + 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 || col == COL_SHADER_OUT_2) { 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 == 3) - { - if(isEvent(index)) - return tr("Tex After\n\n") + modString(getMods(index).last().postMod); - else + 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_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); + } } } if(role == Qt::BackgroundRole && (m_IsDepth || m_IsFloat)) { - // pre mod color - if(col == 2) + if(isEvent(index)) { - if(isEvent(index)) + if(col == COL_TEX_BEFORE_COLOR || col == COL_SHADER_OUT_COLOR || + col == COL_SHADER_OUT_2_COLOR || col == COL_BLEND_SRC_COLOR) { return backgroundBrush(getMods(index).first().preMod); } - else + else if(col == COL_TEX_AFTER_COLOR || col == COL_BLEND_DST_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 || 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 == 4) - { - if(isEvent(index)) - return backgroundBrush(getMods(index).last().postMod); - else + 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); + } } } + 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 && (col == 0 || col == 1 || col == 3)) + if(role == Qt::BackgroundRole && !isColorColumn(col)) { // rest if(isEvent(index)) @@ -359,24 +460,22 @@ 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); } } // 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)); + QColor textColor = contrastingColor(GRAY_BACKGROUND, m_Palette.color(QPalette::Text)); if(isEvent(index)) { return QBrush(textColor); @@ -639,11 +738,36 @@ 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_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_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); + + // 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); + 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); + + ui->events->header()->setContextMenuPolicy(Qt::CustomContextMenu); + QObject::connect(ui->events->header(), &QHeaderView::customContextMenuRequested, this, + &PixelHistoryView::events_contextMenu); m_Ctx.AddCaptureViewer(this); } @@ -802,8 +926,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); @@ -819,6 +954,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)); @@ -848,8 +990,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); } 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; diff --git a/renderdoc/api/replay/data_types.h b/renderdoc/api/replay/data_types.h index 3dbb1f1b7f..2423a486d1 100644 --- a/renderdoc/api/replay/data_types.h +++ b/renderdoc/api/replay/data_types.h @@ -2100,12 +2100,13 @@ 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 && 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 && + depthTestFailed == o.depthTestFailed && stencilTestFailed == o.stencilTestFailed; } bool operator<(const PixelModification &o) const { @@ -2123,6 +2124,12 @@ struct PixelModification return preMod < o.preMod; if(!(shaderOut == o.shaderOut)) 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)) @@ -2175,6 +2182,21 @@ 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 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 77f436b73f..efa940f10b 100644 --- a/renderdoc/driver/d3d11/d3d11_pixelhistory.cpp +++ b/renderdoc/driver/d3d11/d3d11_pixelhistory.cpp @@ -1940,6 +1940,9 @@ 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(); + mod.blendSrc.SetInvalid(); + mod.blendDst.SetInvalid(); } } @@ -2316,6 +2319,9 @@ 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(); + 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 515608be3e..648f81805a 100644 --- a/renderdoc/driver/gl/gl_pixelhistory.cpp +++ b/renderdoc/driver/gl/gl_pixelhistory.cpp @@ -1303,6 +1303,9 @@ std::map QueryNumFragmentsByEvent( numFragments = history[i].shaderOut.stencil; 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); @@ -1587,6 +1590,9 @@ void QueryShaderOutPerFragment(WrappedOpenGL *driver, GLReplay *replay, int(historyIndex - history.begin())); 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 500ef7b28a..dfbe367477 100644 --- a/renderdoc/driver/vulkan/vk_pixelhistory.cpp +++ b/renderdoc/driver/vulkan/vk_pixelhistory.cpp @@ -3972,6 +3972,9 @@ rdcarray VulkanReplay::PixelHistory(rdcarray even mod.preMod.SetInvalid(); mod.postMod.SetInvalid(); mod.shaderOut.SetInvalid(); + mod.shaderOutDualSrc.SetInvalid(); + mod.blendSrc.SetInvalid(); + mod.blendDst.SetInvalid(); h++; continue; } @@ -3999,6 +4002,9 @@ 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(); + mod.blendSrc.SetInvalid(); + mod.blendDst.SetInvalid(); bool someFragsClipped = (fragsClipped < frags); mod.primitiveID = someFragsClipped; // Draws in secondary command buffers will fail this check, @@ -4145,6 +4151,11 @@ rdcarray VulkanReplay::PixelHistory(rdcarray even { history[h].preMod = history[h - 1].postMod; } + + 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 058149e3bb..4fd593c975 100644 --- a/renderdoc/replay/renderdoc_serialise.inl +++ b/renderdoc/replay/renderdoc_serialise.inl @@ -893,6 +893,9 @@ 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); @@ -906,7 +909,7 @@ void DoSerialise(SerialiserType &ser, PixelModification &el) SERIALISE_MEMBER(stencilTestFailed); SERIALISE_MEMBER(predicationSkipped); - SIZE_CHECK(100); + SIZE_CHECK(172); } template