Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dxcopt: Support full container and restore extra data to module #4845

Merged
merged 30 commits into from
Dec 13, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
298aca7
dxcopt: Support full container and restore subobjects/root sig to module
tex3d Dec 3, 2022
9956bac
Move more code into the try block.
tex3d Dec 3, 2022
dea301d
Beginning outline of tests
tex3d Dec 3, 2022
dd5b6bd
Better return code when container doesn't contain DXIL
tex3d Dec 3, 2022
f91f943
Assemble to container, add a test
jeffnn Dec 3, 2022
5f72f78
More test
jeffnn Dec 3, 2022
7c13794
Fix ubuntu build?
jeffnn Dec 6, 2022
b91c86f
Assemble to container outside optimizer
jeffnn Dec 7, 2022
b4504f5
Copy PSV0 ViewID data back to DxilModule serialized data
tex3d Dec 7, 2022
99abb03
Restore resource names from shader reflection part (STAT)
tex3d Dec 8, 2022
ff66248
Restore Resource HLSL types and type annotations
tex3d Dec 8, 2022
ecc4330
Some error checking when copying resource info
tex3d Dec 8, 2022
2a4e96f
Remove existing type annotation if present, to force replacement
tex3d Dec 8, 2022
e2adc94
Start of view id tests
jeffnn Dec 8, 2022
5886db8
Merge branch 'dxcopt-from-container' of github.com:tex3d/DirectXShade…
jeffnn Dec 8, 2022
97beb9c
Test by comparing before and after
jeffnn Dec 8, 2022
92c66af
View instancing tests
jeffnn Dec 9, 2022
8c22fb4
GS test
jeffnn Dec 9, 2022
f1900dd
Move function restoring resource reflection to DxilModule
tex3d Dec 9, 2022
e3c7d67
Check target GlobalSymbol() before trying to set the name
tex3d Dec 9, 2022
4ca6522
Resource copy tests
jeffnn Dec 9, 2022
c31ab03
Merge branch 'dxcopt-from-container' of github.com:tex3d/DirectXShade…
jeffnn Dec 9, 2022
70ac5fd
Not should be not-not, initialize from the right data
jeffnn Dec 9, 2022
d07d3a2
ARE_EQUAL_STR
jeffnn Dec 9, 2022
a3733c9
Test fixes
jeffnn Dec 9, 2022
89ddbb7
test fixes
jeffnn Dec 9, 2022
e823397
Undo mistaken checkin
jeffnn Dec 9, 2022
190f138
Tests for i/o dependency map
jeffnn Dec 10, 2022
0182587
Test all tables
jeffnn Dec 10, 2022
1cfd5e7
NC: Update comment for what's restored from STAT
tex3d Dec 13, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 97 additions & 1 deletion lib/DxilPIXPasses/PixPassHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@

#include "dxc/DXIL/DxilOperations.h"
#include "dxc/DXIL/DxilInstructions.h"
#include "dxc/DXIL/DxilFunctionProps.h"
#include "dxc/DXIL/DxilModule.h"
#include "dxc/DXIL/DxilResourceBinding.h"
#include "dxc/DXIL/DxilResourceProperties.h"
#include "dxc/HLSL/DxilSpanAllocator.h"
#include "dxc/DxilRootSignature/DxilRootSignature.h"

#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
Expand All @@ -21,6 +23,10 @@

#include "PixPassHelpers.h"

#include "dxc/Support/Global.h"
#include "dxc/Support/WinIncludes.h"
#include "dxc/dxcapi.h"

#ifdef PIX_DEBUG_DUMP_HELPER
#include <iostream>
#include "llvm/IR/DebugInfo.h"
Expand Down Expand Up @@ -159,7 +165,89 @@ llvm::CallInst *CreateHandleForResource(hlsl::DxilModule &DM,
}
}

// Set up a UAV with structure of a single int
template<typename RootSigDesc, typename RootParameterDesc>
void ExtendRootSig(RootSigDesc &rootSigDesc) {
auto *existingParams = rootSigDesc.pParameters;
auto *newParams = new RootParameterDesc[rootSigDesc.NumParameters + 1];
memcpy(newParams, existingParams,
rootSigDesc.NumParameters * sizeof(RootParameterDesc));
if (existingParams != nullptr) {
delete[] existingParams;
}
rootSigDesc.pParameters = newParams;
rootSigDesc.pParameters[rootSigDesc.NumParameters].ParameterType = DxilRootParameterType::UAV;
rootSigDesc.pParameters[rootSigDesc.NumParameters].Descriptor.RegisterSpace = -2;
rootSigDesc.pParameters[rootSigDesc.NumParameters].Descriptor.ShaderRegister = 0;
rootSigDesc.pParameters[rootSigDesc.NumParameters].ShaderVisibility = DxilShaderVisibility::All;
rootSigDesc.NumParameters++;
}

static CComPtr<IDxcBlob> AddUAVParamterToRootSignature(const void *Data,
uint32_t Size) {
DxilVersionedRootSignatureDesc const *rootSignature = nullptr;
DeserializeRootSignature(Data, Size, &rootSignature);
auto *rs = const_cast<DxilVersionedRootSignatureDesc *>(rootSignature);
switch (rootSignature->Version) {
case DxilRootSignatureVersion::Version_1_0:
ExtendRootSig<DxilRootSignatureDesc, DxilRootParameter>(rs->Desc_1_0);
break;
case DxilRootSignatureVersion::Version_1_1:
ExtendRootSig<DxilRootSignatureDesc1, DxilRootParameter1>(rs->Desc_1_1);
rs->Desc_1_1.pParameters[rs->Desc_1_1.NumParameters - 1].Descriptor.Flags =
hlsl::DxilRootDescriptorFlags::None;
break;
}
CComPtr<IDxcBlob> serializedRootSignature;
CComPtr<IDxcBlobEncoding> errorBlob;
constexpr bool allowReservedRegisterSpace = true;
SerializeRootSignature(rootSignature, &serializedRootSignature, &errorBlob,
allowReservedRegisterSpace);
return serializedRootSignature;
}

static void AddUAVToShaderAttributeRootSignature(DxilModule &DM,
Function *function) {
if (DM.HasDxilFunctionProps(function)) {
auto &fnProps = DM.GetDxilFunctionProps(function);
if (!fnProps.serializedRootSignature.empty()) {
auto extendedRootSig = AddUAVParamterToRootSignature(
fnProps.serializedRootSignature.data(),
static_cast<uint32_t>(fnProps.serializedRootSignature.size()));
fnProps.SetSerializedRootSignature(
reinterpret_cast<const uint8_t *>(
extendedRootSig->GetBufferPointer()),
static_cast<unsigned int>(extendedRootSig->GetBufferSize()));
}
}
}

static void AddUAVToDxilDefinedGlobalRootSignatures(DxilModule& DM) {
auto *subObjects = DM.GetSubobjects();
if (subObjects != nullptr) {
for (auto const &subObject : subObjects->GetSubobjects()) {
if (subObject.second->GetKind() ==
DXIL::SubobjectKind::GlobalRootSignature) {
const char *Text;
const void *Data;
uint32_t Size;
constexpr bool notALocalRS = false;
if (subObject.second->GetRootSignature(notALocalRS, Data, Size,
&Text)) {
auto extendedRootSig = AddUAVParamterToRootSignature(Data, Size);
auto rootSignatureSubObjectName = subObject.first;
subObjects->RemoveSubobject(rootSignatureSubObjectName);
subObjects->CreateRootSignature(rootSignatureSubObjectName,
notALocalRS,
extendedRootSig->GetBufferPointer(),
extendedRootSig->GetBufferSize());
break;
}
}
}
}
}

// Set up a UAV with structure of a single int
llvm::CallInst *CreateUAV(DxilModule &DM, IRBuilder<> &Builder,
unsigned int registerId, const char *name) {
LLVMContext &Ctx = DM.GetModule()->getContext();
Expand All @@ -170,8 +258,16 @@ llvm::CallInst *CreateUAV(DxilModule &DM, IRBuilder<> &Builder,
if (UAVStructTy == nullptr) {
SmallVector<llvm::Type *, 1> Elements{Type::getInt32Ty(Ctx)};
UAVStructTy = llvm::StructType::create(Elements, PIXStructTypeName);

// Since we only have to do this once per module, we can do it now when
// we're adding the singular UAV structure type to the module:
AddUAVToDxilDefinedGlobalRootSignatures(DM);
}

AddUAVToShaderAttributeRootSignature(
DM,
Builder.GetInsertBlock()->getParent());

std::unique_ptr<DxilResource> pUAV = llvm::make_unique<DxilResource>();

auto const *shaderModel = DM.GetShaderModel();
Expand Down
41 changes: 30 additions & 11 deletions tools/clang/unittests/HLSL/OptimizerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,16 @@ void OptimizerTest::ComparePSV0BeforeAndAfterOptimization(const char *source, co
*optimizedPsv.GetViewIDOutputMask(stream).Mask);
VERIFY_ARE_EQUAL(originalPsv.GetViewIDOutputMask(stream).NumVectors,
optimizedPsv.GetViewIDOutputMask(stream).NumVectors);

VERIFY_ARE_EQUAL(originalPsv.GetInputToOutputTable(stream).IsValid(),
optimizedPsv.GetInputToOutputTable(stream).IsValid());
if (originalPsv.GetInputToOutputTable(stream).IsValid()) {
VERIFY_ARE_EQUAL(
originalPsv.GetInputToOutputTable(stream).InputVectors,
optimizedPsv.GetInputToOutputTable(stream).InputVectors);
VERIFY_ARE_EQUAL(
originalPsv.GetInputToOutputTable(stream).OutputVectors,
optimizedPsv.GetInputToOutputTable(stream).OutputVectors);
}
}
tex3d marked this conversation as resolved.
Show resolved Hide resolved
}
}
Expand Down Expand Up @@ -1227,22 +1236,32 @@ void CompareResources(const vector<unique_ptr<ResourceType>> &original,
auto const &optimizedRes = optimized.at(i);
VERIFY_ARE_EQUAL(originalRes->GetClass(), optimizedRes->GetClass());
VERIFY_ARE_EQUAL(originalRes->GetGlobalName(), optimizedRes->GetGlobalName());
VERIFY_ARE_EQUAL(originalRes->GetGlobalSymbol()->getName(),
optimizedRes->GetGlobalSymbol()->getName());
VERIFY_ARE_EQUAL(originalRes->GetHLSLType()->getTypeID(),
if (originalRes->GetGlobalSymbol() != nullptr &&
optimizedRes->GetGlobalSymbol() != nullptr) {
VERIFY_ARE_EQUAL(originalRes->GetGlobalSymbol()->getName(),
optimizedRes->GetGlobalSymbol()->getName());
}
if (originalRes->GetHLSLType() != nullptr &&
optimizedRes->GetHLSLType() != nullptr) {
VERIFY_ARE_EQUAL(originalRes->GetHLSLType()->getTypeID(),
optimizedRes->GetHLSLType()->getTypeID());
if (originalRes->GetHLSLType()->getTypeID() == Type::TypeID::StructTyID) {
VERIFY_ARE_EQUAL(originalRes->GetHLSLType()->getStructName(),
optimizedRes->GetHLSLType()->getStructName());
if (originalRes->GetHLSLType()->getTypeID() == Type::PointerTyID) {
auto originalPointedType = originalRes->GetHLSLType()->getArrayElementType();
auto optimizedPointedType = optimizedRes->GetHLSLType()->getArrayElementType();
VERIFY_ARE_EQUAL(originalPointedType->getTypeID(),
optimizedPointedType->getTypeID());
if (optimizedPointedType->getTypeID() == Type::StructTyID) {
VERIFY_ARE_EQUAL(originalPointedType->getStructName(),
optimizedPointedType->getStructName());
}
}
}
VERIFY_ARE_EQUAL(originalRes->GetID(), optimizedRes->GetID());
VERIFY_ARE_EQUAL(originalRes->GetKind(), optimizedRes->GetKind());
VERIFY_ARE_EQUAL(originalRes->GetLowerBound(), optimizedRes->GetLowerBound());
VERIFY_ARE_EQUAL(originalRes->GetRangeSize(), optimizedRes->GetRangeSize());
VERIFY_ARE_EQUAL(originalRes->GetResBindPrefix(), optimizedRes->GetResBindPrefix());
VERIFY_ARE_EQUAL(originalRes->GetResClassName(), optimizedRes->GetResClassName());
VERIFY_ARE_EQUAL(originalRes->GetResDimName(), optimizedRes->GetResDimName());
VERIFY_ARE_EQUAL(originalRes->GetResIDPrefix(), optimizedRes->GetResIDPrefix());
VERIFY_ARE_EQUAL_STR(originalRes->GetResBindPrefix(), optimizedRes->GetResBindPrefix());
VERIFY_ARE_EQUAL_STR(originalRes->GetResIDPrefix(), optimizedRes->GetResIDPrefix());
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are just the prefix character decoded from the Class, so comparing GetResBindPrefix and GetResIDPrefix are also unnecessary. Basically, if Class was wrong, there would be something very fundamentally wrong with which list the resource is in for the DxilModule. By which I mean we would have much bigger problems, and expect a whole lot of things to break.

VERIFY_ARE_EQUAL(originalRes->GetSpaceID(), optimizedRes->GetSpaceID());
VERIFY_ARE_EQUAL(originalRes->GetUpperBound(), optimizedRes->GetUpperBound());
}
Expand Down