Skip to content

Commit

Permalink
[ViewID] build viewid mask for primitive output (#6886)
Browse files Browse the repository at this point in the history
Currently, viewid mask for primitive output is always empty. This change
will fix it by treat entry as PC entry and skip output when it is not
what is checking.

For #6817
  • Loading branch information
python3kgae authored Sep 5, 2024
1 parent 663785a commit 72f306c
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 10 deletions.
28 changes: 20 additions & 8 deletions lib/HLSL/ComputeViewIdStateBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ class DxilViewIdStateBuilder {
// Contributing instructions per output.
std::unordered_map<unsigned, InstructionSetType>
ContributingInstructions[kNumStreams];

void Clear();
};

Expand Down Expand Up @@ -142,7 +141,8 @@ class DxilViewIdStateBuilder {
llvm::CallGraphNode *pNode,
FunctionSetType &FuncSet);
void AnalyzeFunctions(EntryInfo &Entry);
void CollectValuesContributingToOutputs(EntryInfo &Entry);
void CollectValuesContributingToOutputs(EntryInfo &Entry,
bool IsForPatchConstant);
void CollectValuesContributingToOutputRec(
EntryInfo &Entry, llvm::Value *pContributingValue,
InstructionSetType &ContributingInstructions);
Expand Down Expand Up @@ -190,9 +190,12 @@ void DxilViewIdStateBuilder::Compute() {
CallGraph CG = CGA.run(m_pModule->GetModule());
m_Entry.pEntryFunc = m_pModule->GetEntryFunction();
m_PCEntry.pEntryFunc = m_pModule->GetPatchConstantFunction();
// For MS, use main entry as PC entry to collect primitive outputs.
if (pSM->IsMS())
m_PCEntry.pEntryFunc = m_pModule->GetEntryFunction();
ComputeReachableFunctionsRec(CG, CG[m_Entry.pEntryFunc], m_Entry.Functions);
if (m_PCEntry.pEntryFunc) {
DXASSERT_NOMSG(pSM->IsHS());
DXASSERT_NOMSG(pSM->IsHS() || pSM->IsMS());
ComputeReachableFunctionsRec(CG, CG[m_PCEntry.pEntryFunc],
m_PCEntry.Functions);
}
Expand All @@ -205,10 +208,11 @@ void DxilViewIdStateBuilder::Compute() {
}

// 4. Collect sets of values contributing to outputs.
CollectValuesContributingToOutputs(m_Entry);
if (m_PCEntry.pEntryFunc) {
CollectValuesContributingToOutputs(m_PCEntry);
}
CollectValuesContributingToOutputs(m_Entry,
/*IsForPatchConstantOrPrimitive*/ false);
if (m_PCEntry.pEntryFunc)
CollectValuesContributingToOutputs(m_PCEntry,
/*IsForPatchConstantOrPrimitive*/ true);

// 5. Construct dependency sets.
for (unsigned StreamId = 0; StreamId < (pSM->IsGS() ? kNumStreams : 1u);
Expand Down Expand Up @@ -454,35 +458,43 @@ void DxilViewIdStateBuilder::AnalyzeFunctions(EntryInfo &Entry) {
}

void DxilViewIdStateBuilder::CollectValuesContributingToOutputs(
EntryInfo &Entry) {
EntryInfo &Entry, bool IsForPatchConstantOrPrimitive) {
for (auto *CI : Entry.Outputs) { // CI = call instruction
DxilSignature *pDxilSig = nullptr;
Value *pContributingValue = nullptr;
unsigned id = (unsigned)-1;
int startRow = Semantic::kUndefinedRow, endRow = Semantic::kUndefinedRow;
unsigned col = (unsigned)-1;
if (DxilInst_StoreOutput SO = DxilInst_StoreOutput(CI)) {
if (IsForPatchConstantOrPrimitive)
continue;
pDxilSig = &m_pModule->GetOutputSignature();
pContributingValue = SO.get_value();
GetUnsignedVal(SO.get_outputSigId(), &id);
GetUnsignedVal(SO.get_colIndex(), &col);
GetUnsignedVal(SO.get_rowIndex(), (uint32_t *)&startRow);
} else if (DxilInst_StoreVertexOutput SVO =
DxilInst_StoreVertexOutput(CI)) {
if (IsForPatchConstantOrPrimitive)
continue;
pDxilSig = &m_pModule->GetOutputSignature();
pContributingValue = SVO.get_value();
GetUnsignedVal(SVO.get_outputSigId(), &id);
GetUnsignedVal(SVO.get_colIndex(), &col);
GetUnsignedVal(SVO.get_rowIndex(), (uint32_t *)&startRow);
} else if (DxilInst_StorePrimitiveOutput SPO =
DxilInst_StorePrimitiveOutput(CI)) {
if (!IsForPatchConstantOrPrimitive)
continue;
pDxilSig = &m_pModule->GetPatchConstOrPrimSignature();
pContributingValue = SPO.get_value();
GetUnsignedVal(SPO.get_outputSigId(), &id);
GetUnsignedVal(SPO.get_colIndex(), &col);
GetUnsignedVal(SPO.get_rowIndex(), (uint32_t *)&startRow);
} else if (DxilInst_StorePatchConstant SPC =
DxilInst_StorePatchConstant(CI)) {
if (!IsForPatchConstantOrPrimitive)
continue;
pDxilSig = &m_pModule->GetPatchConstOrPrimSignature();
pContributingValue = SPC.get_value();
GetUnsignedVal(SPC.get_outputSigID(), &id);
Expand Down
4 changes: 2 additions & 2 deletions tools/clang/test/DXC/dumpPSV_MS.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
// CHECK-NEXT: Outputs affected by ViewID as a bitmask for stream 0:
// CHECK-NEXT: ViewID influencing Outputs[0] : 0 1 2 3 4 8 12 16
// CHECK-NEXT: PCOutputs affected by ViewID as a bitmask:
// CHECK-NEXT: ViewID influencing PCOutputs : None
// CHECK-NEXT: ViewID influencing PCOutputs : 3
// CHECK-NEXT: Outputs affected by inputs as a table of bitmasks for stream 0:
// CHECK-NEXT: Inputs contributing to computation of Outputs[0]: None

Expand Down Expand Up @@ -189,7 +189,7 @@ void main(
op.normal = mpl.normal;
op.malnor = gsMem[tig / 3 + 1];
op.alnorm = mpl.alnorm;
op.ormaln = mpl.ormaln;
op.ormaln = mpl.ormaln + vid;
op.layer[0] = mpl.layer[0];
op.layer[1] = mpl.layer[1];
op.layer[2] = mpl.layer[2];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// RUN: %dxc -E main -T ms_6_5 %s | FileCheck %s

// RUN: %dxc -E main -T ms_6_5 -DVIEWID %s | FileCheck %s -check-prefix=VIEWID

// RUN: %dxc -E main -T ms_6_5 -DVIEWID -DVIEWID_A %s | FileCheck %s -check-prefix=VIEWID_A

// RUN: %dxc -E main -T ms_6_5 -DVIEWID -DVIEWID_B %s | FileCheck %s -check-prefix=VIEWID_B

// RUN: %dxc -E main -T ms_6_5 -DVIEWID -DVIEWID_C %s | FileCheck %s -check-prefix=VIEWID_C

// RUN: %dxc -E main -T ms_6_5 -DVIEWID -DVIEWID_D %s | FileCheck %s -check-prefix=VIEWID_D


// CHECK:; Number of inputs: 0, outputs: 17, primitive outputs: 25
// CHECK:; Outputs dependent on ViewId: { }
// CHECK:; Primitive Outputs dependent on ViewId: { }
// CHECK:; Inputs contributing to computation of Outputs:
// CHECK:; Inputs contributing to computation of Primitive Outputs:

// VIEWID:; Number of inputs: 0, outputs: 17, primitive outputs: 25
// VIEWID:; Outputs dependent on ViewId: { }
// VIEWID:; Primitive Outputs dependent on ViewId: { }
// VIEWID:; Inputs contributing to computation of Outputs:
// VIEWID:; Inputs contributing to computation of Primitive Outputs:

// VIEWID_A:; Number of inputs: 0, outputs: 17, primitive outputs: 25
// VIEWID_A:; Outputs dependent on ViewId: { 12 }
// VIEWID_A:; Primitive Outputs dependent on ViewId: { }
// VIEWID_A:; Inputs contributing to computation of Outputs:
// VIEWID_A:; Inputs contributing to computation of Primitive Outputs:


// VIEWID_B:; Number of inputs: 0, outputs: 17, primitive outputs: 25
// VIEWID_B:; Outputs dependent on ViewId: { }
// VIEWID_B:; Primitive Outputs dependent on ViewId: { 0, 1, 2, 3, 4, 8, 12, 16, 20, 24 }
// VIEWID_B:; Inputs contributing to computation of Outputs:
// VIEWID_B:; Inputs contributing to computation of Primitive Outputs:


// VIEWID_C:; Number of inputs: 0, outputs: 17, primitive outputs: 25
// VIEWID_C:; Outputs dependent on ViewId: { 8 }
// VIEWID_C:; Primitive Outputs dependent on ViewId: { }
// VIEWID_C:; Inputs contributing to computation of Outputs:
// VIEWID_C:; Inputs contributing to computation of Primitive Outputs:


// VIEWID_D:; Number of inputs: 0, outputs: 17, primitive outputs: 25
// VIEWID_D:; Outputs dependent on ViewId: { }
// VIEWID_D:; Primitive Outputs dependent on ViewId: { 24 }
// VIEWID_D:; Inputs contributing to computation of Outputs:
// VIEWID_D:; Inputs contributing to computation of Primitive Outputs:

#define MAX_VERT 32
#define MAX_PRIM 16
#define NUM_THREADS 32
struct MeshPerVertex {
float4 position : SV_Position;
float color[4] : COLOR;
};

struct MeshPerPrimitive {
float normal : NORMAL;
float malnor : MALNOR;
float alnorm : ALNORM;
float ormaln : ORMALN;
int layer[6] : LAYER;
bool cullPrimitive : SV_CullPrimitive;
};

struct MeshPayload {
float normal;
float malnor;
float alnorm;
float ormaln;
int layer[6];
};

groupshared float gsMem[MAX_PRIM];

[numthreads(NUM_THREADS, 1, 1)]
[outputtopology("triangle")]
void main(
out indices uint3 primIndices[MAX_PRIM],
out vertices MeshPerVertex verts[MAX_VERT],
out primitives MeshPerPrimitive prims[MAX_PRIM],
in payload MeshPayload mpl,
in uint tig : SV_GroupIndex
#ifdef VIEWID
,in uint vid : SV_ViewID
#endif
)
{
SetMeshOutputCounts(MAX_VERT, MAX_PRIM);
MeshPerVertex ov;
if (tig % 2) {
ov.position = float4(4.0,5.0,6.0,7.0);
ov.color[0] = 4.0;
ov.color[1] = 5.0;
#ifdef VIEWID_A
ov.color[2] = vid;
#else
ov.color[2] = 6.0;
#endif
ov.color[3] = 7.0;
} else {
ov.position = float4(14.0,15.0,16.0,17.0);
ov.color[0] = 14.0;
#ifdef VIEWID_C
ov.color[1] = vid;
#else
ov.color[1] = 15.0;
#endif
ov.color[2] = 16.0;
ov.color[3] = 17.0;
}

#ifdef VIEWID_B
if (vid % 3) {
#else
if (tig % 3) {
#endif
primIndices[tig / 3] = uint3(tig, tig + 1, tig + 2);
MeshPerPrimitive op;
op.normal = mpl.normal;
op.malnor = gsMem[tig / 3 + 1];
op.alnorm = mpl.alnorm;
op.ormaln = mpl.ormaln;
op.layer[0] = mpl.layer[0];
op.layer[1] = mpl.layer[1];
op.layer[2] = mpl.layer[2];
op.layer[3] = mpl.layer[3];
op.layer[4] = mpl.layer[4];
#ifdef VIEWID_D
op.layer[5] = mpl.layer[5] + vid;
#else
op.layer[5] = mpl.layer[5];
#endif
op.cullPrimitive = false;
gsMem[tig / 3] = op.normal;
prims[tig / 3] = op;
}
verts[tig] = ov;
}

0 comments on commit 72f306c

Please sign in to comment.