blob: 3efdef6c3ebae4502cbbd0887a51bf7de6cbf295 [file] [log] [blame] [edit]
///////////////////////////////////////////////////////////////////////////////
// //
// DxilRootSignatureConvert.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. //
// //
// Convert root signature structures. //
// //
///////////////////////////////////////////////////////////////////////////////
#include "dxc/DXIL/DxilConstants.h"
#include "dxc/DxilRootSignature/DxilRootSignature.h"
#include "dxc/Support/FileIOHelper.h"
#include "dxc/Support/Global.h"
#include "dxc/Support/WinFunctions.h"
#include "dxc/Support/WinIncludes.h"
#include "dxc/dxcapi.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "DxilRootSignatureHelper.h"
using namespace llvm;
using std::string;
namespace hlsl {
using namespace root_sig_helper;
//////////////////////////////////////////////////////////////////////////////
template <typename IN_DXIL_ROOT_SIGNATURE_DESC,
typename OUT_DXIL_ROOT_SIGNATURE_DESC,
typename OUT_DXIL_ROOT_PARAMETER, typename OUT_DXIL_ROOT_DESCRIPTOR,
typename OUT_DXIL_DESCRIPTOR_RANGE>
void ConvertRootSignatureTemplate(const IN_DXIL_ROOT_SIGNATURE_DESC &DescIn,
DxilRootSignatureVersion DescVersionOut,
OUT_DXIL_ROOT_SIGNATURE_DESC &DescOut) {
const IN_DXIL_ROOT_SIGNATURE_DESC *pDescIn = &DescIn;
OUT_DXIL_ROOT_SIGNATURE_DESC *pDescOut = &DescOut;
// Root signature descriptor.
pDescOut->Flags = pDescIn->Flags;
pDescOut->NumParameters = 0;
pDescOut->NumStaticSamplers = 0;
// Intialize all pointers early so that clean up works properly.
pDescOut->pParameters = nullptr;
pDescOut->pStaticSamplers = nullptr;
// Root signature parameters.
if (pDescIn->NumParameters > 0) {
pDescOut->pParameters = new OUT_DXIL_ROOT_PARAMETER[pDescIn->NumParameters];
pDescOut->NumParameters = pDescIn->NumParameters;
memset((void *)pDescOut->pParameters, 0,
pDescOut->NumParameters * sizeof(OUT_DXIL_ROOT_PARAMETER));
}
for (unsigned iRP = 0; iRP < pDescIn->NumParameters; iRP++) {
const auto &ParamIn = pDescIn->pParameters[iRP];
OUT_DXIL_ROOT_PARAMETER &ParamOut =
(OUT_DXIL_ROOT_PARAMETER &)pDescOut->pParameters[iRP];
ParamOut.ParameterType = ParamIn.ParameterType;
ParamOut.ShaderVisibility = ParamIn.ShaderVisibility;
switch (ParamIn.ParameterType) {
case DxilRootParameterType::DescriptorTable: {
ParamOut.DescriptorTable.pDescriptorRanges = nullptr;
unsigned NumRanges = ParamIn.DescriptorTable.NumDescriptorRanges;
if (NumRanges > 0) {
ParamOut.DescriptorTable.pDescriptorRanges =
new OUT_DXIL_DESCRIPTOR_RANGE[NumRanges];
ParamOut.DescriptorTable.NumDescriptorRanges = NumRanges;
}
for (unsigned i = 0; i < NumRanges; i++) {
const auto &RangeIn = ParamIn.DescriptorTable.pDescriptorRanges[i];
OUT_DXIL_DESCRIPTOR_RANGE &RangeOut =
(OUT_DXIL_DESCRIPTOR_RANGE &)
ParamOut.DescriptorTable.pDescriptorRanges[i];
RangeOut.RangeType = RangeIn.RangeType;
RangeOut.NumDescriptors = RangeIn.NumDescriptors;
RangeOut.BaseShaderRegister = RangeIn.BaseShaderRegister;
RangeOut.RegisterSpace = RangeIn.RegisterSpace;
RangeOut.OffsetInDescriptorsFromTableStart =
RangeIn.OffsetInDescriptorsFromTableStart;
DxilDescriptorRangeFlags Flags = GetFlags(RangeIn);
SetFlags(RangeOut, Flags);
}
break;
}
case DxilRootParameterType::Constants32Bit: {
ParamOut.Constants.Num32BitValues = ParamIn.Constants.Num32BitValues;
ParamOut.Constants.ShaderRegister = ParamIn.Constants.ShaderRegister;
ParamOut.Constants.RegisterSpace = ParamIn.Constants.RegisterSpace;
break;
}
case DxilRootParameterType::CBV:
case DxilRootParameterType::SRV:
case DxilRootParameterType::UAV: {
ParamOut.Descriptor.ShaderRegister = ParamIn.Descriptor.ShaderRegister;
ParamOut.Descriptor.RegisterSpace = ParamIn.Descriptor.RegisterSpace;
DxilRootDescriptorFlags Flags = GetFlags(ParamIn.Descriptor);
SetFlags(ParamOut.Descriptor, Flags);
break;
}
default:
IFT(E_FAIL);
}
}
// Static samplers.
if (pDescIn->NumStaticSamplers > 0) {
pDescOut->pStaticSamplers =
new DxilStaticSamplerDesc[pDescIn->NumStaticSamplers];
pDescOut->NumStaticSamplers = pDescIn->NumStaticSamplers;
memcpy((void *)pDescOut->pStaticSamplers, pDescIn->pStaticSamplers,
pDescOut->NumStaticSamplers * sizeof(DxilStaticSamplerDesc));
}
}
void ConvertRootSignature(
const DxilVersionedRootSignatureDesc *pRootSignatureIn,
DxilRootSignatureVersion RootSignatureVersionOut,
const DxilVersionedRootSignatureDesc **ppRootSignatureOut) {
IFTBOOL(pRootSignatureIn != nullptr && ppRootSignatureOut != nullptr,
E_INVALIDARG);
*ppRootSignatureOut = nullptr;
if (pRootSignatureIn->Version == RootSignatureVersionOut) {
// No conversion. Return the original root signature pointer; no cloning.
*ppRootSignatureOut = pRootSignatureIn;
return;
}
DxilVersionedRootSignatureDesc *pRootSignatureOut = nullptr;
try {
pRootSignatureOut = new DxilVersionedRootSignatureDesc();
memset(pRootSignatureOut, 0, sizeof(*pRootSignatureOut));
// Convert root signature.
switch (RootSignatureVersionOut) {
case DxilRootSignatureVersion::Version_1_0:
switch (pRootSignatureIn->Version) {
case DxilRootSignatureVersion::Version_1_1:
pRootSignatureOut->Version = DxilRootSignatureVersion::Version_1_0;
ConvertRootSignatureTemplate<DxilRootSignatureDesc1,
DxilRootSignatureDesc, DxilRootParameter,
DxilRootDescriptor, DxilDescriptorRange>(
pRootSignatureIn->Desc_1_1, DxilRootSignatureVersion::Version_1_0,
pRootSignatureOut->Desc_1_0);
break;
default:
IFT(E_INVALIDARG);
}
break;
case DxilRootSignatureVersion::Version_1_1:
switch (pRootSignatureIn->Version) {
case DxilRootSignatureVersion::Version_1_0:
pRootSignatureOut->Version = DxilRootSignatureVersion::Version_1_1;
ConvertRootSignatureTemplate<DxilRootSignatureDesc,
DxilRootSignatureDesc1, DxilRootParameter1,
DxilRootDescriptor1, DxilDescriptorRange1>(
pRootSignatureIn->Desc_1_0, DxilRootSignatureVersion::Version_1_1,
pRootSignatureOut->Desc_1_1);
break;
default:
IFT(E_INVALIDARG);
}
break;
default:
IFT(E_INVALIDARG);
break;
}
} catch (...) {
DeleteRootSignature(pRootSignatureOut);
throw;
}
*ppRootSignatureOut = pRootSignatureOut;
}
} // namespace hlsl