195 строки
6.3 KiB
C++
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
|