Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DXIL] Adding support to RootSignatureFlags in obj2yaml #122396

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions llvm/include/llvm/BinaryFormat/DXContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,15 @@ struct ShaderHash {
void swapBytes() { sys::swapByteOrder(Flags); }
};

struct RootSignatureDesc {
uint32_t Version;
uint32_t Flags;
void swapBytes() {
sys::swapByteOrder(Version);
sys::swapByteOrder(Flags);
}
};

struct ContainerVersion {
uint16_t Major;
uint16_t Minor;
Expand Down Expand Up @@ -152,6 +161,11 @@ enum class FeatureFlags : uint64_t {
static_assert((uint64_t)FeatureFlags::NextUnusedBit <= 1ull << 63,
"Shader flag bits exceed enum size.");

#define ROOT_ELEMENT_FLAG(Num, Val, Str) Val = 1ull << Num,
enum class RootElementFlag : uint32_t {
#include "DXContainerConstants.def"
};

PartType parsePartType(StringRef S);

struct VertexPSVInfo {
Expand Down
20 changes: 20 additions & 0 deletions llvm/include/llvm/BinaryFormat/DXContainerConstants.def
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ CONTAINER_PART(DXIL)
CONTAINER_PART(SFI0)
CONTAINER_PART(HASH)
CONTAINER_PART(PSV0)
CONTAINER_PART(RTS0)
CONTAINER_PART(ISG1)
CONTAINER_PART(OSG1)
CONTAINER_PART(PSG1)
Expand Down Expand Up @@ -52,6 +53,25 @@ SHADER_FEATURE_FLAG(31, 36, NextUnusedBit, "Next reserved shader flag bit (not a
#undef SHADER_FEATURE_FLAG
#endif // SHADER_FEATURE_FLAG

#ifdef ROOT_ELEMENT_FLAG

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could add a similar description as we have in the other enums


ROOT_ELEMENT_FLAG(0, AllowInputAssemblerInputLayout, "The app is opting in to using the Input Assembler")
ROOT_ELEMENT_FLAG(1, DenyVertexShaderRootAccess, "Denies the vertex shader access to the root signature.")
ROOT_ELEMENT_FLAG(2, DenyHullShaderRootAccess, "Denies the hull shader access to the root signature.")
ROOT_ELEMENT_FLAG(3, DenyDomainShaderRootAccess, "Denies the domain shader access to the root signature.")
ROOT_ELEMENT_FLAG(4, DenyGeometryShaderRootAccess, "Denies the geometry shader access to the root signature.")
ROOT_ELEMENT_FLAG(5, DenyPixelShaderRootAccess, "Denies the pixel shader access to the root signature.")
ROOT_ELEMENT_FLAG(6, AllowStreamOutput, "The app is opting in to using Stream Output.")
ROOT_ELEMENT_FLAG(7, LocalRootSignature, "The root signature is to be used with raytracing shaders to define resource bindings sourced from shader records in shader tables.")
ROOT_ELEMENT_FLAG(8, DenyAmplificationShaderRootAccess, "Denies the amplification shader access to the root signature.")
ROOT_ELEMENT_FLAG(9, DenyMeshShaderRootAccess, "Denies the mesh shader access to the root signature.")
ROOT_ELEMENT_FLAG(10, CBVSRVUAVHeapDirectlyIndexed, "The shaders are allowed to index the CBV/SRV/UAV descriptor heap directly, using the ResourceDescriptorHeap built-in variable.")
ROOT_ELEMENT_FLAG(11, SamplerHeapDirectlyIndexed, "The shaders are allowed to index the sampler descriptor heap directly, using the SamplerDescriptorHeap built-in variable.")
#undef ROOT_ELEMENT_FLAG
#endif // ROOT_ELEMENT_FLAG


#ifdef DXIL_MODULE_FLAG

// Only save DXIL module flags which not map to feature flags here.
Expand Down
27 changes: 27 additions & 0 deletions llvm/include/llvm/MC/DXContainerRootSignature.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//===- llvm/MC/DXContainerRootSignature.h - DXContainer RootSignature -*- C++
//-------*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <cstdint>
#include <limits>

namespace llvm {

class raw_ostream;

namespace mcdxbc {
struct RootSignatureHeader {
uint32_t Version;
uint32_t Flags;

void swapBytes();
void write(raw_ostream &OS,
uint32_t Version = std::numeric_limits<uint32_t>::max());
};
} // namespace mcdxbc
} // namespace llvm
25 changes: 25 additions & 0 deletions llvm/include/llvm/Object/DXContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include "llvm/Support/MemoryBufferRef.h"
#include "llvm/TargetParser/Triple.h"
#include <array>
#include <cstdint>
#include <sys/types.h>
#include <variant>

namespace llvm {
Expand Down Expand Up @@ -116,6 +118,23 @@ template <typename T> struct ViewArray {
};

namespace DirectX {

class RootSignature {
private:
StringRef Data;
uint32_t Version;
uint32_t Flags;

public:
RootSignature(StringRef Data) : Data(Data) {}

Error parse();

uint32_t getVersion() const { return Version; }

uint32_t getFlags() const { return Flags; }
};

class PSVRuntimeInfo {

using ResourceArray = ViewArray<dxbc::PSV::v2::ResourceBindInfo>;
Expand Down Expand Up @@ -287,6 +306,7 @@ class DXContainer {
std::optional<uint64_t> ShaderFeatureFlags;
std::optional<dxbc::ShaderHash> Hash;
std::optional<DirectX::PSVRuntimeInfo> PSVInfo;
std::optional<DirectX::RootSignature> RootSignature;
DirectX::Signature InputSignature;
DirectX::Signature OutputSignature;
DirectX::Signature PatchConstantSignature;
Expand All @@ -296,6 +316,7 @@ class DXContainer {
Error parseDXILHeader(StringRef Part);
Error parseShaderFeatureFlags(StringRef Part);
Error parseHash(StringRef Part);
Error parseRootSignature(StringRef Part);
Error parsePSVInfo(StringRef Part);
Error parseSignature(StringRef Part, DirectX::Signature &Array);
friend class PartIterator;
Expand Down Expand Up @@ -382,6 +403,10 @@ class DXContainer {

std::optional<dxbc::ShaderHash> getShaderHash() const { return Hash; }

std::optional<DirectX::RootSignature> getRootSignature() const {
return RootSignature;
}

const std::optional<DirectX::PSVRuntimeInfo> &getPSVInfo() const {
return PSVInfo;
};
Expand Down
17 changes: 17 additions & 0 deletions llvm/include/llvm/ObjectYAML/DXContainerYAML.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/Object/DXContainer.h"
#include "llvm/ObjectYAML/YAML.h"
#include "llvm/Support/YAMLTraits.h"
#include <array>
Expand Down Expand Up @@ -72,6 +73,16 @@ struct ShaderHash {
std::vector<llvm::yaml::Hex8> Digest;
};

#define ROOT_ELEMENT_FLAG(Num, Val, Str) bool Val = false;
struct RootSignatureDesc {
RootSignatureDesc() = default;
RootSignatureDesc(const object::DirectX::RootSignature &Data);

uint32_t getEncodedFlags();
uint32_t Version;
#include "llvm/BinaryFormat/DXContainerConstants.def"
};

using ResourceFlags = dxbc::PSV::ResourceFlags;
using ResourceBindInfo = dxbc::PSV::v2::ResourceBindInfo;

Expand Down Expand Up @@ -159,6 +170,7 @@ struct Part {
std::optional<ShaderHash> Hash;
std::optional<PSVInfo> Info;
std::optional<DXContainerYAML::Signature> Signature;
std::optional<DXContainerYAML::RootSignatureDesc> RootSignature;
};

struct Object {
Expand Down Expand Up @@ -241,6 +253,11 @@ template <> struct MappingTraits<DXContainerYAML::Signature> {
static void mapping(IO &IO, llvm::DXContainerYAML::Signature &El);
};

template <> struct MappingTraits<DXContainerYAML::RootSignatureDesc> {
static void mapping(IO &IO,
DXContainerYAML::RootSignatureDesc &RootSignature);
};

} // namespace yaml

} // namespace llvm
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/MC/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
add_llvm_component_library(LLVMMC
ConstantPools.cpp
DXContainerPSVInfo.cpp
DXContainerRootSignature.cpp
ELFObjectWriter.cpp
GOFFObjectWriter.cpp
MCAsmBackend.cpp
Expand Down
29 changes: 29 additions & 0 deletions llvm/lib/MC/DXContainerRootSignature.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//===- llvm/MC/DXContainerRootSignature.cpp - DXContainer RootSignature -*- C++
//-------*-===//
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like clang format wrapped your header.

//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/MC/DXContainerRootSignature.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/SwapByteOrder.h"
#include <iterator>

using namespace llvm;
using namespace llvm::mcdxbc;

void RootSignatureHeader::write(raw_ostream &OS, uint32_t Version) {

uint32_t SizeInfo = sizeof(this);
// support::endian::write(OS, SizeInfo, llvm::endianness::little);

if (sys::IsBigEndianHost) {
sys::swapByteOrder(Version);
sys::swapByteOrder(Flags);
}

OS.write(reinterpret_cast<const char *>(this), SizeInfo);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're writing the size without byte-swapping, and byte swapping the fields (in place) without writing them.

This seems wrong. Wouldn't it be better to just write:

uint32_t SizeInfo = sizeof(this);
support::endian::write(OS, SizeInfo, llvm::endianness::little);
support::endian::write(OS, Version, llvm::endianness::little);
support::endian::write(OS, Flags, llvm::endianness::little);

}
28 changes: 28 additions & 0 deletions llvm/lib/Object/DXContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,16 @@ Error DXContainer::parseHash(StringRef Part) {
return Error::success();
}

Error DXContainer::parseRootSignature(StringRef Part) {
if (RootSignature)
return parseFailed("More than one RTS0 part is present in the file");
DirectX::RootSignature Desc(Part);
if (Error Err = Desc.parse())
return Err;
RootSignature = Desc;
return Error::success();
}

Error DXContainer::parsePSVInfo(StringRef Part) {
if (PSVInfo)
return parseFailed("More than one PSV0 part is present in the file");
Expand Down Expand Up @@ -193,6 +203,10 @@ Error DXContainer::parsePartOffsets() {
break;
case dxbc::PartType::Unknown:
break;
case dxbc::PartType::RTS0:
if (Error Err = parseRootSignature(PartData))
return Err;
break;
}
}

Expand Down Expand Up @@ -228,6 +242,20 @@ void DXContainer::PartIterator::updateIteratorImpl(const uint32_t Offset) {
IteratorState.Offset = Offset;
}

Error DirectX::RootSignature::parse() {
const char *Current = Data.begin();
dxbc::RootSignatureDesc Desc;
if (Error Err = readStruct(Data, Current, Desc))
return Err;

if (sys::IsBigEndianHost)
Desc.swapBytes();

Version = Desc.Version;
Flags = Desc.Flags;
return Error::success();
}

Error DirectX::PSVRuntimeInfo::parse(uint16_t ShaderKind) {
Triple::EnvironmentType ShaderStage = dxbc::getShaderStage(ShaderKind);

Expand Down
11 changes: 11 additions & 0 deletions llvm/lib/ObjectYAML/DXContainerEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/MC/DXContainerPSVInfo.h"
#include "llvm/MC/DXContainerRootSignature.h"
#include "llvm/ObjectYAML/ObjectYAML.h"
#include "llvm/ObjectYAML/yaml2obj.h"
#include "llvm/Support/Errc.h"
Expand Down Expand Up @@ -261,6 +262,16 @@ void DXContainerWriter::writeParts(raw_ostream &OS) {
}
case dxbc::PartType::Unknown:
break; // Skip any handling for unrecognized parts.
case dxbc::PartType::RTS0:
if (!P.RootSignature.has_value())
continue;

mcdxbc::RootSignatureHeader Header;
Header.Version = P.RootSignature->Version;
Header.Flags = P.RootSignature->getEncodedFlags();

Header.write(OS);
break;
}
uint64_t BytesWritten = OS.tell() - DataStart;
RollingOffset += BytesWritten;
Expand Down
28 changes: 28 additions & 0 deletions llvm/lib/ObjectYAML/DXContainerYAML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
#include "llvm/ObjectYAML/DXContainerYAML.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/Object/DXContainer.h"
#include "llvm/Support/ScopedPrinter.h"
#include <cstdint>

namespace llvm {

Expand All @@ -29,6 +31,24 @@ DXContainerYAML::ShaderFeatureFlags::ShaderFeatureFlags(uint64_t FlagData) {
#include "llvm/BinaryFormat/DXContainerConstants.def"
}

DXContainerYAML::RootSignatureDesc::RootSignatureDesc(
const object::DirectX::RootSignature &Data)
: Version(Data.getVersion()) {
uint32_t Flags = Data.getFlags();
#define ROOT_ELEMENT_FLAG(Num, Val, Str) \
Val = (Flags & (uint32_t)dxbc::RootElementFlag::Val) > 0;
#include "llvm/BinaryFormat/DXContainerConstants.def"
}

uint32_t DXContainerYAML::RootSignatureDesc::getEncodedFlags() {
uint64_t Flag = 0;
#define ROOT_ELEMENT_FLAG(Num, Val, Str) \
if (Val) \
Flag |= (uint32_t)dxbc::RootElementFlag::Val;
#include "llvm/BinaryFormat/DXContainerConstants.def"
return Flag;
}

uint64_t DXContainerYAML::ShaderFeatureFlags::getEncodedFlags() {
uint64_t Flag = 0;
#define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str) \
Expand Down Expand Up @@ -188,6 +208,13 @@ void MappingTraits<DXContainerYAML::Signature>::mapping(
IO.mapRequired("Parameters", S.Parameters);
}

void MappingTraits<DXContainerYAML::RootSignatureDesc>::mapping(
IO &IO, DXContainerYAML::RootSignatureDesc &S) {
IO.mapRequired("Version", S.Version);
#define ROOT_ELEMENT_FLAG(Num, Val, Str) IO.mapRequired(#Val, S.Val);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could instead consider doing this as a mapOptional with false as the default value. That would make it more concise in the YAML representation.

#include "llvm/BinaryFormat/DXContainerConstants.def"
}

void MappingTraits<DXContainerYAML::Part>::mapping(IO &IO,
DXContainerYAML::Part &P) {
IO.mapRequired("Name", P.Name);
Expand All @@ -197,6 +224,7 @@ void MappingTraits<DXContainerYAML::Part>::mapping(IO &IO,
IO.mapOptional("Hash", P.Hash);
IO.mapOptional("PSVInfo", P.Info);
IO.mapOptional("Signature", P.Signature);
IO.mapOptional("RootSignature", P.RootSignature);
}

void MappingTraits<DXContainerYAML::Object>::mapping(
Expand Down
Loading
Loading