Implement baseline mesh shader on D3D12

This commit is contained in:
baldurk
2023-08-28 11:11:59 +01:00
parent 5ad3e67a2d
commit b0c97182f6
25 changed files with 1861 additions and 448 deletions
File diff suppressed because it is too large Load Diff
@@ -65,6 +65,7 @@ private slots:
void on_showEmpty_toggled(bool checked);
void on_exportHTML_clicked();
void on_meshView_clicked();
void on_msMeshButton_clicked();
void on_iaLayouts_itemActivated(RDTreeWidgetItem *item, int column);
void on_iaBuffers_itemActivated(RDTreeWidgetItem *item, int column);
void on_iaLayouts_mouseMove(QMouseEvent *event);
@@ -88,6 +89,9 @@ private:
PipelineStateViewer &m_Common;
ComputeDebugSelector *m_ComputeDebugSelector;
void setOldMeshPipeFlow();
void setNewMeshPipeFlow();
void setShaderState(const rdcarray<D3D12Pipe::RootSignatureRange> &rootElements,
const D3D12Pipe::Shader &stage, RDLabel *shader, RDLabel *rootSig,
RDTreeWidget *tex, RDTreeWidget *samp, RDTreeWidget *cbuffer,
@@ -129,4 +133,6 @@ private:
QList<RDTreeWidgetItem *> m_VBNodes;
// list of empty VB nodes that shouldn't be highlighted on hover
QList<RDTreeWidgetItem *> m_EmptyNodes;
bool m_MeshPipe = false;
};
@@ -4096,6 +4096,882 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="AS">
<attribute name="title">
<string>Amplification Shader</string>
</attribute>
<layout class="QVBoxLayout" name="asverticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="asShaderGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Shader</string>
</property>
<layout class="QHBoxLayout" name="asHorizontalLayout1">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="asShaderControlsFrame">
<layout class="QHBoxLayout" name="asHorizontalLayout2">
<property name="spacing">
<number>4</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="RDLabel" name="asRootSig">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
</widget>
</item>
<item>
<widget class="RDLabel" name="asShader">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="asShaderViewButton">
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="toolTip">
<string>Open Shader Source</string>
</property>
<property name="text">
<string>View</string>
</property>
<property name="icon">
<iconset resource="../../Resources/resources.qrc">
<normaloff>:/action.png</normaloff>:/action.png</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="asShaderEditButton">
<property name="toolTip">
<string>Edit Shader</string>
</property>
<property name="text">
<string>Edit</string>
</property>
<property name="icon">
<iconset resource="../../Resources/resources.qrc">
<normaloff>:/page_white_edit.png</normaloff>:/page_white_edit.png</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::MenuButtonPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="asShaderSaveButton">
<property name="toolTip">
<string>Save Shader DXBC</string>
</property>
<property name="text">
<string>Save</string>
</property>
<property name="icon">
<iconset resource="../../Resources/resources.qrc">
<normaloff>:/save.png</normaloff>:/save.png</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="asHorizontalSpacer1">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QScrollArea" name="asScroll">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="asScrollContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>868</width>
<height>452</height>
</rect>
</property>
<layout class="QVBoxLayout" name="asVerticalLayout3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="CollapseGroupBox" name="asResGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Resources</string>
</property>
<layout class="QHBoxLayout" name="asHorizontalLayout4">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="RDTreeWidget" name="asResources">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<attribute name="headerStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="CollapseGroupBox" name="asUAVGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>UAVs</string>
</property>
<layout class="QHBoxLayout" name="asUAVLayout">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="RDTreeWidget" name="asUAVs">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<attribute name="headerStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="CollapseGroupBox" name="asSamplerGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Samplers</string>
</property>
<layout class="QHBoxLayout" name="asHorizontalLayout5">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="RDTreeWidget" name="asSamplers">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<attribute name="headerStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="CollapseGroupBox" name="asCBufferGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Constant Buffers</string>
</property>
<layout class="QHBoxLayout" name="asHorizontalLayout6">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="RDTreeWidget" name="asCBuffers">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<attribute name="headerStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="asVerticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="MS">
<attribute name="title">
<string>Mesh Shader</string>
</attribute>
<layout class="QVBoxLayout" name="msverticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="msShaderGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Shader</string>
</property>
<layout class="QHBoxLayout" name="msHorizontalLayout1">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="msShaderControlsFrame">
<layout class="QHBoxLayout" name="msHorizontalLayout2">
<property name="spacing">
<number>4</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="RDLabel" name="msRootSig">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
</widget>
</item>
<item>
<widget class="RDLabel" name="msShader">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="msShaderViewButton">
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="toolTip">
<string>Open Shader Source</string>
</property>
<property name="text">
<string>View</string>
</property>
<property name="icon">
<iconset resource="../../Resources/resources.qrc">
<normaloff>:/action.png</normaloff>:/action.png</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="msShaderEditButton">
<property name="toolTip">
<string>Edit Shader</string>
</property>
<property name="text">
<string>Edit</string>
</property>
<property name="icon">
<iconset resource="../../Resources/resources.qrc">
<normaloff>:/page_white_edit.png</normaloff>:/page_white_edit.png</iconset>
</property>
<property name="popupMode">
<enum>QToolButton::MenuButtonPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="msShaderSaveButton">
<property name="toolTip">
<string>Save Shader DXBC</string>
</property>
<property name="text">
<string>Save</string>
</property>
<property name="icon">
<iconset resource="../../Resources/resources.qrc">
<normaloff>:/save.png</normaloff>:/save.png</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QToolButton" name="msMeshButton">
<property name="toolTip">
<string>View Mesh</string>
</property>
<property name="text">
<string>View Mesh</string>
</property>
<property name="icon">
<iconset resource="../../Resources/resources.qrc">
<normaloff>:/draw_vertex.png</normaloff>:/draw_vertex.png</iconset>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextBesideIcon</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="msTopoLabel">
<property name="text">
<string> Output Topology: </string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="msTopology">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="msHorizontalSpacer1">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QScrollArea" name="msScroll">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="msScrollContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>868</width>
<height>452</height>
</rect>
</property>
<layout class="QVBoxLayout" name="msVerticalLayout3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="CollapseGroupBox" name="msResGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Resources</string>
</property>
<layout class="QHBoxLayout" name="msHorizontalLayout4">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="RDTreeWidget" name="msResources">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<attribute name="headerStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="CollapseGroupBox" name="msUAVGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>UAVs</string>
</property>
<layout class="QHBoxLayout" name="msUAVLayout">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="RDTreeWidget" name="msUAVs">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<attribute name="headerStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="CollapseGroupBox" name="msSamplerGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Samplers</string>
</property>
<layout class="QHBoxLayout" name="msHorizontalLayout5">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="RDTreeWidget" name="msSamplers">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<attribute name="headerStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="CollapseGroupBox" name="msCBufferGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Constant Buffers</string>
</property>
<layout class="QHBoxLayout" name="msHorizontalLayout6">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="RDTreeWidget" name="msCBuffers">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<attribute name="headerStretchLastSection">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="msVerticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::MinimumExpanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
+13 -1
View File
@@ -119,7 +119,9 @@ bool PipeState::IsD3D12Stage(ShaderStage stage) const
case ShaderStage::Hull:
case ShaderStage::Geometry:
case ShaderStage::Pixel:
case ShaderStage::Compute: return true;
case ShaderStage::Compute:
case ShaderStage::Amplification:
case ShaderStage::Mesh: return true;
default: return false;
}
}
@@ -187,6 +189,10 @@ const D3D12Pipe::Shader &PipeState::GetD3D12Stage(ShaderStage stage) const
return m_D3D12->pixelShader;
if(stage == ShaderStage::Compute)
return m_D3D12->computeShader;
if(stage == ShaderStage::Amplification)
return m_D3D12->ampShader;
if(stage == ShaderStage::Mesh)
return m_D3D12->meshShader;
RENDERDOC_LogMessage(LogType::Error, "PIPE", __FILE__, __LINE__, "Error - invalid stage");
return m_D3D12->computeShader;
@@ -315,6 +321,8 @@ const ShaderBindpointMapping &PipeState::GetBindpointMapping(ShaderStage stage)
case ShaderStage::Geometry: return m_D3D12->geometryShader.bindpointMapping;
case ShaderStage::Pixel: return m_D3D12->pixelShader.bindpointMapping;
case ShaderStage::Compute: return m_D3D12->computeShader.bindpointMapping;
case ShaderStage::Amplification: return m_D3D12->ampShader.bindpointMapping;
case ShaderStage::Mesh: return m_D3D12->meshShader.bindpointMapping;
default: break;
}
}
@@ -380,6 +388,8 @@ const ShaderReflection *PipeState::GetShaderReflection(ShaderStage stage) const
case ShaderStage::Geometry: return m_D3D12->geometryShader.reflection;
case ShaderStage::Pixel: return m_D3D12->pixelShader.reflection;
case ShaderStage::Compute: return m_D3D12->computeShader.reflection;
case ShaderStage::Amplification: return m_D3D12->ampShader.reflection;
case ShaderStage::Mesh: return m_D3D12->meshShader.reflection;
default: break;
}
}
@@ -502,6 +512,8 @@ ResourceId PipeState::GetShader(ShaderStage stage) const
case ShaderStage::Geometry: return m_D3D12->geometryShader.resourceId;
case ShaderStage::Pixel: return m_D3D12->pixelShader.resourceId;
case ShaderStage::Compute: return m_D3D12->computeShader.resourceId;
case ShaderStage::Amplification: return m_D3D12->ampShader.resourceId;
case ShaderStage::Mesh: return m_D3D12->meshShader.resourceId;
default: break;
}
}
@@ -24,9 +24,90 @@
#include "d3d12_command_list.h"
template <typename SerialiserType>
bool WrappedID3D12GraphicsCommandList::Serialise_DispatchMesh(SerialiserType &ser,
UINT ThreadGroupCountX,
UINT ThreadGroupCountY,
UINT ThreadGroupCountZ)
{
ID3D12GraphicsCommandList6 *pCommandList = this;
SERIALISE_ELEMENT(pCommandList);
SERIALISE_ELEMENT(ThreadGroupCountX).Important();
SERIALISE_ELEMENT(ThreadGroupCountY).Important();
SERIALISE_ELEMENT(ThreadGroupCountZ).Important();
SERIALISE_CHECK_READ_ERRORS();
if(IsReplayingAndReading())
{
if(GetWrapped(pCommandList)->GetReal6() == NULL)
{
SET_ERROR_RESULT(m_Cmd->m_FailedReplayResult, ResultCode::APIHardwareUnsupported,
"Capture requires ID3D12GraphicsCommandList6 which isn't available");
return false;
}
if(m_pDevice->GetOpts7().MeshShaderTier == D3D12_MESH_SHADER_TIER_NOT_SUPPORTED)
{
SET_ERROR_RESULT(m_Cmd->m_FailedReplayResult, ResultCode::APIHardwareUnsupported,
"Capture requires mesh shading support which isn't available");
return false;
}
m_Cmd->m_LastCmdListID = GetResourceManager()->GetOriginalID(GetResID(pCommandList));
if(IsActiveReplaying(m_State))
{
if(m_Cmd->InRerecordRange(m_Cmd->m_LastCmdListID))
{
ID3D12GraphicsCommandListX *list = m_Cmd->RerecordCmdList(m_Cmd->m_LastCmdListID);
uint32_t eventId = m_Cmd->HandlePreCallback(list, ActionFlags::MeshDispatch);
Unwrap6(list)->DispatchMesh(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ);
if(eventId && m_Cmd->m_ActionCallback->PostDraw(eventId, list))
{
Unwrap6(list)->DispatchMesh(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ);
m_Cmd->m_ActionCallback->PostRedraw(eventId, list);
}
}
}
else
{
Unwrap6(pCommandList)->DispatchMesh(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ);
m_Cmd->AddEvent();
ActionDescription action;
action.dispatchDimension[0] = ThreadGroupCountX;
action.dispatchDimension[1] = ThreadGroupCountY;
action.dispatchDimension[2] = ThreadGroupCountZ;
action.flags |= ActionFlags::MeshDispatch;
m_Cmd->AddAction(action);
}
}
return true;
}
void STDMETHODCALLTYPE WrappedID3D12GraphicsCommandList::DispatchMesh(UINT ThreadGroupCountX,
UINT ThreadGroupCountY,
UINT ThreadGroupCountZ)
{
RDCERR("DispatchMesh called but mesh shading is not supported!");
SERIALISE_TIME_CALL(m_pList6->DispatchMesh(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ));
if(IsCaptureMode(m_State))
{
CACHE_THREAD_SERIALISER();
ser.SetActionChunk();
SCOPED_SERIALISE_CHUNK(D3D12Chunk::List_DispatchMesh);
Serialise_DispatchMesh(ser, ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ);
m_ListRecord->AddChunk(scope.Get(m_ListRecord->cmdInfo->alloc));
}
}
INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12GraphicsCommandList, DispatchMesh,
UINT ThreadGroupCountX, UINT ThreadGroupCountY,
UINT ThreadGroupCountZ);
@@ -3753,6 +3753,37 @@ void WrappedID3D12GraphicsCommandList::FinaliseExecuteIndirectEvents(BakedCmdLis
break;
}
case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH:
{
D3D12_DISPATCH_MESH_ARGUMENTS *args = (D3D12_DISPATCH_MESH_ARGUMENTS *)data;
data += sizeof(D3D12_DISPATCH_MESH_ARGUMENTS);
curAction.dispatchDimension[0] = args->ThreadGroupCountX;
curAction.dispatchDimension[1] = args->ThreadGroupCountY;
curAction.dispatchDimension[2] = args->ThreadGroupCountZ;
curAction.flags |= ActionFlags::MeshDispatch | ActionFlags::Indirect;
curAction.customName =
StringFormat::Fmt("[%u] arg%u: IndirectDispatchMesh(<%u, %u, %u>)", i, a,
curAction.dispatchDimension[0], curAction.dispatchDimension[1],
curAction.dispatchDimension[2]);
fakeChunk->name = curAction.customName;
structuriser.Serialise("ArgumentData"_lit, *args).Important();
// if this is the first action of the indirect, we could have picked up previous
// non-indirect events in this action, so the EID will be higher than we expect. Just
// assign the action's EID
eid = curAction.eventId;
m_Cmd->AddUsage(state, actions[idx]);
// advance
idx++;
eid++;
break;
}
case D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT:
{
size_t argSize = sizeof(uint32_t) * arg.Constant.Num32BitValuesToSet;
@@ -4155,6 +4186,7 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ExecuteIndirect(
switch(arg.Type)
{
case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH:
case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH:
case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED:
case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW:
{
+36 -18
View File
@@ -899,6 +899,9 @@ bool WrappedID3D12CommandQueue::ProcessChunk(ReadSerialiser &ser, D3D12Chunk chu
ser, D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED);
break;
case D3D12Chunk::List_Barrier: ret = m_ReplayList->Serialise_Barrier(ser, 0, NULL); break;
case D3D12Chunk::List_DispatchMesh:
ret = m_ReplayList->Serialise_DispatchMesh(ser, 0, 0, 0);
break;
case D3D12Chunk::PushMarker: ret = m_ReplayList->Serialise_BeginEvent(ser, 0, NULL, 0); break;
case D3D12Chunk::PopMarker: ret = m_ReplayList->Serialise_EndEvent(ser); break;
@@ -1761,6 +1764,7 @@ uint32_t D3D12CommandData::HandlePreCallback(ID3D12GraphicsCommandListX *list, A
switch(type)
{
case ActionFlags::MeshDispatch:
case ActionFlags::Drawcall:
{
m_ActionCallback->PreDraw(eventId, list);
@@ -2076,7 +2080,7 @@ void D3D12CommandData::AddUsage(const D3D12RenderState &state, D3D12ActionTreeNo
uint32_t eid = a.eventId;
ActionFlags DrawMask = ActionFlags::Drawcall | ActionFlags::Dispatch;
ActionFlags DrawMask = ActionFlags::Drawcall | ActionFlags::MeshDispatch | ActionFlags::Dispatch;
if(!(a.flags & DrawMask))
return;
@@ -2108,11 +2112,22 @@ void D3D12CommandData::AddUsage(const D3D12RenderState &state, D3D12ActionTreeNo
if(pipe && pipe->IsGraphics())
{
D3D12_SHADER_BYTECODE *srcArr[] = {&pipe->graphics->VS, &pipe->graphics->HS,
&pipe->graphics->DS, &pipe->graphics->GS,
&pipe->graphics->PS};
for(size_t stage = 0; stage < 5; stage++)
D3D12_SHADER_BYTECODE *srcArr[] = {
&pipe->graphics->VS,
&pipe->graphics->HS,
&pipe->graphics->DS,
&pipe->graphics->GS,
&pipe->graphics->PS,
// compute
NULL,
&pipe->graphics->AS,
&pipe->graphics->MS,
};
for(size_t stage = 0; stage < ARRAY_COUNT(srcArr); stage++)
{
if(!srcArr[stage])
continue;
WrappedID3D12Shader *sh = (WrappedID3D12Shader *)srcArr[stage]->pShaderBytecode;
if(sh)
@@ -2124,21 +2139,24 @@ void D3D12CommandData::AddUsage(const D3D12RenderState &state, D3D12ActionTreeNo
actionNode.resourceUsage.push_back(
make_rdcpair(state.ibuffer.buf, EventUsage(eid, ResourceUsage::IndexBuffer)));
for(size_t i = 0; i < state.vbuffers.size(); i++)
if(a.flags & ActionFlags::Drawcall)
{
if(state.vbuffers[i].buf != ResourceId())
actionNode.resourceUsage.push_back(
make_rdcpair(state.vbuffers[i].buf, EventUsage(eid, ResourceUsage::VertexBuffer)));
}
for(size_t i = 0; i < state.vbuffers.size(); i++)
{
if(state.vbuffers[i].buf != ResourceId())
actionNode.resourceUsage.push_back(
make_rdcpair(state.vbuffers[i].buf, EventUsage(eid, ResourceUsage::VertexBuffer)));
}
for(size_t i = 0; i < state.streamouts.size(); i++)
{
if(state.streamouts[i].buf != ResourceId())
actionNode.resourceUsage.push_back(
make_rdcpair(state.streamouts[i].buf, EventUsage(eid, ResourceUsage::StreamOut)));
if(state.streamouts[i].countbuf != ResourceId())
actionNode.resourceUsage.push_back(
make_rdcpair(state.streamouts[i].countbuf, EventUsage(eid, ResourceUsage::StreamOut)));
for(size_t i = 0; i < state.streamouts.size(); i++)
{
if(state.streamouts[i].buf != ResourceId())
actionNode.resourceUsage.push_back(
make_rdcpair(state.streamouts[i].buf, EventUsage(eid, ResourceUsage::StreamOut)));
if(state.streamouts[i].countbuf != ResourceId())
actionNode.resourceUsage.push_back(make_rdcpair(
state.streamouts[i].countbuf, EventUsage(eid, ResourceUsage::StreamOut)));
}
}
rdcarray<ResourceId> rts = state.GetRTVIDs();
+32 -22
View File
@@ -399,6 +399,10 @@ bool D3D12InitParams::IsSupportedVersion(uint64_t ver)
if(ver == 0xF)
return true;
// 0x10 -> 0x11 - Expanded PSO desc is serialised with amplification and mesh shader descs
if(ver == 0x10)
return true;
return false;
}
@@ -865,8 +869,8 @@ ShaderStageMask ConvertVisibility(D3D12_SHADER_VISIBILITY ShaderVisibility)
case D3D12_SHADER_VISIBILITY_DOMAIN: return ShaderStageMask::Domain;
case D3D12_SHADER_VISIBILITY_GEOMETRY: return ShaderStageMask::Geometry;
case D3D12_SHADER_VISIBILITY_PIXEL: return ShaderStageMask::Pixel;
case D3D12_SHADER_VISIBILITY_AMPLIFICATION:
case D3D12_SHADER_VISIBILITY_MESH:
case D3D12_SHADER_VISIBILITY_AMPLIFICATION: return ShaderStageMask::Amplification;
case D3D12_SHADER_VISIBILITY_MESH: return ShaderStageMask::Mesh;
default: RDCERR("Unexpected visibility %u", ShaderVisibility); break;
}
@@ -1263,6 +1267,8 @@ D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC::D3D12_EXPANDED_PIPELINE_STATE_STREAM_
RDCEraseEl(GS);
RDCEraseEl(PS);
RDCEraseEl(CS);
RDCEraseEl(AS);
RDCEraseEl(MS);
NodeMask = 0;
RDCEraseEl(CachedPSO);
Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
@@ -1387,6 +1393,18 @@ D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC::D3D12_EXPANDED_PIPELINE_STATE_STREAM_
ITER_ADV(D3D12_SHADER_BYTECODE);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_AS:
{
AS = ptr->data.shader;
ITER_ADV(D3D12_SHADER_BYTECODE);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MS:
{
MS = ptr->data.shader;
ITER_ADV(D3D12_SHADER_BYTECODE);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_STREAM_OUTPUT:
{
StreamOutput = ptr->data.StreamOutput;
@@ -1538,26 +1556,6 @@ D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC::D3D12_EXPANDED_PIPELINE_STATE_STREAM_
ITER_ADV(D3D12_VIEW_INSTANCING_DESC);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_AS:
{
if(ptr->data.shader.BytecodeLength > 0)
{
RDCERR("AS passed to D3D12_PIPELINE_STATE_STREAM_DESC but mesh shaders not supported");
errored = true;
}
ITER_ADV(D3D12_SHADER_BYTECODE);
break;
}
case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MS:
{
if(ptr->data.shader.BytecodeLength > 0)
{
RDCERR("MS passed to D3D12_PIPELINE_STATE_STREAM_DESC but mesh shaders not supported");
errored = true;
}
ITER_ADV(D3D12_SHADER_BYTECODE);
break;
}
default:
{
RDCERR("Unknown subobject type %d", obj->type);
@@ -1606,6 +1604,8 @@ D3D12_PACKED_PIPELINE_STATE_STREAM_DESC &D3D12_PACKED_PIPELINE_STATE_STREAM_DESC
m_GraphicsStreamData.CachedPSO = expanded.CachedPSO;
m_GraphicsStreamData.Flags = expanded.Flags;
m_GraphicsStreamData.ViewInstancing = expanded.ViewInstancing;
AS = expanded.AS;
MS = expanded.MS;
byte *ptr = m_GraphicsStreamData.VariableVersionedData;
const byte *start = ptr;
@@ -1732,6 +1732,16 @@ D3D12_PACKED_PIPELINE_STATE_STREAM_DESC &D3D12_PACKED_PIPELINE_STATE_STREAM_DESC
WRITE_VERSIONED_SUBOJBECT(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1, desc1);
}
if(expanded.AS.BytecodeLength > 0)
{
WRITE_VERSIONED_SUBOJBECT(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_AS, expanded.AS);
}
if(expanded.MS.BytecodeLength > 0)
{
WRITE_VERSIONED_SUBOJBECT(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MS, expanded.MS);
}
m_VariableVersionedDataLength = ptr - start;
}
+21 -4
View File
@@ -567,6 +567,8 @@ struct D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC
D3D12_SHADER_BYTECODE DS = {};
D3D12_SHADER_BYTECODE HS = {};
D3D12_SHADER_BYTECODE GS = {};
D3D12_SHADER_BYTECODE AS = {};
D3D12_SHADER_BYTECODE MS = {};
D3D12_STREAM_OUTPUT_DESC StreamOutput = {};
D3D12_BLEND_DESC BlendState = {};
UINT SampleMask = 0;
@@ -630,12 +632,18 @@ public:
}
}
size_t GetStageCount() { return 6; }
size_t GetStageCount() { return 8; }
D3D12_SHADER_BYTECODE &GetStage(size_t i)
{
D3D12_SHADER_BYTECODE *stages[] = {
&m_GraphicsStreamData.VS, &m_GraphicsStreamData.HS, &m_GraphicsStreamData.DS,
&m_GraphicsStreamData.GS, &m_GraphicsStreamData.PS, &m_ComputeStreamData.CS,
&m_GraphicsStreamData.VS,
&m_GraphicsStreamData.HS,
&m_GraphicsStreamData.DS,
&m_GraphicsStreamData.GS,
&m_GraphicsStreamData.PS,
&m_ComputeStreamData.CS,
&AS,
&MS,
};
return *stages[i];
}
@@ -694,9 +702,16 @@ private:
// depth-stencil is versioned for separate stencil masks
sizeof(D3D12_DEPTH_STENCIL_DESC2) + sizeof(void *) +
// rasterization is versioned for line raster mode
sizeof(D3D12_RASTERIZER_DESC2) + sizeof(void *)];
sizeof(D3D12_RASTERIZER_DESC2) + sizeof(void *) +
// AS ...
sizeof(D3D12_SHADER_BYTECODE) + sizeof(void *) +
// ... and MS are optional
sizeof(D3D12_SHADER_BYTECODE) + sizeof(void *)];
} m_GraphicsStreamData;
D3D12_SHADER_BYTECODE AS = {};
D3D12_SHADER_BYTECODE MS = {};
size_t m_VariableVersionedDataLength;
struct
@@ -885,6 +900,7 @@ DECLARE_REFLECTION_STRUCT(D3D12_WRITEBUFFERIMMEDIATE_PARAMETER);
DECLARE_REFLECTION_STRUCT(D3D12_DRAW_ARGUMENTS);
DECLARE_REFLECTION_STRUCT(D3D12_DRAW_INDEXED_ARGUMENTS);
DECLARE_REFLECTION_STRUCT(D3D12_DISPATCH_ARGUMENTS);
DECLARE_REFLECTION_STRUCT(D3D12_DISPATCH_MESH_ARGUMENTS);
DECLARE_REFLECTION_STRUCT(D3D12_RENDER_PASS_BEGINNING_ACCESS_CLEAR_PARAMETERS);
DECLARE_REFLECTION_STRUCT(D3D12_RENDER_PASS_BEGINNING_ACCESS);
DECLARE_REFLECTION_STRUCT(D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_SUBRESOURCE_PARAMETERS);
@@ -1041,5 +1057,6 @@ enum class D3D12Chunk : uint32_t
List_RSSetDepthBias,
List_IASetIndexBufferStripCutValue,
List_Barrier,
List_DispatchMesh,
Max,
};
+64 -11
View File
@@ -52,6 +52,11 @@ rdcarray<GPUCounter> D3D12Replay::EnumerateCounters()
ret.push_back(GPUCounter::GSInvocations);
ret.push_back(GPUCounter::PSInvocations);
ret.push_back(GPUCounter::CSInvocations);
if(m_pDevice->GetOpts9().MeshShaderPipelineStatsSupported)
{
ret.push_back(GPUCounter::ASInvocations);
ret.push_back(GPUCounter::MSInvocations);
}
if(m_pAMDCounters)
{
@@ -192,6 +197,20 @@ CounterDescription D3D12Replay::DescribeCounter(GPUCounter counterID)
desc.resultType = CompType::UInt;
desc.unit = CounterUnit::Absolute;
break;
case GPUCounter::ASInvocations:
desc.name = "AS Invocations";
desc.description = "Number of times an amplification shader was invoked.";
desc.resultByteWidth = 8;
desc.resultType = CompType::UInt;
desc.unit = CounterUnit::Absolute;
break;
case GPUCounter::MSInvocations:
desc.name = "MS Invocations";
desc.description = "Number of times a mesh shader was invoked.";
desc.resultByteWidth = 8;
desc.resultType = CompType::UInt;
desc.unit = CounterUnit::Absolute;
break;
default:
desc.name = "Unknown";
desc.description = "Unknown counter ID";
@@ -399,10 +418,11 @@ rdcarray<CounterResult> D3D12Replay::FetchCountersAMD(const rdcarray<GPUCounter>
struct D3D12GPUTimerCallback : public D3D12ActionCallback
{
D3D12GPUTimerCallback(WrappedID3D12Device *dev, D3D12Replay *rp, ID3D12QueryHeap *tqh,
ID3D12QueryHeap *psqh, ID3D12QueryHeap *oqh)
D3D12GPUTimerCallback(WrappedID3D12Device *dev, D3D12Replay *rp, D3D12_QUERY_TYPE pipeQueryType,
ID3D12QueryHeap *tqh, ID3D12QueryHeap *psqh, ID3D12QueryHeap *oqh)
: m_pDevice(dev),
m_pReplay(rp),
m_PipeQueryType(pipeQueryType),
m_TimerQueryHeap(tqh),
m_PipeStatsQueryHeap(psqh),
m_OcclusionQueryHeap(oqh),
@@ -420,7 +440,7 @@ struct D3D12GPUTimerCallback : public D3D12ActionCallback
if(cmd->GetType() == D3D12_COMMAND_LIST_TYPE_DIRECT)
{
cmd->BeginQuery(m_OcclusionQueryHeap, D3D12_QUERY_TYPE_OCCLUSION, m_NumStatsQueries);
cmd->BeginQuery(m_PipeStatsQueryHeap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, m_NumStatsQueries);
cmd->BeginQuery(m_PipeStatsQueryHeap, m_PipeQueryType, m_NumStatsQueries);
}
cmd->EndQuery(m_TimerQueryHeap, D3D12_QUERY_TYPE_TIMESTAMP, m_NumTimestampQueries * 2 + 0);
}
@@ -436,7 +456,7 @@ struct D3D12GPUTimerCallback : public D3D12ActionCallback
bool direct = (cmd->GetType() == D3D12_COMMAND_LIST_TYPE_DIRECT);
if(direct)
{
cmd->EndQuery(m_PipeStatsQueryHeap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, m_NumStatsQueries);
cmd->EndQuery(m_PipeStatsQueryHeap, m_PipeQueryType, m_NumStatsQueries);
cmd->EndQuery(m_OcclusionQueryHeap, D3D12_QUERY_TYPE_OCCLUSION, m_NumStatsQueries);
m_NumStatsQueries++;
@@ -483,6 +503,7 @@ struct D3D12GPUTimerCallback : public D3D12ActionCallback
WrappedID3D12Device *m_pDevice;
D3D12Replay *m_pReplay;
D3D12_QUERY_TYPE m_PipeQueryType;
ID3D12QueryHeap *m_TimerQueryHeap;
ID3D12QueryHeap *m_PipeStatsQueryHeap;
ID3D12QueryHeap *m_OcclusionQueryHeap;
@@ -556,7 +577,7 @@ rdcarray<CounterResult> D3D12Replay::FetchCounters(const rdcarray<GPUCounter> &c
D3D12_RESOURCE_DESC bufDesc;
bufDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
bufDesc.Alignment = 0;
bufDesc.Width = (sizeof(uint64_t) * 3 + sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS)) * maxEID;
bufDesc.Width = (sizeof(uint64_t) * 3 + sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS1)) * maxEID;
bufDesc.Height = 1;
bufDesc.DepthOrArraySize = 1;
bufDesc.MipLevels = 1;
@@ -595,6 +616,17 @@ rdcarray<CounterResult> D3D12Replay::FetchCounters(const rdcarray<GPUCounter> &c
pipestatsQueryDesc.Count = maxEID;
pipestatsQueryDesc.NodeMask = 1;
pipestatsQueryDesc.Type = D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS;
D3D12_QUERY_TYPE pipeQueryType = D3D12_QUERY_TYPE_PIPELINE_STATISTICS;
const bool meshQueries = d3dCounters.contains(GPUCounter::ASInvocations) ||
d3dCounters.contains(GPUCounter::MSInvocations);
if(meshQueries)
{
pipestatsQueryDesc.Type = D3D12_QUERY_HEAP_TYPE_PIPELINE_STATISTICS1;
pipeQueryType = D3D12_QUERY_TYPE_PIPELINE_STATISTICS1;
}
ID3D12QueryHeap *pipestatsQueryHeap = NULL;
hr = m_pDevice->CreateQueryHeap(&pipestatsQueryDesc, __uuidof(pipestatsQueryHeap),
(void **)&pipestatsQueryHeap);
@@ -632,7 +664,8 @@ rdcarray<CounterResult> D3D12Replay::FetchCounters(const rdcarray<GPUCounter> &c
return ret;
}
D3D12GPUTimerCallback cb(m_pDevice, this, timerQueryHeap, pipestatsQueryHeap, occlusionQueryHeap);
D3D12GPUTimerCallback cb(m_pDevice, this, pipeQueryType, timerQueryHeap, pipestatsQueryHeap,
occlusionQueryHeap);
// replay the events to perform all the queries
m_pDevice->ReplayLog(0, maxEID, eReplay_Full);
@@ -658,10 +691,13 @@ rdcarray<CounterResult> D3D12Replay::FetchCounters(const rdcarray<GPUCounter> &c
bufferOffset += sizeof(uint64_t) * 2 * cb.m_NumTimestampQueries;
list->ResolveQueryData(pipestatsQueryHeap, D3D12_QUERY_TYPE_PIPELINE_STATISTICS, 0,
cb.m_NumStatsQueries, readbackBuf, bufferOffset);
list->ResolveQueryData(pipestatsQueryHeap, pipeQueryType, 0, cb.m_NumStatsQueries, readbackBuf,
bufferOffset);
bufferOffset += sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS) * cb.m_NumStatsQueries;
if(meshQueries)
bufferOffset += sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS1) * cb.m_NumStatsQueries;
else
bufferOffset += sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS) * cb.m_NumStatsQueries;
list->ResolveQueryData(occlusionQueryHeap, D3D12_QUERY_TYPE_OCCLUSION, 0, cb.m_NumStatsQueries,
readbackBuf, bufferOffset);
@@ -692,7 +728,12 @@ rdcarray<CounterResult> D3D12Replay::FetchCounters(const rdcarray<GPUCounter> &c
uint64_t *timestamps = (uint64_t *)data;
data += cb.m_NumTimestampQueries * 2 * sizeof(uint64_t);
D3D12_QUERY_DATA_PIPELINE_STATISTICS *pipelinestats = (D3D12_QUERY_DATA_PIPELINE_STATISTICS *)data;
data += cb.m_NumStatsQueries * sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS);
D3D12_QUERY_DATA_PIPELINE_STATISTICS1 *pipelinestats1 =
(D3D12_QUERY_DATA_PIPELINE_STATISTICS1 *)data;
if(meshQueries)
data += cb.m_NumStatsQueries * sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS1);
else
data += cb.m_NumStatsQueries * sizeof(D3D12_QUERY_DATA_PIPELINE_STATISTICS);
uint64_t *occlusion = (uint64_t *)data;
uint64_t freq;
@@ -703,15 +744,25 @@ rdcarray<CounterResult> D3D12Replay::FetchCounters(const rdcarray<GPUCounter> &c
bool direct = cb.m_Results[i].second;
D3D12_QUERY_DATA_PIPELINE_STATISTICS pipeStats = {};
D3D12_QUERY_DATA_PIPELINE_STATISTICS1 pipeStats1 = {};
uint64_t occl = 0;
// only events on direct lists recorded pipeline stats or occlusion queries
if(direct)
{
pipeStats = *pipelinestats;
if(meshQueries)
{
pipeStats1 = *pipelinestats1;
memcpy(&pipeStats, &pipeStats1, sizeof(pipeStats));
}
else
{
pipeStats = *pipelinestats;
}
occl = *occlusion;
pipelinestats++;
pipelinestats1++;
occlusion++;
}
@@ -742,6 +793,8 @@ rdcarray<CounterResult> D3D12Replay::FetchCounters(const rdcarray<GPUCounter> &c
case GPUCounter::GSInvocations: result.value.u64 = pipeStats.GSInvocations; break;
case GPUCounter::PSInvocations: result.value.u64 = pipeStats.PSInvocations; break;
case GPUCounter::CSInvocations: result.value.u64 = pipeStats.CSInvocations; break;
case GPUCounter::ASInvocations: result.value.u64 = pipeStats1.ASInvocations; break;
case GPUCounter::MSInvocations: result.value.u64 = pipeStats1.MSInvocations; break;
default: break;
}
+5
View File
@@ -965,6 +965,11 @@ rdcpair<ID3D12Resource *, UINT64> D3D12DebugManager::PatchExecuteIndirect(
offset += sizeof(D3D12_DISPATCH_ARGUMENTS);
break;
}
case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH:
{
offset += sizeof(D3D12_DISPATCH_MESH_ARGUMENTS);
break;
}
case D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT:
{
offset += sizeof(uint32_t) * arg.Constant.Num32BitValuesToSet;
+15
View File
@@ -527,6 +527,8 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara
RDCEraseEl(m_D3D12Opts2);
RDCEraseEl(m_D3D12Opts3);
RDCEraseEl(m_D3D12Opts6);
RDCEraseEl(m_D3D12Opts7);
RDCEraseEl(m_D3D12Opts9);
RDCEraseEl(m_D3D12Opts12);
RDCEraseEl(m_D3D12Opts14);
RDCEraseEl(m_D3D12Opts15);
@@ -597,6 +599,14 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara
sizeof(m_D3D12Opts6));
if(hr != S_OK)
RDCEraseEl(m_D3D12Opts6);
hr = m_pDevice->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS7, &m_D3D12Opts7,
sizeof(m_D3D12Opts7));
if(hr != S_OK)
RDCEraseEl(m_D3D12Opts7);
hr = m_pDevice->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS9, &m_D3D12Opts9,
sizeof(m_D3D12Opts9));
if(hr != S_OK)
RDCEraseEl(m_D3D12Opts9);
hr = m_pDevice->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS12, &m_D3D12Opts12,
sizeof(m_D3D12Opts12));
if(hr != S_OK)
@@ -3121,6 +3131,10 @@ HRESULT WrappedID3D12Device::CreatePipeState(D3D12_EXPANDED_PIPELINE_STATE_STREA
graphicsDesc.BlendState = desc.BlendState;
graphicsDesc.SampleMask = desc.SampleMask;
// can't create mesh shaders with old function, so we should not be trying
RDCASSERT(desc.AS.BytecodeLength == 0);
RDCASSERT(desc.MS.BytecodeLength == 0);
// graphicsDesc.RasterizerState = desc.RasterizerState;
{
graphicsDesc.RasterizerState.FillMode = desc.RasterizerState.FillMode;
@@ -4296,6 +4310,7 @@ bool WrappedID3D12Device::ProcessChunk(ReadSerialiser &ser, D3D12Chunk context)
case D3D12Chunk::List_RSSetDepthBias:
case D3D12Chunk::List_IASetIndexBufferStripCutValue:
case D3D12Chunk::List_Barrier:
case D3D12Chunk::List_DispatchMesh:
RDCERR("Unexpected chunk while processing initialisation: %s", ToStr(context).c_str());
return false;
+5 -1
View File
@@ -54,7 +54,7 @@ struct D3D12InitParams
UINT SDKVersion = 0;
// check if a frame capture section version is supported
static const uint64_t CurrentVersion = 0x10;
static const uint64_t CurrentVersion = 0x11;
static bool IsSupportedVersion(uint64_t ver);
};
@@ -790,6 +790,8 @@ private:
D3D12_FEATURE_DATA_D3D12_OPTIONS2 m_D3D12Opts2;
D3D12_FEATURE_DATA_D3D12_OPTIONS3 m_D3D12Opts3;
D3D12_FEATURE_DATA_D3D12_OPTIONS6 m_D3D12Opts6;
D3D12_FEATURE_DATA_D3D12_OPTIONS7 m_D3D12Opts7;
D3D12_FEATURE_DATA_D3D12_OPTIONS9 m_D3D12Opts9;
D3D12_FEATURE_DATA_D3D12_OPTIONS12 m_D3D12Opts12;
D3D12_FEATURE_DATA_D3D12_OPTIONS14 m_D3D12Opts14;
D3D12_FEATURE_DATA_D3D12_OPTIONS15 m_D3D12Opts15;
@@ -825,6 +827,8 @@ public:
const D3D12_FEATURE_DATA_D3D12_OPTIONS2 &GetOpts2() { return m_D3D12Opts2; }
const D3D12_FEATURE_DATA_D3D12_OPTIONS3 &GetOpts3() { return m_D3D12Opts3; }
const D3D12_FEATURE_DATA_D3D12_OPTIONS6 &GetOpts6() { return m_D3D12Opts6; }
const D3D12_FEATURE_DATA_D3D12_OPTIONS7 &GetOpts7() { return m_D3D12Opts7; }
const D3D12_FEATURE_DATA_D3D12_OPTIONS9 &GetOpts9() { return m_D3D12Opts9; }
const D3D12_FEATURE_DATA_D3D12_OPTIONS12 &GetOpts12() { return m_D3D12Opts12; }
const D3D12_FEATURE_DATA_D3D12_OPTIONS14 &GetOpts14() { return m_D3D12Opts14; }
const D3D12_FEATURE_DATA_D3D12_OPTIONS15 &GetOpts15() { return m_D3D12Opts15; }
+8 -3
View File
@@ -634,7 +634,8 @@ void WrappedID3D12Device::ProcessCreatedGraphicsPSO(ID3D12PipelineState *real,
D3D12_SHADER_BYTECODE *shaders[] = {
&wrapped->graphics->VS, &wrapped->graphics->HS, &wrapped->graphics->DS,
&wrapped->graphics->GS, &wrapped->graphics->PS,
&wrapped->graphics->GS, &wrapped->graphics->PS, &wrapped->graphics->AS,
&wrapped->graphics->MS,
};
for(size_t i = 0; i < ARRAY_COUNT(shaders); i++)
@@ -1799,6 +1800,11 @@ bool WrappedID3D12Device::Serialise_CreateCommandSignature(SerialiserType &ser,
wrapped->sig.graphics = false;
break;
}
case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH:
{
wrapped->sig.PackedByteSize += sizeof(D3D12_DISPATCH_MESH_ARGUMENTS);
break;
}
case D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT:
{
wrapped->sig.PackedByteSize +=
@@ -2327,8 +2333,7 @@ HRESULT WrappedID3D12Device::CheckFeatureSupport(D3D12_FEATURE Feature, void *pF
if(FeatureSupportDataSize != sizeof(D3D12_FEATURE_DATA_D3D12_OPTIONS7))
return E_INVALIDARG;
// don't support mesh shading or sampler feedback
opts->MeshShaderTier = D3D12_MESH_SHADER_TIER_NOT_SUPPORTED;
// don't support sampler feedback
opts->SamplerFeedbackTier = D3D12_SAMPLER_FEEDBACK_TIER_NOT_SUPPORTED;
if(dolog)
+20 -5
View File
@@ -64,6 +64,8 @@ bool WrappedID3D12Device::Serialise_CreatePipelineState(SerialiserType &ser,
if(!DXBC::DXBCContainer::IsHashedContainer(sh.pShaderBytecode, sh.BytecodeLength))
DXBC::DXBCContainer::HashContainer((void *)sh.pShaderBytecode, sh.BytecodeLength);
if(DXBC::DXBCContainer::CheckForDXIL(sh.pShaderBytecode, sh.BytecodeLength))
m_UsedDXIL = true;
}
if(m_pDevice2)
@@ -93,8 +95,8 @@ bool WrappedID3D12Device::Serialise_CreatePipelineState(SerialiserType &ser,
new D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC(Descriptor);
D3D12_SHADER_BYTECODE *shaders[] = {
&storedDesc->VS, &storedDesc->HS, &storedDesc->DS,
&storedDesc->GS, &storedDesc->PS, &storedDesc->CS,
&storedDesc->VS, &storedDesc->HS, &storedDesc->DS, &storedDesc->GS,
&storedDesc->PS, &storedDesc->CS, &storedDesc->AS, &storedDesc->MS,
};
AddResource(pPipelineState, ResourceType::PipelineState, "Pipeline State");
@@ -246,7 +248,9 @@ HRESULT WrappedID3D12Device::CreatePipelineState(const D3D12_PIPELINE_STATE_STRE
UsesExtensionUAV(expandedDesc.DS, reg, space) ||
UsesExtensionUAV(expandedDesc.GS, reg, space) ||
UsesExtensionUAV(expandedDesc.PS, reg, space) ||
UsesExtensionUAV(expandedDesc.CS, reg, space))
UsesExtensionUAV(expandedDesc.CS, reg, space) ||
UsesExtensionUAV(expandedDesc.AS, reg, space) ||
UsesExtensionUAV(expandedDesc.MS, reg, space))
{
// don't set initparams until we've seen at least one shader actually created using the
// extensions.
@@ -260,6 +264,17 @@ HRESULT WrappedID3D12Device::CreatePipelineState(const D3D12_PIPELINE_STATE_STRE
}
}
for(const D3D12_SHADER_BYTECODE &sh :
{expandedDesc.VS, expandedDesc.HS, expandedDesc.DS, expandedDesc.GS, expandedDesc.PS,
expandedDesc.CS, expandedDesc.AS, expandedDesc.MS})
{
if(sh.BytecodeLength == 0 || sh.pShaderBytecode == NULL)
continue;
if(DXBC::DXBCContainer::CheckForDXIL(sh.pShaderBytecode, sh.BytecodeLength))
m_UsedDXIL = true;
}
SCOPED_SERIALISE_CHUNK(D3D12Chunk::Device_CreatePipelineState);
Serialise_CreatePipelineState(ser, pDesc, riid, (void **)&wrapped);
@@ -283,8 +298,8 @@ HRESULT WrappedID3D12Device::CreatePipelineState(const D3D12_PIPELINE_STATE_STRE
new D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC(expandedDesc);
D3D12_SHADER_BYTECODE *shaders[] = {
&storedDesc->VS, &storedDesc->HS, &storedDesc->DS,
&storedDesc->GS, &storedDesc->PS, &storedDesc->CS,
&storedDesc->VS, &storedDesc->HS, &storedDesc->DS, &storedDesc->GS,
&storedDesc->PS, &storedDesc->CS, &storedDesc->AS, &storedDesc->MS,
};
for(size_t i = 0; i < ARRAY_COUNT(shaders); i++)
+11 -1
View File
@@ -150,6 +150,7 @@ struct D3D12QuadOverdrawCallback : public D3D12ActionCallback
pipeDesc.SampleDesc.Quality = 0;
bool dxil =
pipeDesc.MS.BytecodeLength > 0 ||
DXBC::DXBCContainer::CheckForDXIL(pipeDesc.VS.pShaderBytecode, pipeDesc.VS.BytecodeLength);
// dxil is stricter about pipeline signatures matching. On D3D11 there's an error but all
@@ -345,6 +346,8 @@ void D3D12Replay::PatchQuadWritePS(D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC &pi
rastFeeding = &pipeDesc.DS;
if(pipeDesc.GS.BytecodeLength > 0)
rastFeeding = &pipeDesc.GS;
if(pipeDesc.MS.BytecodeLength > 0)
rastFeeding = &pipeDesc.MS;
uint32_t hash[4];
DXBC::DXBCContainer::GetHash(hash, rastFeeding->pShaderBytecode, rastFeeding->BytecodeLength);
@@ -1170,6 +1173,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
pipe->Fill(psoDesc);
bool dxil =
psoDesc.MS.BytecodeLength > 0 ||
DXBC::DXBCContainer::CheckForDXIL(psoDesc.VS.pShaderBytecode, psoDesc.VS.BytecodeLength);
ID3DBlob *ps =
@@ -1259,6 +1263,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
BOOL origFrontCCW = psoDesc.RasterizerState.FrontCounterClockwise;
bool dxil =
psoDesc.MS.BytecodeLength > 0 ||
DXBC::DXBCContainer::CheckForDXIL(psoDesc.VS.pShaderBytecode, psoDesc.VS.BytecodeLength);
ID3DBlob *red = m_pDevice->GetShaderCache()->MakeFixedColShader(D3D12ShaderCache::RED, dxil);
@@ -1367,6 +1372,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
pipe->Fill(psoDesc);
bool dxil =
psoDesc.MS.BytecodeLength > 0 ||
DXBC::DXBCContainer::CheckForDXIL(psoDesc.VS.pShaderBytecode, psoDesc.VS.BytecodeLength);
ID3DBlob *ps =
@@ -1522,6 +1528,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
pipe->Fill(psoDesc);
bool dxil =
psoDesc.MS.BytecodeLength > 0 ||
DXBC::DXBCContainer::CheckForDXIL(psoDesc.VS.pShaderBytecode, psoDesc.VS.BytecodeLength);
ID3DBlob *red = m_pDevice->GetShaderCache()->MakeFixedColShader(D3D12ShaderCache::RED, dxil);
@@ -1706,7 +1713,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
const ActionDescription *action = m_pDevice->GetAction(events[0]);
// remove any non-drawcalls, like the pass boundary.
if(!(action->flags & ActionFlags::Drawcall))
if(!(action->flags & (ActionFlags::MeshDispatch | ActionFlags::Drawcall)))
events.erase(0);
else
break;
@@ -1758,6 +1765,8 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
pipeDesc.VS.pShaderBytecode = m_Overlay.MeshVS->GetBufferPointer();
RDCEraseEl(pipeDesc.HS);
RDCEraseEl(pipeDesc.DS);
RDCEraseEl(pipeDesc.AS);
RDCEraseEl(pipeDesc.MS);
pipeDesc.GS.BytecodeLength = m_Overlay.TriangleSizeGS->GetBufferSize();
pipeDesc.GS.pShaderBytecode = m_Overlay.TriangleSizeGS->GetBufferPointer();
pipeDesc.PS.BytecodeLength = m_Overlay.TriangleSizePS->GetBufferSize();
@@ -2231,6 +2240,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De
pipe->Fill(psoDesc);
bool dxil =
psoDesc.MS.BytecodeLength > 0 ||
DXBC::DXBCContainer::CheckForDXIL(psoDesc.VS.pShaderBytecode, psoDesc.VS.BytecodeLength);
ID3DBlob *red = m_pDevice->GetShaderCache()->MakeFixedColShader(D3D12ShaderCache::RED, dxil);
+43 -10
View File
@@ -624,6 +624,8 @@ rdcstr D3D12Replay::DisassembleShader(ResourceId pipeline, const ShaderReflectio
case ShaderStage::Geometry: search = "stage=\"GS\""; break;
case ShaderStage::Pixel: search = "stage=\"PS\""; break;
case ShaderStage::Compute: search = "stage=\"CS\""; break;
case ShaderStage::Amplification: search = "stage=\"AS\""; break;
case ShaderStage::Mesh: search = "stage=\"MS\""; break;
default: return "; Unknown shader stage in shader reflection\n";
}
@@ -1030,12 +1032,14 @@ ShaderStageMask ToShaderStageMask(D3D12_SHADER_VISIBILITY vis)
case D3D12_SHADER_VISIBILITY_DOMAIN: return ShaderStageMask::Domain;
case D3D12_SHADER_VISIBILITY_GEOMETRY: return ShaderStageMask::Geometry;
case D3D12_SHADER_VISIBILITY_PIXEL: return ShaderStageMask::Pixel;
case D3D12_SHADER_VISIBILITY_AMPLIFICATION: return ShaderStageMask::Amplification;
case D3D12_SHADER_VISIBILITY_MESH: return ShaderStageMask::Mesh;
default: return ShaderStageMask::Unknown;
}
}
void D3D12Replay::FillRootElements(uint32_t eventId, const D3D12RenderState::RootSignature &rootSig,
const ShaderBindpointMapping *mappings[(uint32_t)ShaderStage::Count],
const ShaderBindpointMapping *mappings[NumShaderStages],
rdcarray<D3D12Pipe::RootSignatureRange> &rootElements)
{
if(rootSig.rootsig == ResourceId())
@@ -1730,14 +1734,35 @@ void D3D12Replay::SavePipelineState(uint32_t eventId)
}
else if(pipe)
{
D3D12Pipe::Shader *dstArr[] = {&state.vertexShader, &state.hullShader, &state.domainShader,
&state.geometryShader, &state.pixelShader};
D3D12Pipe::Shader *dstArr[] = {
&state.vertexShader,
&state.hullShader,
&state.domainShader,
&state.geometryShader,
&state.pixelShader,
// compute
NULL,
&state.ampShader,
&state.meshShader,
};
D3D12_SHADER_BYTECODE *srcArr[] = {&pipe->graphics->VS, &pipe->graphics->HS, &pipe->graphics->DS,
&pipe->graphics->GS, &pipe->graphics->PS};
D3D12_SHADER_BYTECODE *srcArr[] = {
&pipe->graphics->VS,
&pipe->graphics->HS,
&pipe->graphics->DS,
&pipe->graphics->GS,
&pipe->graphics->PS,
// compute
NULL,
&pipe->graphics->AS,
&pipe->graphics->MS,
};
for(size_t stage = 0; stage < 5; stage++)
for(size_t stage = 0; stage < ARRAY_COUNT(dstArr); stage++)
{
if(!dstArr[stage])
continue;
D3D12Pipe::Shader &dst = *dstArr[stage];
D3D12_SHADER_BYTECODE &src = *srcArr[stage];
@@ -1764,13 +1789,15 @@ void D3D12Replay::SavePipelineState(uint32_t eventId)
// Root Signature
/////////////////////////////////////////////////
{
const ShaderBindpointMapping *mappings[(uint32_t)ShaderStage::Count];
const ShaderBindpointMapping *mappings[NumShaderStages];
mappings[(uint32_t)ShaderStage::Vertex] = &state.vertexShader.bindpointMapping;
mappings[(uint32_t)ShaderStage::Hull] = &state.hullShader.bindpointMapping;
mappings[(uint32_t)ShaderStage::Domain] = &state.domainShader.bindpointMapping;
mappings[(uint32_t)ShaderStage::Geometry] = &state.geometryShader.bindpointMapping;
mappings[(uint32_t)ShaderStage::Pixel] = &state.pixelShader.bindpointMapping;
mappings[(uint32_t)ShaderStage::Compute] = &state.computeShader.bindpointMapping;
mappings[(uint32_t)ShaderStage::Amplification] = &state.ampShader.bindpointMapping;
mappings[(uint32_t)ShaderStage::Mesh] = &state.meshShader.bindpointMapping;
if(pipe && pipe->IsCompute())
{
@@ -3211,7 +3238,7 @@ rdcarray<uint32_t> D3D12Replay::GetPassEvents(uint32_t eventId)
// so we don't actually do anything (init postvs/action overlay)
// but it's useful to have the first part of the pass as part
// of the list
if(start->flags & (ActionFlags::Drawcall | ActionFlags::PassBoundary))
if(start->flags & (ActionFlags::MeshDispatch | ActionFlags::Drawcall | ActionFlags::PassBoundary))
passEvents.push_back(start->eventId);
start = start->next;
@@ -3362,6 +3389,8 @@ void D3D12Replay::BuildShader(ShaderEncoding sourceEncoding, const bytebuf &sour
case ShaderStage::Geometry: profile = "gs_5_1"; break;
case ShaderStage::Pixel: profile = "ps_5_1"; break;
case ShaderStage::Compute: profile = "cs_5_1"; break;
case ShaderStage::Amplification: profile = "as_6_5"; break;
case ShaderStage::Mesh: profile = "ms_6_5"; break;
default:
RDCERR("Unexpected type in BuildShader!");
id = ResourceId();
@@ -3488,7 +3517,7 @@ void D3D12Replay::RefreshDerivedReplacements()
if(pipe->IsGraphics())
{
ResourceId shaders[5];
ResourceId shaders[NumShaderStages];
if(pipe->VS())
shaders[0] = rm->GetOriginalID(pipe->VS()->GetResourceID());
@@ -3500,6 +3529,10 @@ void D3D12Replay::RefreshDerivedReplacements()
shaders[3] = rm->GetOriginalID(pipe->GS()->GetResourceID());
if(pipe->PS())
shaders[4] = rm->GetOriginalID(pipe->PS()->GetResourceID());
if(pipe->AS())
shaders[6] = rm->GetOriginalID(pipe->AS()->GetResourceID());
if(pipe->MS())
shaders[7] = rm->GetOriginalID(pipe->MS()->GetResourceID());
for(size_t i = 0; i < ARRAY_COUNT(shaders); i++)
{
@@ -3526,7 +3559,7 @@ void D3D12Replay::RefreshDerivedReplacements()
D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC desc = *pipe->graphics;
D3D12_SHADER_BYTECODE *shaders[] = {
&desc.VS, &desc.HS, &desc.DS, &desc.GS, &desc.PS,
&desc.VS, &desc.HS, &desc.DS, &desc.GS, &desc.PS, &desc.AS, &desc.MS,
};
for(size_t s = 0; s < ARRAY_COUNT(shaders); s++)
+1 -1
View File
@@ -261,7 +261,7 @@ public:
private:
void FillRootElements(uint32_t eventId, const D3D12RenderState::RootSignature &rootSig,
const ShaderBindpointMapping *mappings[(uint32_t)ShaderStage::Count],
const ShaderBindpointMapping *mappings[NumShaderStages],
rdcarray<D3D12Pipe::RootSignatureRange> &rootElements);
void FillResourceView(D3D12Pipe::View &view, const D3D12Descriptor *desc);
void FillSampler(D3D12Pipe::Sampler &view, const D3D12_SAMPLER_DESC2 &desc);
+8
View File
@@ -641,6 +641,10 @@ public:
desc.GS = GS()->GetDesc();
if(PS())
desc.PS = PS()->GetDesc();
if(AS())
desc.AS = AS()->GetDesc();
if(MS())
desc.MS = MS()->GetDesc();
}
else
{
@@ -854,6 +858,8 @@ public:
ShaderEntry *DS() { return (ShaderEntry *)graphics->DS.pShaderBytecode; }
ShaderEntry *GS() { return (ShaderEntry *)graphics->GS.pShaderBytecode; }
ShaderEntry *PS() { return (ShaderEntry *)graphics->PS.pShaderBytecode; }
ShaderEntry *AS() { return (ShaderEntry *)graphics->AS.pShaderBytecode; }
ShaderEntry *MS() { return (ShaderEntry *)graphics->MS.pShaderBytecode; }
ShaderEntry *CS() { return (ShaderEntry *)compute->CS.pShaderBytecode; }
WrappedID3D12PipelineState(ID3D12PipelineState *real, WrappedID3D12Device *device)
: WrappedDeviceChild12(real, device)
@@ -875,6 +881,8 @@ public:
ShaderEntry::ReleaseShader(DS());
ShaderEntry::ReleaseShader(GS());
ShaderEntry::ReleaseShader(PS());
ShaderEntry::ReleaseShader(AS());
ShaderEntry::ReleaseShader(MS());
SAFE_DELETE_ARRAY(graphics->InputLayout.pInputElementDescs);
SAFE_DELETE_ARRAY(graphics->StreamOutput.pSODeclaration);
+3 -1
View File
@@ -394,7 +394,9 @@ void D3D12_PrepareReplaySDKVersion(bool untrustedCapture, UINT SDKVersion, byteb
// similarly, if the system version is enough then the user didn't use a new runtime (or they used
// what was at the time a new runtime but is now available in the system...), so also abort.
// That means we'll only do the interception & patching when we think it's really needed.
if(SDKVersion <= SystemCoreVersion)
// The only exception is if the user has configured a force override, in which case we always use
// it.
if(SDKVersion <= SystemCoreVersion && D3D12_D3D12CoreDirPath().empty())
return;
// finally we're at a point where we will hook to force the library we want.
@@ -503,6 +503,13 @@ void DoSerialise(SerialiserType &ser, D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC
SERIALISE_MEMBER(DS);
SERIALISE_MEMBER(HS);
SERIALISE_MEMBER(GS);
if(ser.VersionAtLeast(0x11))
{
SERIALISE_MEMBER(AS);
SERIALISE_MEMBER(MS);
}
SERIALISE_MEMBER(StreamOutput);
SERIALISE_MEMBER(BlendState);
SERIALISE_MEMBER(SampleMask);
@@ -557,6 +564,8 @@ void Deserialise(const D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC &el)
FreeAlignedBuffer((byte *)(el.DS.pShaderBytecode));
FreeAlignedBuffer((byte *)(el.HS.pShaderBytecode));
FreeAlignedBuffer((byte *)(el.GS.pShaderBytecode));
FreeAlignedBuffer((byte *)(el.AS.pShaderBytecode));
FreeAlignedBuffer((byte *)(el.MS.pShaderBytecode));
FreeAlignedBuffer((byte *)(el.CS.pShaderBytecode));
}
@@ -818,6 +827,7 @@ void DoSerialise(SerialiserType &ser, D3D12_INDIRECT_ARGUMENT_DESC &el)
case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW:
case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED:
case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH:
case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH:
case D3D12_INDIRECT_ARGUMENT_TYPE_INDEX_BUFFER_VIEW:
// nothing to serialise
break;
@@ -1718,6 +1728,14 @@ void DoSerialise(SerialiserType &ser, D3D12_DISPATCH_ARGUMENTS &el)
SERIALISE_MEMBER(ThreadGroupCountZ).Important();
}
template <class SerialiserType>
void DoSerialise(SerialiserType &ser, D3D12_DISPATCH_MESH_ARGUMENTS &el)
{
SERIALISE_MEMBER(ThreadGroupCountX).Important();
SERIALISE_MEMBER(ThreadGroupCountY).Important();
SERIALISE_MEMBER(ThreadGroupCountZ).Important();
}
template <class SerialiserType>
void DoSerialise(SerialiserType &ser, D3D12ResourceLayout &el)
{
@@ -1881,3 +1899,4 @@ INSTANTIATE_SERIALISE_TYPE(D3D12ResourceLayout);
INSTANTIATE_SERIALISE_TYPE(D3D12_DRAW_ARGUMENTS);
INSTANTIATE_SERIALISE_TYPE(D3D12_DRAW_INDEXED_ARGUMENTS);
INSTANTIATE_SERIALISE_TYPE(D3D12_DISPATCH_ARGUMENTS);
INSTANTIATE_SERIALISE_TYPE(D3D12_DISPATCH_MESH_ARGUMENTS);
@@ -1103,7 +1103,8 @@ bool D3D12Replay::FetchShaderFeedback(uint32_t eventId)
const ActionDescription *action = m_pDevice->GetAction(eventId);
if(action == NULL || !(action->flags & (ActionFlags::Dispatch | ActionFlags::Drawcall)))
if(action == NULL ||
!(action->flags & (ActionFlags::Dispatch | ActionFlags::MeshDispatch | ActionFlags::Drawcall)))
{
// deliberately show no bindings as used for non-draws
result.valid = true;
@@ -1207,6 +1208,12 @@ bool D3D12Replay::FetchShaderFeedback(uint32_t eventId)
dynamicAccessPerStage[4] = AddArraySlots(
pipe->PS(), space, maxDescriptors, slots[(uint32_t)ShaderStage::Pixel], numSlots,
editedBlob[uint32_t(ShaderStage::Pixel)], pipeDesc.PS, directHeapAccess);
dynamicAccessPerStage[6] = AddArraySlots(
pipe->AS(), space, maxDescriptors, slots[(uint32_t)ShaderStage::Amplification], numSlots,
editedBlob[uint32_t(ShaderStage::Amplification)], pipeDesc.AS, directHeapAccess);
dynamicAccessPerStage[7] = AddArraySlots(
pipe->MS(), space, maxDescriptors, slots[(uint32_t)ShaderStage::Mesh], numSlots,
editedBlob[uint32_t(ShaderStage::Mesh)], pipeDesc.MS, directHeapAccess);
}
// if numSlots wasn't increased, none of the resources were arrayed so we have nothing to do.
@@ -1453,6 +1460,10 @@ bool D3D12Replay::FetchShaderFeedback(uint32_t eventId)
visMask = (uint32_t)ShaderStageMask::Geometry;
break;
case D3D12_SHADER_VISIBILITY_PIXEL: visMask = uint32_t(ShaderStageMask::Pixel); break;
case D3D12_SHADER_VISIBILITY_AMPLIFICATION:
visMask = uint32_t(ShaderStageMask::Amplification);
break;
case D3D12_SHADER_VISIBILITY_MESH: visMask = uint32_t(ShaderStageMask::Mesh); break;
default: RDCERR("Unexpected shader visibility %d", p.ShaderVisibility); return true;
}
@@ -60,6 +60,13 @@ static bool IsShaderParameterVisible(DXBC::ShaderType shaderType,
if(shaderType == DXBC::ShaderType::Pixel && shaderVisibility == D3D12_SHADER_VISIBILITY_PIXEL)
return true;
if(shaderType == DXBC::ShaderType::Amplification &&
shaderVisibility == D3D12_SHADER_VISIBILITY_AMPLIFICATION)
return true;
if(shaderType == DXBC::ShaderType::Mesh && shaderVisibility == D3D12_SHADER_VISIBILITY_MESH)
return true;
return false;
}
+2 -1
View File
@@ -91,7 +91,8 @@ void D3D12RenderState::ResolvePendingIndirectState(WrappedID3D12Device *device)
{
case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW:
case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED:
case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH: break;
case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH:
case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH: break;
case D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT:
{
size_t argSize = sizeof(uint32_t) * arg.Constant.Num32BitValuesToSet;
+3 -1
View File
@@ -28,7 +28,7 @@
template <>
rdcstr DoStringise(const D3D12Chunk &el)
{
RDCCOMPILE_ASSERT((uint32_t)D3D12Chunk::Max == 1123, "Chunks changed without updating names");
RDCCOMPILE_ASSERT((uint32_t)D3D12Chunk::Max == 1124, "Chunks changed without updating names");
BEGIN_ENUM_STRINGISE(D3D12Chunk)
{
@@ -220,6 +220,7 @@ rdcstr DoStringise(const D3D12Chunk &el)
STRINGISE_ENUM_CLASS_NAMED(List_IASetIndexBufferStripCutValue,
"ID3D12GraphicsCommandList9::IASetIndexBufferStripCutValue");
STRINGISE_ENUM_CLASS_NAMED(List_Barrier, "ID3D12GraphicsCommandList7::Barrier");
STRINGISE_ENUM_CLASS_NAMED(List_DispatchMesh, "ID3D12GraphicsCommandList6::DispatchMesh");
STRINGISE_ENUM_CLASS_NAMED(Max, "Max Chunk");
}
END_ENUM_STRINGISE()
@@ -732,6 +733,7 @@ rdcstr DoStringise(const D3D12_INDIRECT_ARGUMENT_TYPE &el)
STRINGISE_ENUM(D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW)
STRINGISE_ENUM(D3D12_INDIRECT_ARGUMENT_TYPE_SHADER_RESOURCE_VIEW)
STRINGISE_ENUM(D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW)
STRINGISE_ENUM(D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH)
}
END_ENUM_STRINGISE();
}