Skip to content

Commit

Permalink
Merge 80ef3fb into a64a768
Browse files Browse the repository at this point in the history
  • Loading branch information
bob80905 authored Jun 30, 2023
2 parents a64a768 + 80ef3fb commit b9bd7bb
Show file tree
Hide file tree
Showing 8 changed files with 336 additions and 163 deletions.
3 changes: 3 additions & 0 deletions include/dxc/DxilContainer/DxilContainerAssembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "dxc/DxilContainer/DxilContainer.h"
#include "llvm/ADT/StringRef.h"

struct IDxcVersionInfo;
struct IStream;
class DxilPipelineStateValidation;

Expand Down Expand Up @@ -51,6 +52,7 @@ DxilPartWriter *NewRootSignatureWriter(const RootSignatureHandle &S);
DxilPartWriter *NewFeatureInfoWriter(const DxilModule &M);
DxilPartWriter *NewPSVWriter(const DxilModule &M, uint32_t PSVVersion = UINT_MAX);
DxilPartWriter *NewRDATWriter(const DxilModule &M);
DxilPartWriter *NewVersionWriter(IDxcVersionInfo *pVersionInfo);

// Store serialized ViewID data from DxilModule to PipelineStateValidation.
void StoreViewIDStateToPSV(const uint32_t *pInputData,
Expand All @@ -77,6 +79,7 @@ void WriteProgramPart(const hlsl::ShaderModel *pModel,

void SerializeDxilContainerForModule(
hlsl::DxilModule *pModule, AbstractMemoryStream *pModuleBitcode,
IDxcVersionInfo *DXCVersionInfo,
AbstractMemoryStream *pStream, llvm::StringRef DebugName,
SerializeDxilFlags Flags, DxilShaderHash *pShaderHashOut = nullptr,
AbstractMemoryStream *pReflectionStreamOut = nullptr,
Expand Down
112 changes: 112 additions & 0 deletions lib/DxilContainer/DxilContainerAssembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1008,6 +1008,93 @@ class DxilPSVWriter : public DxilPartWriter {
}
};

//////////////////////////////////////////////////////////
// DxilVersionWriter - Writes VERS part
class DxilVersionWriter : public DxilPartWriter {
hlsl::DxilCompilerVersion m_Header = {};
CComHeapPtr<char> m_CommitShaStorage;
llvm::StringRef m_CommitSha = "";
CComHeapPtr<char> m_CustomStringStorage;
llvm::StringRef m_CustomString = "";
public:
DxilVersionWriter(IDxcVersionInfo *pVersion)
{
Init(pVersion);
}

void Init(IDxcVersionInfo *pVersionInfo) {
m_Header = {};

UINT32 Major = 0, Minor = 0;
UINT32 Flags = 0;
IFT(pVersionInfo->GetVersion(&Major, &Minor));
IFT(pVersionInfo->GetFlags(&Flags));

m_Header.Major = Major;
m_Header.Minor = Minor;
m_Header.VersionFlags = Flags;
CComPtr<IDxcVersionInfo2> pVersionInfo2;
if (SUCCEEDED(pVersionInfo->QueryInterface(&pVersionInfo2))) {
UINT32 CommitCount = 0;
IFT(pVersionInfo2->GetCommitInfo(&CommitCount, &m_CommitShaStorage));
m_CommitSha = llvm::StringRef(m_CommitShaStorage.m_pData, strlen(m_CommitShaStorage.m_pData));
m_Header.CommitCount = CommitCount;
m_Header.VersionStringListSizeInBytes += m_CommitSha.size();
}
m_Header.VersionStringListSizeInBytes += /*null term*/ 1;

CComPtr<IDxcVersionInfo3> pVersionInfo3;
if (SUCCEEDED(pVersionInfo->QueryInterface(&pVersionInfo3))) {
IFT(pVersionInfo3->GetCustomVersionString(&m_CustomStringStorage));
m_CustomString = llvm::StringRef(m_CustomStringStorage, strlen(m_CustomStringStorage.m_pData));
m_Header.VersionStringListSizeInBytes += m_CustomString.size();
}
m_Header.VersionStringListSizeInBytes += /*null term*/ 1;
}

static uint32_t PadToDword(uint32_t size, uint32_t *outNumPadding=nullptr) {
uint32_t rem = size % 4;
if (rem) {
uint32_t padding = (4 - rem);
if (outNumPadding)
*outNumPadding = padding;
return size + padding;
}
if (outNumPadding)
*outNumPadding = 0;
return size;
}

UINT32 size() const override {
return PadToDword(sizeof(m_Header) + m_Header.VersionStringListSizeInBytes);
}

void write(AbstractMemoryStream *pStream) override {
const uint8_t padByte = 0;
UINT32 uPadding = 0;
UINT32 uSize = PadToDword(sizeof(m_Header) + m_Header.VersionStringListSizeInBytes, &uPadding);
(void)uSize;

ULONG cbWritten = 0;
IFT(pStream->Write(&m_Header, sizeof(m_Header), &cbWritten));

// Write a null terminator even if the string is empty
IFT(pStream->Write(m_CommitSha.data(), m_CommitSha.size(), &cbWritten));
// Null terminator for the commit sha
IFT(pStream->Write(&padByte, sizeof(padByte), &cbWritten));

// Write the custom version string.
IFT(pStream->Write(m_CustomString.data(), m_CustomString.size(), &cbWritten));
// Null terminator for the custom version string.
IFT(pStream->Write(&padByte, sizeof(padByte), &cbWritten));

// Write padding
for (unsigned i = 0; i < uPadding; i++) {
IFT(pStream->Write(&padByte, sizeof(padByte), &cbWritten));
}
}
};

using namespace DXIL;

class DxilRDATWriter : public DxilPartWriter {
Expand Down Expand Up @@ -1398,6 +1485,10 @@ DxilPartWriter *hlsl::NewRDATWriter(const DxilModule &M) {
return new DxilRDATWriter(M);
}

DxilPartWriter *hlsl::NewVersionWriter(IDxcVersionInfo *DXCVersionInfo) {
return new DxilVersionWriter(DXCVersionInfo);
}

class DxilContainerWriter_impl : public DxilContainerWriter {
private:
class DxilPart {
Expand Down Expand Up @@ -1575,6 +1666,7 @@ void hlsl::StripAndCreateReflectionStream(Module *pReflectionM, uint32_t *pRefle

void hlsl::SerializeDxilContainerForModule(
DxilModule *pModule, AbstractMemoryStream *pModuleBitcode,
IDxcVersionInfo *DXCVersionInfo,
AbstractMemoryStream *pFinalStream, llvm::StringRef DebugName,
SerializeDxilFlags Flags, DxilShaderHash *pShaderHashOut,
AbstractMemoryStream *pReflectionStreamOut,
Expand Down Expand Up @@ -1646,8 +1738,11 @@ void hlsl::SerializeDxilContainerForModule(
});
}
}

std::unique_ptr<DxilVersionWriter> pVERSWriter = nullptr;
std::unique_ptr<DxilRDATWriter> pRDATWriter = nullptr;
std::unique_ptr<DxilPSVWriter> pPSVWriter = nullptr;

unsigned int major, minor;
pModule->GetDxilVersion(major, minor);
RootSignatureWriter rootSigWriter(std::move(pModule->GetSerializedRootSignature())); // Grab RS here
Expand All @@ -1657,6 +1752,23 @@ void hlsl::SerializeDxilContainerForModule(
if (pModule->GetShaderModel()->IsLib()) {
DXASSERT(pModule->GetSerializedRootSignature().empty(),
"otherwise, library has root signature outside subobject definitions");
// Write the DxilCompilerVersion (VERS) part.

if (DXCVersionInfo) {

pVERSWriter = llvm::make_unique<DxilVersionWriter>(DXCVersionInfo);

writer.AddPart(
hlsl::DFCC_CompilerVersion,
pVERSWriter->size(),
[&pVERSWriter](AbstractMemoryStream *pStream) {
pVERSWriter->write(pStream);
return S_OK;
}
);
}


// Write the DxilRuntimeData (RDAT) part.
pRDATWriter = llvm::make_unique<DxilRDATWriter>(*pModule);
writer.AddPart(
Expand Down
83 changes: 83 additions & 0 deletions lib/HLSL/DxilValidation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5539,6 +5539,79 @@ static void VerifyFeatureInfoMatches(_In_ ValidationContext &ValCtx,
VerifyBlobPartMatches(ValCtx, "Feature Info", pWriter.get(), pFeatureInfoData, FeatureInfoSize);
}

// return true if the pBlob is a valid, well-formed CompilerVersion part, false
// otherwise
bool ValidateCompilerVersionPart(const void *pBlobPtr, UINT blobSize) {
// The hlsl::DxilCompilerVersion struct is always 16 bytes. (2 2-byte
// uint16's, 3 4-byte uint32's) The blob size should absolutely never be less
// than 16 bytes.
if (blobSize < sizeof(hlsl::DxilCompilerVersion)) {
return false;
}

const hlsl::DxilCompilerVersion *pDCV =
(const hlsl::DxilCompilerVersion *)pBlobPtr;
if (pDCV->VersionStringListSizeInBytes == 0) {
// No version strings, just make sure there is no extra space.
return blobSize == sizeof(hlsl::DxilCompilerVersion);
}

// after this point, we know VersionStringListSizeInBytes >= 1, because it is
// a UINT

UINT EndOfVersionStringIndex =
sizeof(hlsl::DxilCompilerVersion) + pDCV->VersionStringListSizeInBytes;
// Make sure that the buffer size is large enough to contain both the DCV
// struct and the version string but not any larger than necessary
if (PSVALIGN4(EndOfVersionStringIndex) != blobSize) {
return false;
}

const char *VersionStringsListData =
(const char *)pBlobPtr + sizeof(hlsl::DxilCompilerVersion);
UINT VersionStringListSizeInBytes = pDCV->VersionStringListSizeInBytes;

// now make sure that any pad bytes that were added are null-terminators.
for (UINT i = VersionStringListSizeInBytes;
i < blobSize - sizeof(hlsl::DxilCompilerVersion); i++) {
if (VersionStringsListData[i] != '\0') {
return false;
}
}

// Now, version string validation
// first, the final byte of the string should always be null-terminator so
// that the string ends
if (VersionStringsListData[VersionStringListSizeInBytes - 1] != '\0') {
return false;
}

// construct the first string
// data format for VersionString can be see in the definition for the
// DxilCompilerVersion struct. summary: 2 strings that each end with the null
// terminator, and [0-3] null terminators after the final null terminator
StringRef firstStr(VersionStringsListData);

// if the second string exists, attempt to construct it.
if (VersionStringListSizeInBytes > (firstStr.size() + 1)) {
StringRef secondStr(VersionStringsListData + firstStr.size() + 1);

// the VersionStringListSizeInBytes member should be exactly equal to the
// two string lengths, plus the 2 null terminator bytes.
if (VersionStringListSizeInBytes !=
firstStr.size() + secondStr.size() + 2) {
return false;
}
} else {
// the VersionStringListSizeInBytes member should be exactly equal to the
// first string length, plus the 1 null terminator byte.
if (VersionStringListSizeInBytes != firstStr.size() + 1) {
return false;
}
}

return true;
}

static void VerifyRDATMatches(_In_ ValidationContext &ValCtx,
_In_reads_bytes_(RDATSize) const void *pRDATData,
Expand Down Expand Up @@ -5657,6 +5730,16 @@ HRESULT ValidateDxilContainerParts(llvm::Module *pModule,
case DFCC_FeatureInfo:
VerifyFeatureInfoMatches(ValCtx, GetDxilPartData(pPart), pPart->PartSize);
break;
case DFCC_CompilerVersion:
// Either this blob is a PDB, or it is a library with shader model at least 6.8
if (ValCtx.isLibProfile) {
if (!ValidateCompilerVersionPart((void *)GetDxilPartData(pPart), pPart->PartSize))
{
ValCtx.EmitFormatError(ValidationRule::ContainerPartInvalid, { szFourCC });
}
}
break;

case DFCC_RootSignature:
pRootSignaturePart = pPart;
if (ValCtx.isLibProfile) {
Expand Down
Loading

0 comments on commit b9bd7bb

Please sign in to comment.