DirectXShaderCompiler/lib/DxilRootSignature/DxilRootSignature.cpp

195 строки
6.3 KiB
C++

///////////////////////////////////////////////////////////////////////////////
// //
// DxilRootSignature.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. //
// //
// Provides support for manipulating root signature structures. //
// //
///////////////////////////////////////////////////////////////////////////////
#include "dxc/DXIL/DxilConstants.h"
#include "dxc/DxilRootSignature/DxilRootSignature.h"
#include "dxc/DxilContainer/DxilPipelineStateValidation.h"
#include "dxc/Support/Global.h"
#include "dxc/Support/WinIncludes.h"
#include "dxc/Support/WinFunctions.h"
#include "dxc/Support/FileIOHelper.h"
#include "dxc/dxcapi.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include <string>
#include <algorithm>
#include <utility>
#include <vector>
#include <set>
#include "DxilRootSignatureHelper.h"
using namespace llvm;
using std::string;
namespace hlsl {
//////////////////////////////////////////////////////////////////////////////
// Root signature handler.
RootSignatureHandle::RootSignatureHandle(RootSignatureHandle&& other) {
m_pDesc = nullptr;
m_pSerialized = nullptr;
std::swap(m_pDesc, other.m_pDesc);
std::swap(m_pSerialized, other.m_pSerialized);
}
void RootSignatureHandle::Assign(const DxilVersionedRootSignatureDesc *pDesc,
IDxcBlob *pSerialized) {
Clear();
m_pDesc = pDesc;
m_pSerialized = pSerialized;
if (m_pSerialized)
m_pSerialized->AddRef();
}
void RootSignatureHandle::Clear() {
hlsl::DeleteRootSignature(m_pDesc);
m_pDesc = nullptr;
if (m_pSerialized != nullptr) {
m_pSerialized->Release();
m_pSerialized = nullptr;
}
}
const uint8_t *RootSignatureHandle::GetSerializedBytes() const {
DXASSERT_NOMSG(m_pSerialized != nullptr);
return (uint8_t *)m_pSerialized->GetBufferPointer();
}
unsigned RootSignatureHandle::GetSerializedSize() const {
DXASSERT_NOMSG(m_pSerialized != nullptr);
return m_pSerialized->GetBufferSize();
}
void RootSignatureHandle::EnsureSerializedAvailable() {
DXASSERT_NOMSG(!IsEmpty());
if (m_pSerialized == nullptr) {
CComPtr<IDxcBlob> pResult;
hlsl::SerializeRootSignature(m_pDesc, &pResult, nullptr, false);
IFTBOOL(pResult != nullptr, E_FAIL);
m_pSerialized = pResult.Detach();
}
}
void RootSignatureHandle::Deserialize() {
DXASSERT_NOMSG(m_pSerialized && !m_pDesc);
DeserializeRootSignature((uint8_t*)m_pSerialized->GetBufferPointer(), (uint32_t)m_pSerialized->GetBufferSize(), &m_pDesc);
}
void RootSignatureHandle::LoadSerialized(const uint8_t *pData,
unsigned length) {
DXASSERT_NOMSG(IsEmpty());
IDxcBlobEncoding *pCreated;
IFT(DxcCreateBlobWithEncodingOnHeapCopy(pData, length, CP_UTF8, &pCreated));
m_pSerialized = pCreated;
}
//////////////////////////////////////////////////////////////////////////////
namespace root_sig_helper {
// GetFlags/SetFlags overloads.
DxilRootDescriptorFlags GetFlags(const DxilRootDescriptor &) {
// Upconvert root parameter flags to be volatile.
return DxilRootDescriptorFlags::DataVolatile;
}
void SetFlags(DxilRootDescriptor &, DxilRootDescriptorFlags) {
// Drop the flags; none existed in rs_1_0.
}
DxilRootDescriptorFlags GetFlags(const DxilRootDescriptor1 &D) {
return D.Flags;
}
void SetFlags(DxilRootDescriptor1 &D, DxilRootDescriptorFlags Flags) {
D.Flags = Flags;
}
void SetFlags(DxilContainerRootDescriptor1 &D, DxilRootDescriptorFlags Flags) {
D.Flags = (uint32_t)Flags;
}
DxilDescriptorRangeFlags GetFlags(const DxilDescriptorRange &D) {
// Upconvert range flags to be volatile.
DxilDescriptorRangeFlags Flags =
DxilDescriptorRangeFlags::DescriptorsVolatile;
// Sampler does not have data.
if (D.RangeType != DxilDescriptorRangeType::Sampler)
Flags = (DxilDescriptorRangeFlags)(
(unsigned)Flags | (unsigned)DxilDescriptorRangeFlags::DataVolatile);
return Flags;
}
void SetFlags(DxilDescriptorRange &, DxilDescriptorRangeFlags) {}
DxilDescriptorRangeFlags GetFlags(const DxilContainerDescriptorRange &D) {
// Upconvert range flags to be volatile.
DxilDescriptorRangeFlags Flags =
DxilDescriptorRangeFlags::DescriptorsVolatile;
// Sampler does not have data.
if (D.RangeType != (uint32_t)DxilDescriptorRangeType::Sampler)
Flags |= DxilDescriptorRangeFlags::DataVolatile;
return Flags;
}
void SetFlags(DxilContainerDescriptorRange &, DxilDescriptorRangeFlags) {}
DxilDescriptorRangeFlags GetFlags(const DxilDescriptorRange1 &D) {
return D.Flags;
}
void SetFlags(DxilDescriptorRange1 &D, DxilDescriptorRangeFlags Flags) {
D.Flags = Flags;
}
DxilDescriptorRangeFlags GetFlags(const DxilContainerDescriptorRange1 &D) {
return (DxilDescriptorRangeFlags)D.Flags;
}
void SetFlags(DxilContainerDescriptorRange1 &D,
DxilDescriptorRangeFlags Flags) {
D.Flags = (uint32_t)Flags;
}
} // namespace root_sig_helper
//////////////////////////////////////////////////////////////////////////////
template <typename T>
void DeleteRootSignatureTemplate(const T &RS) {
for (unsigned i = 0; i < RS.NumParameters; i++) {
const auto &P = RS.pParameters[i];
if (P.ParameterType == DxilRootParameterType::DescriptorTable) {
delete[] P.DescriptorTable.pDescriptorRanges;
}
}
delete[] RS.pParameters;
delete[] RS.pStaticSamplers;
}
void DeleteRootSignature(const DxilVersionedRootSignatureDesc * pRootSignature)
{
if (pRootSignature == nullptr)
return;
switch (pRootSignature->Version)
{
case DxilRootSignatureVersion::Version_1_0:
DeleteRootSignatureTemplate<DxilRootSignatureDesc>(pRootSignature->Desc_1_0);
break;
case DxilRootSignatureVersion::Version_1_1:
default:
DXASSERT(pRootSignature->Version == DxilRootSignatureVersion::Version_1_1, "else version is incorrect");
DeleteRootSignatureTemplate<DxilRootSignatureDesc1>(pRootSignature->Desc_1_1);
break;
}
delete pRootSignature;
}
} // namespace hlsl