123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416 |
- ///////////////////////////////////////////////////////////////////////////////
- // //
- // DxilSubobject.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. //
- // //
- ///////////////////////////////////////////////////////////////////////////////
- #include "dxc/Support/Global.h"
- #include "dxc/Support/Unicode.h"
- #include "dxc/Support/WinIncludes.h"
- #include "dxc/DXIL/DxilSubobject.h"
- #include "dxc/DxilContainer/DxilRuntimeReflection.h"
- #include "llvm/ADT/STLExtras.h"
- namespace hlsl {
- //------------------------------------------------------------------------------
- //
- // Subobject methods.
- //
- DxilSubobject::DxilSubobject(DxilSubobject &&other)
- : m_Owner(other.m_Owner),
- m_Kind(other.m_Kind),
- m_Name(m_Owner.InternString(other.m_Name)),
- m_Exports(std::move(other.m_Exports))
- {
- DXASSERT_NOMSG(DXIL::IsValidSubobjectKind(m_Kind));
- CopyUnionedContents(other);
- }
- DxilSubobject::DxilSubobject(DxilSubobjects &owner, Kind kind, llvm::StringRef name)
- : m_Owner(owner),
- m_Kind(kind),
- m_Name(m_Owner.InternString(name)),
- m_Exports()
- {
- DXASSERT_NOMSG(DXIL::IsValidSubobjectKind(m_Kind));
- }
- DxilSubobject::DxilSubobject(DxilSubobjects &owner, const DxilSubobject &other, llvm::StringRef name)
- : m_Owner(owner),
- m_Kind(other.m_Kind),
- m_Name(name),
- m_Exports(other.m_Exports.begin(), other.m_Exports.end())
- {
- DXASSERT_NOMSG(DXIL::IsValidSubobjectKind(m_Kind));
- CopyUnionedContents(other);
- if (&m_Owner != &other.m_Owner)
- InternStrings();
- }
- void DxilSubobject::CopyUnionedContents(const DxilSubobject &other) {
- switch (m_Kind) {
- case Kind::StateObjectConfig:
- StateObjectConfig.Flags = other.StateObjectConfig.Flags;
- break;
- case Kind::GlobalRootSignature:
- case Kind::LocalRootSignature:
- RootSignature.Size = other.RootSignature.Size;
- RootSignature.Data = other.RootSignature.Data;
- break;
- case Kind::SubobjectToExportsAssociation:
- SubobjectToExportsAssociation.Subobject = other.SubobjectToExportsAssociation.Subobject;
- break;
- case Kind::RaytracingShaderConfig:
- RaytracingShaderConfig.MaxPayloadSizeInBytes = other.RaytracingShaderConfig.MaxPayloadSizeInBytes;
- RaytracingShaderConfig.MaxAttributeSizeInBytes = other.RaytracingShaderConfig.MaxAttributeSizeInBytes;
- break;
- case Kind::RaytracingPipelineConfig:
- RaytracingPipelineConfig.MaxTraceRecursionDepth = other.RaytracingPipelineConfig.MaxTraceRecursionDepth;
- break;
- case Kind::HitGroup:
- HitGroup.Type = other.HitGroup.Type;
- HitGroup.AnyHit = other.HitGroup.AnyHit;
- HitGroup.ClosestHit = other.HitGroup.ClosestHit;
- HitGroup.Intersection = other.HitGroup.Intersection;
- break;
- case Kind::RaytracingPipelineConfig1:
- RaytracingPipelineConfig1.MaxTraceRecursionDepth = other.RaytracingPipelineConfig1.MaxTraceRecursionDepth;
- RaytracingPipelineConfig1.Flags = other.RaytracingPipelineConfig1.Flags;
- break;
- default:
- DXASSERT(0, "invalid kind");
- break;
- }
- }
- void DxilSubobject::InternStrings() {
- // Transfer strings if necessary
- m_Name = m_Owner.InternString(m_Name).data();
- switch (m_Kind) {
- case Kind::SubobjectToExportsAssociation:
- SubobjectToExportsAssociation.Subobject = m_Owner.InternString(SubobjectToExportsAssociation.Subobject).data();
- for (auto &ptr : m_Exports)
- ptr = m_Owner.InternString(ptr).data();
- break;
- case Kind::HitGroup:
- HitGroup.AnyHit = m_Owner.InternString(HitGroup.AnyHit).data();
- HitGroup.ClosestHit = m_Owner.InternString(HitGroup.ClosestHit).data();
- HitGroup.Intersection = m_Owner.InternString(HitGroup.Intersection).data();
- break;
- default:
- break;
- }
- }
- DxilSubobject::~DxilSubobject() {
- }
- // StateObjectConfig
- bool DxilSubobject::GetStateObjectConfig(uint32_t &Flags) const {
- if (m_Kind == Kind::StateObjectConfig) {
- Flags = StateObjectConfig.Flags;
- return true;
- }
- return false;
- }
- // Local/Global RootSignature
- bool DxilSubobject::GetRootSignature(
- bool local, const void * &Data, uint32_t &Size, const char **pText) const {
- Kind expected = local ? Kind::LocalRootSignature : Kind::GlobalRootSignature;
- if (m_Kind == expected) {
- Data = RootSignature.Data;
- Size = RootSignature.Size;
- if (pText)
- *pText = RootSignature.Text;
- return true;
- }
- return false;
- }
- // SubobjectToExportsAssociation
- bool DxilSubobject::GetSubobjectToExportsAssociation(
- llvm::StringRef &Subobject,
- const char * const * &Exports,
- uint32_t &NumExports) const {
- if (m_Kind == Kind::SubobjectToExportsAssociation) {
- Subobject = SubobjectToExportsAssociation.Subobject;
- Exports = m_Exports.data();
- NumExports = (uint32_t)m_Exports.size();
- return true;
- }
- return false;
- }
- // RaytracingShaderConfig
- bool DxilSubobject::GetRaytracingShaderConfig(uint32_t &MaxPayloadSizeInBytes,
- uint32_t &MaxAttributeSizeInBytes) const {
- if (m_Kind == Kind::RaytracingShaderConfig) {
- MaxPayloadSizeInBytes = RaytracingShaderConfig.MaxPayloadSizeInBytes;
- MaxAttributeSizeInBytes = RaytracingShaderConfig.MaxAttributeSizeInBytes;
- return true;
- }
- return false;
- }
- // RaytracingPipelineConfig
- bool DxilSubobject::GetRaytracingPipelineConfig(
- uint32_t &MaxTraceRecursionDepth) const {
- if (m_Kind == Kind::RaytracingPipelineConfig) {
- MaxTraceRecursionDepth = RaytracingPipelineConfig.MaxTraceRecursionDepth;
- return true;
- }
- return false;
- }
- // HitGroup
- bool DxilSubobject::GetHitGroup(DXIL::HitGroupType &hitGroupType,
- llvm::StringRef &AnyHit,
- llvm::StringRef &ClosestHit,
- llvm::StringRef &Intersection) const {
- if (m_Kind == Kind::HitGroup) {
- hitGroupType = HitGroup.Type;
- AnyHit = HitGroup.AnyHit;
- ClosestHit = HitGroup.ClosestHit;
- Intersection = HitGroup.Intersection;
- return true;
- }
- return false;
- }
- // RaytracingPipelineConfig1
- bool DxilSubobject::GetRaytracingPipelineConfig1(
- uint32_t &MaxTraceRecursionDepth, uint32_t &Flags) const {
- if (m_Kind == Kind::RaytracingPipelineConfig1) {
- MaxTraceRecursionDepth = RaytracingPipelineConfig1.MaxTraceRecursionDepth;
- Flags = RaytracingPipelineConfig1.Flags;
- return true;
- }
- return false;
- }
-
- DxilSubobjects::DxilSubobjects()
- : m_BytesStorage()
- , m_Subobjects()
- {}
- DxilSubobjects::DxilSubobjects(DxilSubobjects &&other)
- : m_BytesStorage(std::move(other.m_BytesStorage))
- , m_Subobjects(std::move(other.m_Subobjects))
- {}
- DxilSubobjects::~DxilSubobjects() {}
- llvm::StringRef DxilSubobjects::InternString(llvm::StringRef value) {
- auto it = m_BytesStorage.find(value);
- if (it != m_BytesStorage.end())
- return it->first;
- size_t size = value.size();
- StoredBytes stored(std::make_pair(std::unique_ptr<char[]>(new char[size + 1]), size + 1));
- memcpy(stored.first.get(), value.data(), size);
- stored.first[size] = 0;
- llvm::StringRef key(stored.first.get(), size);
- m_BytesStorage[key] = std::move(stored);
- return key;
- }
- const void *DxilSubobjects::InternRawBytes(const void *ptr, size_t size) {
- auto it = m_BytesStorage.find(llvm::StringRef((const char *)ptr, size));
- if (it != m_BytesStorage.end())
- return it->first.data();
- StoredBytes stored(std::make_pair(std::unique_ptr<char[]>(new char[size]), size));
- memcpy(stored.first.get(), ptr, size);
- llvm::StringRef key(stored.first.get(), size);
- m_BytesStorage[key] = std::move(stored);
- return key.data();
- }
- DxilSubobject *DxilSubobjects::FindSubobject(llvm::StringRef name) {
- auto it = m_Subobjects.find(name);
- if (it != m_Subobjects.end())
- return it->second.get();
- return nullptr;
- }
- void DxilSubobjects::RemoveSubobject(llvm::StringRef name) {
- auto it = m_Subobjects.find(name);
- if (it != m_Subobjects.end())
- m_Subobjects.erase(it);
- }
- DxilSubobject &DxilSubobjects::CloneSubobject(
- const DxilSubobject &Subobject, llvm::StringRef Name) {
- Name = InternString(Name);
- DXASSERT(FindSubobject(Name) == nullptr,
- "otherwise, name collision between subobjects");
- std::unique_ptr<DxilSubobject> ptr(new DxilSubobject(*this, Subobject, Name));
- DxilSubobject &ref = *ptr;
- m_Subobjects[Name] = std::move(ptr);
- return ref;
- }
- // Create DxilSubobjects
- DxilSubobject &DxilSubobjects::CreateStateObjectConfig(
- llvm::StringRef Name, uint32_t Flags) {
- DXASSERT_NOMSG(0 == ((~(uint32_t)DXIL::StateObjectFlags::ValidMask) & Flags));
- auto &obj = CreateSubobject(Kind::StateObjectConfig, Name);
- obj.StateObjectConfig.Flags = Flags;
- return obj;
- }
- DxilSubobject &DxilSubobjects::CreateRootSignature(
- llvm::StringRef Name, bool local, const void *Data, uint32_t Size, llvm::StringRef *pText /*= nullptr*/) {
- auto &obj = CreateSubobject(local ? Kind::LocalRootSignature : Kind::GlobalRootSignature, Name);
- obj.RootSignature.Data = InternRawBytes(Data, Size);
- obj.RootSignature.Size = Size;
- obj.RootSignature.Text = (pText ? InternString(*pText).data() : nullptr);
- return obj;
- }
- DxilSubobject &DxilSubobjects::CreateSubobjectToExportsAssociation(
- llvm::StringRef Name,
- llvm::StringRef Subobject,
- llvm::StringRef *Exports,
- uint32_t NumExports) {
- auto &obj = CreateSubobject(Kind::SubobjectToExportsAssociation, Name);
- Subobject = InternString(Subobject);
- obj.SubobjectToExportsAssociation.Subobject = Subobject.data();
- for (unsigned i = 0; i < NumExports; i++) {
- obj.m_Exports.emplace_back(InternString(Exports[i]).data());
- }
- return obj;
- }
- DxilSubobject &DxilSubobjects::CreateRaytracingShaderConfig(
- llvm::StringRef Name,
- uint32_t MaxPayloadSizeInBytes,
- uint32_t MaxAttributeSizeInBytes) {
- auto &obj = CreateSubobject(Kind::RaytracingShaderConfig, Name);
- obj.RaytracingShaderConfig.MaxPayloadSizeInBytes = MaxPayloadSizeInBytes;
- obj.RaytracingShaderConfig.MaxAttributeSizeInBytes = MaxAttributeSizeInBytes;
- return obj;
- }
- DxilSubobject &DxilSubobjects::CreateRaytracingPipelineConfig(
- llvm::StringRef Name,
- uint32_t MaxTraceRecursionDepth) {
- auto &obj = CreateSubobject(Kind::RaytracingPipelineConfig, Name);
- obj.RaytracingPipelineConfig.MaxTraceRecursionDepth = MaxTraceRecursionDepth;
- return obj;
- }
- DxilSubobject &DxilSubobjects::CreateHitGroup(llvm::StringRef Name,
- DXIL::HitGroupType hitGroupType,
- llvm::StringRef AnyHit,
- llvm::StringRef ClosestHit,
- llvm::StringRef Intersection) {
- auto &obj = CreateSubobject(Kind::HitGroup, Name);
- AnyHit = InternString(AnyHit);
- ClosestHit = InternString(ClosestHit);
- Intersection = InternString(Intersection);
- obj.HitGroup.Type = hitGroupType;
- obj.HitGroup.AnyHit = AnyHit.data();
- obj.HitGroup.ClosestHit = ClosestHit.data();
- obj.HitGroup.Intersection = Intersection.data();
- return obj;
- }
- DxilSubobject &DxilSubobjects::CreateRaytracingPipelineConfig1(
- llvm::StringRef Name, uint32_t MaxTraceRecursionDepth, uint32_t Flags) {
- auto &obj = CreateSubobject(Kind::RaytracingPipelineConfig1, Name);
- obj.RaytracingPipelineConfig1.MaxTraceRecursionDepth = MaxTraceRecursionDepth;
- DXASSERT_NOMSG(
- 0 == ((~(uint32_t)DXIL::RaytracingPipelineFlags::ValidMask) & Flags));
- obj.RaytracingPipelineConfig1.Flags = Flags;
- return obj;
- }
- DxilSubobject &DxilSubobjects::CreateSubobject(Kind kind, llvm::StringRef Name) {
- Name = InternString(Name);
- IFTBOOLMSG(FindSubobject(Name) == nullptr, DXC_E_GENERAL_INTERNAL_ERROR, "Subobject name collision");
- IFTBOOLMSG(!Name.empty(), DXC_E_GENERAL_INTERNAL_ERROR, "Empty Subobject name");
- std::unique_ptr<DxilSubobject> ptr(new DxilSubobject(*this, kind, Name));
- DxilSubobject &ref = *ptr;
- m_Subobjects[Name] = std::move(ptr);
- return ref;
- }
- bool LoadSubobjectsFromRDAT(DxilSubobjects &subobjects, RDAT::SubobjectTableReader *pSubobjectTableReader) {
- if (!pSubobjectTableReader)
- return false;
- bool result = true;
- for (unsigned i = 0; i < pSubobjectTableReader->GetCount(); ++i) {
- try {
- auto reader = pSubobjectTableReader->GetItem(i);
- DXIL::SubobjectKind kind = reader.GetKind();
- bool bLocalRS = false;
- switch (kind) {
- case DXIL::SubobjectKind::StateObjectConfig:
- subobjects.CreateStateObjectConfig(reader.GetName(),
- reader.GetStateObjectConfig_Flags());
- break;
- case DXIL::SubobjectKind::LocalRootSignature:
- bLocalRS = true;
- case DXIL::SubobjectKind::GlobalRootSignature: {
- const void *pOutBytes;
- uint32_t OutSizeInBytes;
- if (!reader.GetRootSignature(&pOutBytes, &OutSizeInBytes)) {
- result = false;
- continue;
- }
- subobjects.CreateRootSignature(reader.GetName(), bLocalRS, pOutBytes, OutSizeInBytes);
- break;
- }
- case DXIL::SubobjectKind::SubobjectToExportsAssociation: {
- uint32_t NumExports = reader.GetSubobjectToExportsAssociation_NumExports();
- std::vector<llvm::StringRef> Exports;
- Exports.resize(NumExports);
- for (unsigned i = 0; i < NumExports; ++i) {
- Exports[i] = reader.GetSubobjectToExportsAssociation_Export(i);
- }
- subobjects.CreateSubobjectToExportsAssociation(reader.GetName(),
- reader.GetSubobjectToExportsAssociation_Subobject(),
- Exports.data(), NumExports);
- break;
- }
- case DXIL::SubobjectKind::RaytracingShaderConfig:
- subobjects.CreateRaytracingShaderConfig(reader.GetName(),
- reader.GetRaytracingShaderConfig_MaxPayloadSizeInBytes(),
- reader.GetRaytracingShaderConfig_MaxAttributeSizeInBytes());
- break;
- case DXIL::SubobjectKind::RaytracingPipelineConfig:
- subobjects.CreateRaytracingPipelineConfig(reader.GetName(),
- reader.GetRaytracingPipelineConfig_MaxTraceRecursionDepth());
- break;
- case DXIL::SubobjectKind::HitGroup:
- subobjects.CreateHitGroup(reader.GetName(),
- reader.GetHitGroup_Type(),
- reader.GetHitGroup_AnyHit(),
- reader.GetHitGroup_ClosestHit(),
- reader.GetHitGroup_Intersection());
- break;
- case DXIL::SubobjectKind::RaytracingPipelineConfig1:
- subobjects.CreateRaytracingPipelineConfig1(
- reader.GetName(),
- reader.GetRaytracingPipelineConfig1_MaxTraceRecursionDepth(),
- reader.GetRaytracingPipelineConfig1_Flags());
- break;
- }
- }
- catch (hlsl::Exception &) {
- result = false;
- }
- }
- return result;
- }
- } // namespace hlsl
|