
- Defines a new declaration node `HLSLRootSignature` in `DeclNodes.td` that will consist of a `TrailingObjects` of the in-memory construction of the root signature, namely an array of `hlsl::rootsig::RootElement`s - Defines a new clang attr `RootSignature` which simply holds an identifier to a corresponding root signature declaration as above - Integrate the `HLSLRootSignatureParser` to construct the decl node in `ParseMicrosoftAttributes` and then attach the parsed attr with an identifier to the entry point function declaration. - Defines the various required declaration methods - Add testing that the declaration and reference attr are created correctly, and some syntactical error tests. It was previously proposed that we could have the root elements reference be stored directly as an additional member of the attribute and to not have a separate root signature decl. In contrast, by defining them separately as this change proposes, we will allow a unique root signature to have its own declaration in the AST tree. This allows us to only construct a single root signature for all duplicate root signature attributes. Having it located directly as a declaration might also prove advantageous when we consider root signature libraries. Resolves https://github.com/llvm/llvm-project/issues/119011
166 lines
4.1 KiB
C++
166 lines
4.1 KiB
C++
//===- HLSLRootSignature.cpp - HLSL Root Signature helper objects ---------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// \file This file contains helpers for working with HLSL Root Signatures.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Frontend/HLSL/HLSLRootSignature.h"
|
|
#include "llvm/ADT/bit.h"
|
|
|
|
namespace llvm {
|
|
namespace hlsl {
|
|
namespace rootsig {
|
|
|
|
static raw_ostream &operator<<(raw_ostream &OS, const Register &Reg) {
|
|
switch (Reg.ViewType) {
|
|
case RegisterType::BReg:
|
|
OS << "b";
|
|
break;
|
|
case RegisterType::TReg:
|
|
OS << "t";
|
|
break;
|
|
case RegisterType::UReg:
|
|
OS << "u";
|
|
break;
|
|
case RegisterType::SReg:
|
|
OS << "s";
|
|
break;
|
|
}
|
|
OS << Reg.Number;
|
|
return OS;
|
|
}
|
|
|
|
static raw_ostream &operator<<(raw_ostream &OS,
|
|
const ShaderVisibility &Visibility) {
|
|
switch (Visibility) {
|
|
case ShaderVisibility::All:
|
|
OS << "All";
|
|
break;
|
|
case ShaderVisibility::Vertex:
|
|
OS << "Vertex";
|
|
break;
|
|
case ShaderVisibility::Hull:
|
|
OS << "Hull";
|
|
break;
|
|
case ShaderVisibility::Domain:
|
|
OS << "Domain";
|
|
break;
|
|
case ShaderVisibility::Geometry:
|
|
OS << "Geometry";
|
|
break;
|
|
case ShaderVisibility::Pixel:
|
|
OS << "Pixel";
|
|
break;
|
|
case ShaderVisibility::Amplification:
|
|
OS << "Amplification";
|
|
break;
|
|
case ShaderVisibility::Mesh:
|
|
OS << "Mesh";
|
|
break;
|
|
}
|
|
|
|
return OS;
|
|
}
|
|
|
|
void DescriptorTable::dump(raw_ostream &OS) const {
|
|
OS << "DescriptorTable(numClauses = " << NumClauses
|
|
<< ", visibility = " << Visibility << ")";
|
|
}
|
|
|
|
static raw_ostream &operator<<(raw_ostream &OS, const ClauseType &Type) {
|
|
switch (Type) {
|
|
case ClauseType::CBuffer:
|
|
OS << "CBV";
|
|
break;
|
|
case ClauseType::SRV:
|
|
OS << "SRV";
|
|
break;
|
|
case ClauseType::UAV:
|
|
OS << "UAV";
|
|
break;
|
|
case ClauseType::Sampler:
|
|
OS << "Sampler";
|
|
break;
|
|
}
|
|
|
|
return OS;
|
|
}
|
|
|
|
static raw_ostream &operator<<(raw_ostream &OS,
|
|
const DescriptorRangeFlags &Flags) {
|
|
bool FlagSet = false;
|
|
unsigned Remaining = llvm::to_underlying(Flags);
|
|
while (Remaining) {
|
|
unsigned Bit = 1u << llvm::countr_zero(Remaining);
|
|
if (Remaining & Bit) {
|
|
if (FlagSet)
|
|
OS << " | ";
|
|
|
|
switch (static_cast<DescriptorRangeFlags>(Bit)) {
|
|
case DescriptorRangeFlags::DescriptorsVolatile:
|
|
OS << "DescriptorsVolatile";
|
|
break;
|
|
case DescriptorRangeFlags::DataVolatile:
|
|
OS << "DataVolatile";
|
|
break;
|
|
case DescriptorRangeFlags::DataStaticWhileSetAtExecute:
|
|
OS << "DataStaticWhileSetAtExecute";
|
|
break;
|
|
case DescriptorRangeFlags::DataStatic:
|
|
OS << "DataStatic";
|
|
break;
|
|
case DescriptorRangeFlags::DescriptorsStaticKeepingBufferBoundsChecks:
|
|
OS << "DescriptorsStaticKeepingBufferBoundsChecks";
|
|
break;
|
|
default:
|
|
OS << "invalid: " << Bit;
|
|
break;
|
|
}
|
|
|
|
FlagSet = true;
|
|
}
|
|
Remaining &= ~Bit;
|
|
}
|
|
|
|
if (!FlagSet)
|
|
OS << "None";
|
|
|
|
return OS;
|
|
}
|
|
|
|
void DescriptorTableClause::dump(raw_ostream &OS) const {
|
|
OS << Type << "(" << Reg << ", numDescriptors = " << NumDescriptors
|
|
<< ", space = " << Space << ", offset = ";
|
|
if (Offset == DescriptorTableOffsetAppend)
|
|
OS << "DescriptorTableOffsetAppend";
|
|
else
|
|
OS << Offset;
|
|
OS << ", flags = " << Flags << ")";
|
|
}
|
|
|
|
void dumpRootElements(raw_ostream &OS, ArrayRef<RootElement> Elements) {
|
|
OS << "RootElements{";
|
|
bool First = true;
|
|
for (const RootElement &Element : Elements) {
|
|
if (!First)
|
|
OS << ",";
|
|
OS << " ";
|
|
First = false;
|
|
if (const auto &Clause = std::get_if<DescriptorTableClause>(&Element))
|
|
Clause->dump(OS);
|
|
if (const auto &Table = std::get_if<DescriptorTable>(&Element))
|
|
Table->dump(OS);
|
|
}
|
|
OS << "}";
|
|
}
|
|
|
|
} // namespace rootsig
|
|
} // namespace hlsl
|
|
} // namespace llvm
|