/////////////////////////////////////////////////////////////////////////////// // // // 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 #include #include #include #include #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 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 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(pRootSignature->Desc_1_0); break; case DxilRootSignatureVersion::Version_1_1: default: DXASSERT(pRootSignature->Version == DxilRootSignatureVersion::Version_1_1, "else version is incorrect"); DeleteRootSignatureTemplate(pRootSignature->Desc_1_1); break; } delete pRootSignature; } } // namespace hlsl