Skip to content

Commit 848b7c4

Browse files
authored
PIX: Make shader access tracking pass return whether or not it modified anything (microsoft#7010)
The SAT pass will now report a string when it finds that no resource access was performed by a module. This solves two issues. -The SAT pass, when operating on a shader that has no resource access, will add a resource declaration for the PIX output UAV. This becomes a problem for PIX in terms of juggling root signatures and/or root parameters. -SAT is a notoriously time-consuming operation in PIX, so if the SAT pass can report that its results do not need to be re-packaged into a new container for passing to the d3d API, then PIX can avoid the overhead of doing so. But of course we need to be careful that the SAT pass doesn't erroneously report that it didn't modify the module when in fact it did, cuz then PIX would fail to notice some dynamic resource accesses. That's what the tests are for.
1 parent e824ae3 commit 848b7c4

File tree

2 files changed

+77
-6
lines changed

2 files changed

+77
-6
lines changed

lib/DxilPIXPasses/DxilShaderAccessTracking.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,9 @@ bool DxilShaderAccessTracking::runOnModule(Module &M) {
10521052
// Done with these guys:
10531053
m_GEPOperandAsInstructionDestroyers.clear();
10541054

1055+
if (OSOverride != nullptr && !Modified) {
1056+
*OSOverride << "\nNotModified\n";
1057+
}
10551058
return Modified;
10561059
}
10571060
char DxilShaderAccessTracking::ID = 0;

tools/clang/unittests/HLSL/PixTest.cpp

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ class PixTest : public ::testing::Test {
112112
TEST_METHOD(SignatureModification_VertexIdAlready)
113113
TEST_METHOD(SignatureModification_SomethingElseFirst)
114114

115+
TEST_METHOD(AccessTracking_ModificationReport_Nothing)
116+
TEST_METHOD(AccessTracking_ModificationReport_Read)
117+
TEST_METHOD(AccessTracking_ModificationReport_Write)
118+
TEST_METHOD(AccessTracking_ModificationReport_SM66)
119+
115120
TEST_METHOD(PixStructAnnotation_Lib_DualRaygen)
116121
TEST_METHOD(PixStructAnnotation_Lib_RaygenAllocaStructAlignment)
117122

@@ -348,6 +353,8 @@ class PixTest : public ::testing::Test {
348353
*ppNewShaderOut = pNewContainer.Detach();
349354
}
350355

356+
void ValidateAccessTrackingMods(const char *hlsl, bool modsExpected);
357+
351358
class ModuleAndHangersOn {
352359
std::unique_ptr<llvm::LLVMContext> llvmContext;
353360
std::unique_ptr<llvm::Module> llvmModule;
@@ -429,7 +436,7 @@ class PixTest : public ::testing::Test {
429436
const wchar_t *profile = L"as_6_5");
430437
void ValidateAllocaWrite(std::vector<AllocaWrite> const &allocaWrites,
431438
size_t index, const char *name);
432-
CComPtr<IDxcBlob> RunShaderAccessTrackingPass(IDxcBlob *blob);
439+
PassOutput RunShaderAccessTrackingPass(IDxcBlob *blob);
433440
std::string RunDxilPIXAddTidToAmplificationShaderPayloadPass(IDxcBlob *blob);
434441
CComPtr<IDxcBlob> RunDxilPIXMeshShaderOutputPass(IDxcBlob *blob);
435442
CComPtr<IDxcBlob> RunDxilPIXDXRInvocationsLog(IDxcBlob *blob);
@@ -576,13 +583,14 @@ TEST_F(PixTest, CompileDebugDisasmPDB) {
576583
VERIFY_SUCCEEDED(pCompiler->Disassemble(pPdbBlob, &pDisasm));
577584
}
578585

579-
CComPtr<IDxcBlob> PixTest::RunShaderAccessTrackingPass(IDxcBlob *blob) {
586+
PassOutput PixTest::RunShaderAccessTrackingPass(IDxcBlob *blob) {
580587
CComPtr<IDxcOptimizer> pOptimizer;
581588
VERIFY_SUCCEEDED(
582589
m_dllSupport.CreateInstance(CLSID_DxcOptimizer, &pOptimizer));
583590
std::vector<LPCWSTR> Options;
584591
Options.push_back(L"-opt-mod-passes");
585-
Options.push_back(L"-hlsl-dxil-pix-shader-access-instrumentation,config=");
592+
Options.push_back(L"-hlsl-dxil-pix-shader-access-instrumentation,config=U0:0:"
593+
L"10i0;U0:1:2i0;.0;0;0.");
586594

587595
CComPtr<IDxcBlob> pOptimizedModule;
588596
CComPtr<IDxcBlobEncoding> pText;
@@ -604,7 +612,12 @@ CComPtr<IDxcBlob> PixTest::RunShaderAccessTrackingPass(IDxcBlob *blob) {
604612
CComPtr<IDxcBlob> pNewContainer;
605613
VERIFY_SUCCEEDED(pAssembleResult->GetResult(&pNewContainer));
606614

607-
return pNewContainer;
615+
PassOutput ret;
616+
ret.blob = pNewContainer;
617+
std::string outputText = BlobToUtf8(pText);
618+
ret.lines = Tokenize(outputText.c_str(), "\n");
619+
620+
return ret;
608621
}
609622

610623
CComPtr<IDxcBlob> PixTest::RunDxilPIXMeshShaderOutputPass(IDxcBlob *blob) {
@@ -816,6 +829,61 @@ TEST_F(PixTest, SignatureModification_SomethingElseFirst) {
816829
VERIFY_ARE_EQUAL(sig.GetElement(2).GetStartRow(), 2);
817830
}
818831

832+
void PixTest::ValidateAccessTrackingMods(const char *hlsl, bool modsExpected) {
833+
auto code = Compile(m_dllSupport, hlsl, L"ps_6_6", {L"-Od"}, L"main");
834+
auto result = RunShaderAccessTrackingPass(code).lines;
835+
bool hasMods = true;
836+
for (auto const &line : result)
837+
if (line.find("NotModified") != std::string::npos)
838+
hasMods = false;
839+
VERIFY_ARE_EQUAL(modsExpected, hasMods);
840+
}
841+
842+
TEST_F(PixTest, AccessTracking_ModificationReport_Nothing) {
843+
const char *hlsl = R"(
844+
float main() : SV_Target
845+
{
846+
return 0;
847+
}
848+
)";
849+
ValidateAccessTrackingMods(hlsl, false);
850+
}
851+
852+
TEST_F(PixTest, AccessTracking_ModificationReport_Read) {
853+
const char *hlsl = R"(
854+
RWByteAddressBuffer g_texture;
855+
float main() : SV_Target
856+
{
857+
return g_texture.Load(0);
858+
}
859+
)";
860+
ValidateAccessTrackingMods(hlsl, true);
861+
}
862+
863+
TEST_F(PixTest, AccessTracking_ModificationReport_Write) {
864+
const char *hlsl = R"(
865+
RWByteAddressBuffer g_texture;
866+
float main() : SV_Target
867+
{
868+
g_texture.Store(0, 0);
869+
return 0;
870+
}
871+
)";
872+
ValidateAccessTrackingMods(hlsl, true);
873+
}
874+
875+
TEST_F(PixTest, AccessTracking_ModificationReport_SM66) {
876+
const char *hlsl = R"(
877+
float main() : SV_Target
878+
{
879+
RWByteAddressBuffer g_texture = ResourceDescriptorHeap[0];
880+
g_texture.Store(0, 0);
881+
return 0;
882+
}
883+
)";
884+
ValidateAccessTrackingMods(hlsl, true);
885+
}
886+
819887
TEST_F(PixTest, AddToASGroupSharedPayload) {
820888

821889
const char *hlsl = R"(
@@ -2720,7 +2788,7 @@ void MyMiss(inout MyPayload payload)
27202788
CComPtr<IDxcBlob> compiled;
27212789
VERIFY_SUCCEEDED(pResult->GetResult(&compiled));
27222790

2723-
auto optimizedContainer = RunShaderAccessTrackingPass(compiled);
2791+
auto optimizedContainer = RunShaderAccessTrackingPass(compiled).blob;
27242792

27252793
const char *pBlobContent =
27262794
reinterpret_cast<const char *>(optimizedContainer->GetBufferPointer());
@@ -2790,7 +2858,7 @@ float4 main(int i : A, float j : B) : SV_TARGET
27902858
)x";
27912859

27922860
auto compiled = Compile(m_dllSupport, dynamicTextureAccess, L"ps_6_6");
2793-
auto pOptimizedContainer = RunShaderAccessTrackingPass(compiled);
2861+
auto pOptimizedContainer = RunShaderAccessTrackingPass(compiled).blob;
27942862

27952863
const char *pBlobContent =
27962864
reinterpret_cast<const char *>(pOptimizedContainer->GetBufferPointer());

0 commit comments

Comments
 (0)