2018-10-18 04:46:43 +03:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// //
|
|
|
|
// DxilRootSignatureSerializer.cpp //
|
|
|
|
// Copyright (C) Microsoft Corporation. All rights reserved. //
|
|
|
|
// This file is distributed under the University of Illinois Open Source //
|
|
|
|
// License. See LICENSE.TXT for details. //
|
|
|
|
// //
|
|
|
|
// Serializer for root signature structures. //
|
|
|
|
// //
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#include "dxc/DXIL/DxilConstants.h"
|
|
|
|
#include "dxc/DxilRootSignature/DxilRootSignature.h"
|
2023-09-19 15:49:22 +03:00
|
|
|
#include "dxc/Support/FileIOHelper.h"
|
2018-10-18 04:46:43 +03:00
|
|
|
#include "dxc/Support/Global.h"
|
|
|
|
#include "dxc/Support/WinFunctions.h"
|
2023-09-19 15:49:22 +03:00
|
|
|
#include "dxc/Support/WinIncludes.h"
|
2018-10-18 04:46:43 +03:00
|
|
|
#include "dxc/dxcapi.h"
|
|
|
|
|
|
|
|
#include "llvm/IR/DiagnosticPrinter.h"
|
2023-09-19 15:49:22 +03:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2018-10-18 04:46:43 +03:00
|
|
|
|
|
|
|
#include <algorithm>
|
2023-09-19 15:49:22 +03:00
|
|
|
#include <set>
|
|
|
|
#include <string>
|
2018-10-18 04:46:43 +03:00
|
|
|
#include <utility>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "DxilRootSignatureHelper.h"
|
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
using std::string;
|
|
|
|
|
|
|
|
namespace hlsl {
|
|
|
|
|
|
|
|
using namespace root_sig_helper;
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Simple serializer.
|
|
|
|
|
|
|
|
class SimpleSerializer {
|
|
|
|
struct Segment {
|
|
|
|
void *pData;
|
|
|
|
unsigned cbSize;
|
|
|
|
bool bOwner;
|
|
|
|
unsigned Offset;
|
|
|
|
Segment *pNext;
|
|
|
|
};
|
|
|
|
|
|
|
|
public:
|
|
|
|
SimpleSerializer();
|
|
|
|
~SimpleSerializer();
|
|
|
|
|
|
|
|
HRESULT AddBlock(void *pData, unsigned cbSize, unsigned *pOffset);
|
|
|
|
HRESULT ReserveBlock(void **ppData, unsigned cbSize, unsigned *pOffset);
|
|
|
|
|
2023-09-14 16:59:49 +03:00
|
|
|
HRESULT Compact(char *pData, unsigned cbSize);
|
2018-10-18 04:46:43 +03:00
|
|
|
unsigned GetSize();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
unsigned m_cbSegments;
|
|
|
|
Segment *m_pSegment;
|
|
|
|
Segment **m_ppSegment;
|
|
|
|
};
|
|
|
|
|
|
|
|
SimpleSerializer::SimpleSerializer() {
|
|
|
|
m_cbSegments = 0;
|
|
|
|
m_pSegment = nullptr;
|
|
|
|
m_ppSegment = &m_pSegment;
|
|
|
|
}
|
|
|
|
|
|
|
|
SimpleSerializer::~SimpleSerializer() {
|
|
|
|
while (m_pSegment) {
|
|
|
|
Segment *pSegment = m_pSegment;
|
|
|
|
m_pSegment = pSegment->pNext;
|
|
|
|
|
|
|
|
if (pSegment->bOwner) {
|
2023-09-19 15:49:22 +03:00
|
|
|
delete[](char *) pSegment->pData;
|
2018-10-18 04:46:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
delete pSegment;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT SimpleSerializer::AddBlock(void *pData, unsigned cbSize,
|
|
|
|
unsigned *pOffset) {
|
|
|
|
Segment *pSegment = nullptr;
|
|
|
|
IFRBOOL(!(cbSize != 0 && pData == nullptr), E_FAIL);
|
|
|
|
|
|
|
|
IFROOM(pSegment = new (std::nothrow) Segment);
|
|
|
|
pSegment->pData = pData;
|
|
|
|
|
|
|
|
m_cbSegments = (m_cbSegments + 3) & ~3;
|
|
|
|
pSegment->Offset = m_cbSegments;
|
|
|
|
pSegment->cbSize = cbSize;
|
|
|
|
pSegment->bOwner = false;
|
|
|
|
pSegment->pNext = nullptr;
|
|
|
|
|
|
|
|
m_cbSegments += pSegment->cbSize;
|
|
|
|
*m_ppSegment = pSegment;
|
|
|
|
m_ppSegment = &pSegment->pNext;
|
|
|
|
|
|
|
|
if (pOffset != nullptr) {
|
|
|
|
*pOffset = pSegment->Offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT SimpleSerializer::ReserveBlock(void **ppData, unsigned cbSize,
|
|
|
|
unsigned *pOffset) {
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
Segment *pSegment = nullptr;
|
|
|
|
void *pClonedData = nullptr;
|
|
|
|
|
|
|
|
IFCOOM(pSegment = new (std::nothrow) Segment);
|
|
|
|
pSegment->pData = nullptr;
|
|
|
|
|
|
|
|
IFCOOM(pClonedData = new (std::nothrow) char[cbSize]);
|
|
|
|
pSegment->pData = pClonedData;
|
|
|
|
|
|
|
|
m_cbSegments = (m_cbSegments + 3) & ~3;
|
|
|
|
pSegment->Offset = m_cbSegments;
|
|
|
|
pSegment->cbSize = cbSize;
|
|
|
|
pSegment->bOwner = true;
|
|
|
|
pSegment->pNext = nullptr;
|
|
|
|
|
|
|
|
m_cbSegments += pSegment->cbSize;
|
|
|
|
*m_ppSegment = pSegment;
|
|
|
|
m_ppSegment = &pSegment->pNext;
|
|
|
|
|
|
|
|
*ppData = pClonedData;
|
|
|
|
if (pOffset) {
|
2023-09-29 17:28:05 +03:00
|
|
|
memcpy(pOffset, &pSegment->Offset, sizeof(pSegment->Offset));
|
2018-10-18 04:46:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
Cleanup:
|
|
|
|
if (FAILED(hr)) {
|
2023-09-19 15:49:22 +03:00
|
|
|
delete[](char *) pClonedData;
|
2018-10-18 04:46:43 +03:00
|
|
|
delete pSegment;
|
|
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
2023-09-14 16:59:49 +03:00
|
|
|
HRESULT SimpleSerializer::Compact(char *pData, unsigned cbSize) {
|
2018-10-18 04:46:43 +03:00
|
|
|
unsigned cb = GetSize();
|
|
|
|
IFRBOOL(cb <= cbSize, E_FAIL);
|
|
|
|
DXASSERT_NOMSG(cb <= UINT32_MAX / 2);
|
|
|
|
|
|
|
|
char *p = (char *)pData;
|
|
|
|
cb = 0;
|
|
|
|
|
|
|
|
for (Segment *pSegment = m_pSegment; pSegment; pSegment = pSegment->pNext) {
|
|
|
|
unsigned cbAlign = ((cb + 3) & ~3) - cb;
|
|
|
|
|
2023-09-14 16:59:49 +03:00
|
|
|
assert(p + cbAlign <= pData + cbSize);
|
2018-10-18 04:46:43 +03:00
|
|
|
memset(p, 0xab, cbAlign);
|
|
|
|
|
|
|
|
p += cbAlign;
|
|
|
|
cb += cbAlign;
|
|
|
|
|
2023-09-14 16:59:49 +03:00
|
|
|
assert(p + pSegment->cbSize <= pData + cbSize);
|
2018-10-18 04:46:43 +03:00
|
|
|
memcpy(p, pSegment->pData, pSegment->cbSize);
|
|
|
|
|
|
|
|
p += pSegment->cbSize;
|
|
|
|
cb += pSegment->cbSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Trailing zeros
|
2023-09-14 16:59:49 +03:00
|
|
|
assert(p + cbSize - cb <= pData + cbSize);
|
2018-10-18 04:46:43 +03:00
|
|
|
memset(p, 0xab, cbSize - cb);
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned SimpleSerializer::GetSize() {
|
|
|
|
// Round up to 4==sizeof(unsigned).
|
|
|
|
return ((m_cbSegments + 3) >> 2) * 4;
|
|
|
|
}
|
|
|
|
|
2023-09-14 16:59:49 +03:00
|
|
|
template <typename T_ROOT_SIGNATURE_DESC, typename T_ROOT_PARAMETER,
|
|
|
|
typename T_ROOT_DESCRIPTOR_INTERNAL,
|
|
|
|
typename T_DESCRIPTOR_RANGE_INTERNAL>
|
|
|
|
void SerializeRootSignatureTemplate(const T_ROOT_SIGNATURE_DESC *pRootSignature,
|
2018-10-18 04:46:43 +03:00
|
|
|
DxilRootSignatureVersion DescVersion,
|
2023-09-14 16:59:49 +03:00
|
|
|
IDxcBlob **ppBlob,
|
2018-10-18 04:46:43 +03:00
|
|
|
DiagnosticPrinter &DiagPrinter,
|
2023-09-14 16:59:49 +03:00
|
|
|
bool bAllowReservedRegisterSpace) {
|
2018-10-18 04:46:43 +03:00
|
|
|
DxilContainerRootSignatureDesc RS;
|
|
|
|
uint32_t Offset;
|
|
|
|
SimpleSerializer Serializer;
|
|
|
|
IFT(Serializer.AddBlock(&RS, sizeof(RS), &Offset));
|
|
|
|
IFTBOOL(Offset == 0, E_FAIL);
|
|
|
|
|
|
|
|
const T_ROOT_SIGNATURE_DESC *pRS = pRootSignature;
|
|
|
|
RS.Version = (uint32_t)DescVersion;
|
|
|
|
RS.Flags = (uint32_t)pRS->Flags;
|
|
|
|
RS.NumParameters = pRS->NumParameters;
|
|
|
|
RS.NumStaticSamplers = pRS->NumStaticSamplers;
|
|
|
|
|
|
|
|
DxilContainerRootParameter *pRP;
|
2023-09-19 15:49:22 +03:00
|
|
|
IFT(Serializer.ReserveBlock(
|
|
|
|
(void **)&pRP, sizeof(DxilContainerRootParameter) * RS.NumParameters,
|
|
|
|
&RS.RootParametersOffset));
|
2018-10-18 04:46:43 +03:00
|
|
|
|
|
|
|
for (uint32_t iRP = 0; iRP < RS.NumParameters; iRP++) {
|
|
|
|
const T_ROOT_PARAMETER *pInRP = &pRS->pParameters[iRP];
|
|
|
|
DxilContainerRootParameter *pOutRP = &pRP[iRP];
|
|
|
|
pOutRP->ParameterType = (uint32_t)pInRP->ParameterType;
|
|
|
|
pOutRP->ShaderVisibility = (uint32_t)pInRP->ShaderVisibility;
|
|
|
|
switch (pInRP->ParameterType) {
|
|
|
|
case DxilRootParameterType::DescriptorTable: {
|
|
|
|
DxilContainerRootDescriptorTable *p1;
|
2023-09-19 15:49:22 +03:00
|
|
|
IFT(Serializer.ReserveBlock((void **)&p1,
|
2018-10-18 04:46:43 +03:00
|
|
|
sizeof(DxilContainerRootDescriptorTable),
|
|
|
|
&pOutRP->PayloadOffset));
|
|
|
|
p1->NumDescriptorRanges = pInRP->DescriptorTable.NumDescriptorRanges;
|
|
|
|
|
|
|
|
T_DESCRIPTOR_RANGE_INTERNAL *p2;
|
2023-09-19 15:49:22 +03:00
|
|
|
IFT(Serializer.ReserveBlock((void **)&p2,
|
|
|
|
sizeof(T_DESCRIPTOR_RANGE_INTERNAL) *
|
|
|
|
p1->NumDescriptorRanges,
|
2018-10-18 04:46:43 +03:00
|
|
|
&p1->DescriptorRangesOffset));
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < p1->NumDescriptorRanges; i++) {
|
2023-09-19 15:49:22 +03:00
|
|
|
p2[i].RangeType =
|
|
|
|
(uint32_t)pInRP->DescriptorTable.pDescriptorRanges[i].RangeType;
|
|
|
|
p2[i].NumDescriptors =
|
|
|
|
pInRP->DescriptorTable.pDescriptorRanges[i].NumDescriptors;
|
|
|
|
p2[i].BaseShaderRegister =
|
|
|
|
pInRP->DescriptorTable.pDescriptorRanges[i].BaseShaderRegister;
|
|
|
|
p2[i].RegisterSpace =
|
|
|
|
pInRP->DescriptorTable.pDescriptorRanges[i].RegisterSpace;
|
|
|
|
p2[i].OffsetInDescriptorsFromTableStart =
|
|
|
|
pInRP->DescriptorTable.pDescriptorRanges[i]
|
|
|
|
.OffsetInDescriptorsFromTableStart;
|
|
|
|
DxilDescriptorRangeFlags Flags =
|
|
|
|
GetFlags(pInRP->DescriptorTable.pDescriptorRanges[i]);
|
2018-10-18 04:46:43 +03:00
|
|
|
SetFlags(p2[i], Flags);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case DxilRootParameterType::Constants32Bit: {
|
|
|
|
DxilRootConstants *p;
|
2023-09-19 15:49:22 +03:00
|
|
|
IFT(Serializer.ReserveBlock((void **)&p, sizeof(DxilRootConstants),
|
|
|
|
&pOutRP->PayloadOffset));
|
2018-10-18 04:46:43 +03:00
|
|
|
p->Num32BitValues = pInRP->Constants.Num32BitValues;
|
|
|
|
p->ShaderRegister = pInRP->Constants.ShaderRegister;
|
|
|
|
p->RegisterSpace = pInRP->Constants.RegisterSpace;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case DxilRootParameterType::CBV:
|
|
|
|
case DxilRootParameterType::SRV:
|
|
|
|
case DxilRootParameterType::UAV: {
|
|
|
|
T_ROOT_DESCRIPTOR_INTERNAL *p;
|
2023-09-19 15:49:22 +03:00
|
|
|
IFT(Serializer.ReserveBlock((void **)&p,
|
|
|
|
sizeof(T_ROOT_DESCRIPTOR_INTERNAL),
|
|
|
|
&pOutRP->PayloadOffset));
|
2018-10-18 04:46:43 +03:00
|
|
|
p->ShaderRegister = pInRP->Descriptor.ShaderRegister;
|
|
|
|
p->RegisterSpace = pInRP->Descriptor.RegisterSpace;
|
|
|
|
DxilRootDescriptorFlags Flags = GetFlags(pInRP->Descriptor);
|
|
|
|
SetFlags(*p, Flags);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
2023-09-19 15:49:22 +03:00
|
|
|
EAT(DiagPrinter
|
|
|
|
<< "D3DSerializeRootSignature: unknown root parameter type ("
|
|
|
|
<< (uint32_t)pInRP->ParameterType << ")\n");
|
2018-10-18 04:46:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DxilStaticSamplerDesc *pSS;
|
2023-09-19 15:49:22 +03:00
|
|
|
unsigned StaticSamplerSize =
|
|
|
|
sizeof(DxilStaticSamplerDesc) * RS.NumStaticSamplers;
|
|
|
|
IFT(Serializer.ReserveBlock((void **)&pSS, StaticSamplerSize,
|
|
|
|
&RS.StaticSamplersOffset));
|
2022-12-10 20:42:25 +03:00
|
|
|
if (StaticSamplerSize > 0)
|
|
|
|
memcpy(pSS, pRS->pStaticSamplers, StaticSamplerSize);
|
2018-10-18 04:46:43 +03:00
|
|
|
|
|
|
|
// Create the result blob.
|
|
|
|
CDxcMallocHeapPtr<char> bytes(DxcGetThreadMallocNoRef());
|
|
|
|
CComPtr<IDxcBlob> pBlob;
|
|
|
|
unsigned cb = Serializer.GetSize();
|
|
|
|
DXASSERT_NOMSG((cb & 0x3) == 0);
|
|
|
|
IFTBOOL(bytes.Allocate(cb), E_OUTOFMEMORY);
|
|
|
|
IFT(Serializer.Compact(bytes.m_pData, cb));
|
2019-04-19 01:04:06 +03:00
|
|
|
IFT(DxcCreateBlobOnMalloc(bytes.m_pData, bytes.GetMallocNoRef(), cb, ppBlob));
|
2018-10-18 04:46:43 +03:00
|
|
|
bytes.Detach(); // Ownership transfered to ppBlob.
|
|
|
|
}
|
|
|
|
|
2023-09-19 15:49:22 +03:00
|
|
|
void SerializeRootSignature(
|
|
|
|
const DxilVersionedRootSignatureDesc *pRootSignature, IDxcBlob **ppBlob,
|
|
|
|
IDxcBlobEncoding **ppErrorBlob, bool bAllowReservedRegisterSpace) {
|
2018-10-18 04:46:43 +03:00
|
|
|
DXASSERT_NOMSG(pRootSignature != nullptr);
|
|
|
|
DXASSERT_NOMSG(ppBlob != nullptr);
|
|
|
|
DXASSERT_NOMSG(ppErrorBlob != nullptr);
|
|
|
|
|
|
|
|
*ppBlob = nullptr;
|
|
|
|
*ppErrorBlob = nullptr;
|
|
|
|
|
|
|
|
// TODO: change SerializeRootSignature to take raw_ostream&
|
|
|
|
string DiagString;
|
|
|
|
raw_string_ostream DiagStream(DiagString);
|
|
|
|
DiagnosticPrinterRawOStream DiagPrinter(DiagStream);
|
|
|
|
|
|
|
|
// Verify root signature.
|
|
|
|
if (!VerifyRootSignature(pRootSignature, DiagStream,
|
|
|
|
bAllowReservedRegisterSpace)) {
|
|
|
|
DiagStream.flush();
|
2023-09-19 15:49:22 +03:00
|
|
|
DxcCreateBlobWithEncodingOnHeapCopy(DiagString.c_str(), DiagString.size(),
|
|
|
|
CP_UTF8, ppErrorBlob);
|
2018-10-18 04:46:43 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
2023-09-19 15:49:22 +03:00
|
|
|
switch (pRootSignature->Version) {
|
2018-10-18 04:46:43 +03:00
|
|
|
case DxilRootSignatureVersion::Version_1_0:
|
2023-09-19 15:49:22 +03:00
|
|
|
SerializeRootSignatureTemplate<DxilRootSignatureDesc, DxilRootParameter,
|
|
|
|
DxilRootDescriptor,
|
|
|
|
DxilContainerDescriptorRange>(
|
|
|
|
&pRootSignature->Desc_1_0, DxilRootSignatureVersion::Version_1_0,
|
|
|
|
ppBlob, DiagPrinter, bAllowReservedRegisterSpace);
|
2018-10-18 04:46:43 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DxilRootSignatureVersion::Version_1_1:
|
|
|
|
default:
|
2023-09-19 15:49:22 +03:00
|
|
|
DXASSERT(pRootSignature->Version == DxilRootSignatureVersion::Version_1_1,
|
|
|
|
"else VerifyRootSignature didn't validate");
|
|
|
|
SerializeRootSignatureTemplate<DxilRootSignatureDesc1, DxilRootParameter1,
|
|
|
|
DxilContainerRootDescriptor1,
|
|
|
|
DxilContainerDescriptorRange1>(
|
|
|
|
&pRootSignature->Desc_1_1, DxilRootSignatureVersion::Version_1_1,
|
|
|
|
ppBlob, DiagPrinter, bAllowReservedRegisterSpace);
|
2018-10-18 04:46:43 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
} catch (...) {
|
|
|
|
DiagStream.flush();
|
2023-09-19 15:49:22 +03:00
|
|
|
DxcCreateBlobWithEncodingOnHeapCopy(DiagString.c_str(), DiagString.size(),
|
|
|
|
CP_UTF8, ppErrorBlob);
|
2018-10-18 04:46:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-14 16:59:49 +03:00
|
|
|
template <typename T_ROOT_SIGNATURE_DESC, typename T_ROOT_PARAMETER,
|
|
|
|
typename T_ROOT_DESCRIPTOR, typename T_ROOT_DESCRIPTOR_INTERNAL,
|
|
|
|
typename T_DESCRIPTOR_RANGE, typename T_DESCRIPTOR_RANGE_INTERNAL>
|
|
|
|
void DeserializeRootSignatureTemplate(
|
|
|
|
const void *pSrcData, uint32_t SrcDataSizeInBytes,
|
|
|
|
DxilRootSignatureVersion DescVersion,
|
|
|
|
T_ROOT_SIGNATURE_DESC &RootSignatureDesc) {
|
2018-10-18 04:46:43 +03:00
|
|
|
// Note that in case of failure, outside code must deallocate memory.
|
|
|
|
T_ROOT_SIGNATURE_DESC *pRootSignature = &RootSignatureDesc;
|
|
|
|
const char *pData = (const char *)pSrcData;
|
|
|
|
const char *pMaxPtr = pData + SrcDataSizeInBytes;
|
|
|
|
UNREFERENCED_PARAMETER(DescVersion);
|
2023-09-19 15:49:22 +03:00
|
|
|
DXASSERT_NOMSG(((const uint32_t *)pData)[0] == (uint32_t)DescVersion);
|
2018-10-18 04:46:43 +03:00
|
|
|
|
|
|
|
// Root signature.
|
|
|
|
IFTBOOL(pData + sizeof(DxilContainerRootSignatureDesc) <= pMaxPtr, E_FAIL);
|
2023-09-19 15:49:22 +03:00
|
|
|
const DxilContainerRootSignatureDesc *pRS =
|
|
|
|
(const DxilContainerRootSignatureDesc *)pData;
|
2018-10-18 04:46:43 +03:00
|
|
|
pRootSignature->Flags = (DxilRootSignatureFlags)pRS->Flags;
|
|
|
|
pRootSignature->NumParameters = pRS->NumParameters;
|
|
|
|
pRootSignature->NumStaticSamplers = pRS->NumStaticSamplers;
|
|
|
|
// Intialize all pointers early so that clean up works properly.
|
|
|
|
pRootSignature->pParameters = nullptr;
|
|
|
|
pRootSignature->pStaticSamplers = nullptr;
|
|
|
|
|
2023-09-19 15:49:22 +03:00
|
|
|
size_t s = sizeof(DxilContainerRootParameter) * pRS->NumParameters;
|
|
|
|
const DxilContainerRootParameter *pInRTS =
|
|
|
|
(const DxilContainerRootParameter *)(pData + pRS->RootParametersOffset);
|
|
|
|
IFTBOOL(((const char *)pInRTS) + s <= pMaxPtr, E_FAIL);
|
2018-10-18 04:46:43 +03:00
|
|
|
if (pRootSignature->NumParameters) {
|
2023-09-19 15:49:22 +03:00
|
|
|
pRootSignature->pParameters =
|
|
|
|
new T_ROOT_PARAMETER[pRootSignature->NumParameters];
|
|
|
|
memset((void *)pRootSignature->pParameters, 0,
|
|
|
|
pRootSignature->NumParameters * sizeof(T_ROOT_PARAMETER));
|
2018-10-18 04:46:43 +03:00
|
|
|
}
|
|
|
|
|
2023-09-19 15:49:22 +03:00
|
|
|
for (unsigned iRP = 0; iRP < pRootSignature->NumParameters; iRP++) {
|
|
|
|
DxilRootParameterType ParameterType =
|
|
|
|
(DxilRootParameterType)pInRTS[iRP].ParameterType;
|
|
|
|
T_ROOT_PARAMETER *pOutRTS =
|
|
|
|
(T_ROOT_PARAMETER *)&pRootSignature->pParameters[iRP];
|
2018-10-18 04:46:43 +03:00
|
|
|
pOutRTS->ParameterType = ParameterType;
|
2023-09-19 15:49:22 +03:00
|
|
|
pOutRTS->ShaderVisibility =
|
|
|
|
(DxilShaderVisibility)pInRTS[iRP].ShaderVisibility;
|
|
|
|
switch (ParameterType) {
|
2018-10-18 04:46:43 +03:00
|
|
|
case DxilRootParameterType::DescriptorTable: {
|
2023-09-19 15:49:22 +03:00
|
|
|
const DxilContainerRootDescriptorTable *p1 =
|
|
|
|
(const DxilContainerRootDescriptorTable *)(pData +
|
|
|
|
pInRTS[iRP].PayloadOffset);
|
|
|
|
IFTBOOL((const char *)p1 + sizeof(DxilContainerRootDescriptorTable) <=
|
|
|
|
pMaxPtr,
|
|
|
|
E_FAIL);
|
2018-10-18 04:46:43 +03:00
|
|
|
pOutRTS->DescriptorTable.NumDescriptorRanges = p1->NumDescriptorRanges;
|
|
|
|
pOutRTS->DescriptorTable.pDescriptorRanges = nullptr;
|
2023-09-19 15:49:22 +03:00
|
|
|
const T_DESCRIPTOR_RANGE_INTERNAL *p2 =
|
|
|
|
(const T_DESCRIPTOR_RANGE_INTERNAL *)(pData +
|
|
|
|
p1->DescriptorRangesOffset);
|
|
|
|
IFTBOOL((const char *)p2 + sizeof(T_DESCRIPTOR_RANGE_INTERNAL) <= pMaxPtr,
|
|
|
|
E_FAIL);
|
2018-10-18 04:46:43 +03:00
|
|
|
if (p1->NumDescriptorRanges) {
|
2023-09-19 15:49:22 +03:00
|
|
|
pOutRTS->DescriptorTable.pDescriptorRanges =
|
|
|
|
new T_DESCRIPTOR_RANGE[p1->NumDescriptorRanges];
|
2018-10-18 04:46:43 +03:00
|
|
|
}
|
|
|
|
for (unsigned i = 0; i < p1->NumDescriptorRanges; i++) {
|
2023-09-19 15:49:22 +03:00
|
|
|
T_DESCRIPTOR_RANGE *p3 = (T_DESCRIPTOR_RANGE *)&pOutRTS->DescriptorTable
|
|
|
|
.pDescriptorRanges[i];
|
|
|
|
p3->RangeType = (DxilDescriptorRangeType)p2[i].RangeType;
|
|
|
|
p3->NumDescriptors = p2[i].NumDescriptors;
|
|
|
|
p3->BaseShaderRegister = p2[i].BaseShaderRegister;
|
|
|
|
p3->RegisterSpace = p2[i].RegisterSpace;
|
|
|
|
p3->OffsetInDescriptorsFromTableStart =
|
|
|
|
p2[i].OffsetInDescriptorsFromTableStart;
|
2018-10-18 04:46:43 +03:00
|
|
|
DxilDescriptorRangeFlags Flags = GetFlags(p2[i]);
|
|
|
|
SetFlags(*p3, Flags);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case DxilRootParameterType::Constants32Bit: {
|
2023-09-19 15:49:22 +03:00
|
|
|
const DxilRootConstants *p =
|
|
|
|
(const DxilRootConstants *)(pData + pInRTS[iRP].PayloadOffset);
|
|
|
|
IFTBOOL((const char *)p + sizeof(DxilRootConstants) <= pMaxPtr, E_FAIL);
|
2018-10-18 04:46:43 +03:00
|
|
|
pOutRTS->Constants.Num32BitValues = p->Num32BitValues;
|
|
|
|
pOutRTS->Constants.ShaderRegister = p->ShaderRegister;
|
2023-09-19 15:49:22 +03:00
|
|
|
pOutRTS->Constants.RegisterSpace = p->RegisterSpace;
|
2018-10-18 04:46:43 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case DxilRootParameterType::CBV:
|
|
|
|
case DxilRootParameterType::SRV:
|
|
|
|
case DxilRootParameterType::UAV: {
|
2023-09-19 15:49:22 +03:00
|
|
|
const T_ROOT_DESCRIPTOR *p =
|
|
|
|
(const T_ROOT_DESCRIPTOR *)(pData + pInRTS[iRP].PayloadOffset);
|
|
|
|
IFTBOOL((const char *)p + sizeof(T_ROOT_DESCRIPTOR) <= pMaxPtr, E_FAIL);
|
2018-10-18 04:46:43 +03:00
|
|
|
pOutRTS->Descriptor.ShaderRegister = p->ShaderRegister;
|
2023-09-19 15:49:22 +03:00
|
|
|
pOutRTS->Descriptor.RegisterSpace = p->RegisterSpace;
|
2018-10-18 04:46:43 +03:00
|
|
|
DxilRootDescriptorFlags Flags = GetFlags(*p);
|
|
|
|
SetFlags(pOutRTS->Descriptor, Flags);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
IFT(E_FAIL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-19 15:49:22 +03:00
|
|
|
s = sizeof(DxilStaticSamplerDesc) * pRS->NumStaticSamplers;
|
|
|
|
const DxilStaticSamplerDesc *pInSS =
|
|
|
|
(const DxilStaticSamplerDesc *)(pData + pRS->StaticSamplersOffset);
|
|
|
|
IFTBOOL(((const char *)pInSS) + s <= pMaxPtr, E_FAIL);
|
2018-10-18 04:46:43 +03:00
|
|
|
if (pRootSignature->NumStaticSamplers) {
|
2023-09-19 15:49:22 +03:00
|
|
|
pRootSignature->pStaticSamplers =
|
|
|
|
new DxilStaticSamplerDesc[pRootSignature->NumStaticSamplers];
|
|
|
|
memcpy((void *)pRootSignature->pStaticSamplers, pInSS, s);
|
2018-10-18 04:46:43 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-19 15:49:22 +03:00
|
|
|
void DeserializeRootSignature(
|
|
|
|
const void *pSrcData, uint32_t SrcDataSizeInBytes,
|
|
|
|
const DxilVersionedRootSignatureDesc **ppRootSignature) {
|
2018-10-18 04:46:43 +03:00
|
|
|
DxilVersionedRootSignatureDesc *pRootSignature = nullptr;
|
2023-09-19 15:49:22 +03:00
|
|
|
IFTBOOL(pSrcData != nullptr && SrcDataSizeInBytes != 0 &&
|
|
|
|
ppRootSignature != nullptr,
|
|
|
|
E_INVALIDARG);
|
2018-10-18 04:46:43 +03:00
|
|
|
IFTBOOL(*ppRootSignature == nullptr, E_INVALIDARG);
|
|
|
|
const char *pData = (const char *)pSrcData;
|
|
|
|
IFTBOOL(pData + sizeof(uint32_t) < pData + SrcDataSizeInBytes, E_FAIL);
|
|
|
|
|
2023-09-19 15:49:22 +03:00
|
|
|
const DxilRootSignatureVersion Version =
|
|
|
|
(const DxilRootSignatureVersion)((const uint32_t *)pData)[0];
|
2018-10-18 04:46:43 +03:00
|
|
|
|
|
|
|
pRootSignature = new DxilVersionedRootSignatureDesc();
|
|
|
|
|
|
|
|
try {
|
|
|
|
switch (Version) {
|
|
|
|
case DxilRootSignatureVersion::Version_1_0:
|
|
|
|
pRootSignature->Version = DxilRootSignatureVersion::Version_1_0;
|
2023-09-19 15:49:22 +03:00
|
|
|
DeserializeRootSignatureTemplate<DxilRootSignatureDesc, DxilRootParameter,
|
|
|
|
DxilRootDescriptor, DxilRootDescriptor,
|
|
|
|
DxilDescriptorRange,
|
|
|
|
DxilContainerDescriptorRange>(
|
|
|
|
pSrcData, SrcDataSizeInBytes, DxilRootSignatureVersion::Version_1_0,
|
|
|
|
pRootSignature->Desc_1_0);
|
2018-10-18 04:46:43 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DxilRootSignatureVersion::Version_1_1:
|
|
|
|
pRootSignature->Version = DxilRootSignatureVersion::Version_1_1;
|
|
|
|
DeserializeRootSignatureTemplate<
|
2023-09-19 15:49:22 +03:00
|
|
|
DxilRootSignatureDesc1, DxilRootParameter1, DxilRootDescriptor1,
|
|
|
|
DxilContainerRootDescriptor1, DxilDescriptorRange1,
|
|
|
|
DxilContainerDescriptorRange1>(pSrcData, SrcDataSizeInBytes,
|
|
|
|
DxilRootSignatureVersion::Version_1_1,
|
|
|
|
pRootSignature->Desc_1_1);
|
2018-10-18 04:46:43 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
IFT(E_FAIL);
|
|
|
|
break;
|
|
|
|
}
|
2023-09-19 15:49:22 +03:00
|
|
|
} catch (...) {
|
2018-10-18 04:46:43 +03:00
|
|
|
DeleteRootSignature(pRootSignature);
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
|
|
|
|
*ppRootSignature = pRootSignature;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace hlsl
|