LLVM 24.0.0git
SemanticSignaturePacking.cpp
Go to the documentation of this file.
1//===- SemanticSignaturePacking.cpp - HLSL signature packing helpers -----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file This file implements helpers for packing HLSL semantic signatures.
10///
11//===----------------------------------------------------------------------===//
12
14#include "llvm/ADT/STLExtras.h"
15#include <algorithm>
16#include <cassert>
17#include <cstdint>
18#include <limits>
19
20using namespace llvm;
21using namespace llvm::hlsl;
22
24
26 switch (Kind) {
28 OS << "signature elements do not fit in " << MaxSignatureRows << " rows";
29 break;
31 OS << "semantic index must be less than " << MaxSignatureRows;
32 break;
33 }
34 OS << " (element " << ElementIndex << ")";
35}
36
39 Triple::EnvironmentType ShaderStage, IOType IOTy) {
40 assert(ShaderStage == Triple::Vertex && IOTy == IOType::In &&
41 "stacked packing is only valid for a vertex shader input signature");
42
43 unsigned NextRow = 0;
44 for (auto &&[Index, Element] : enumerate(Elements)) {
45 assert(Element.StartRow == UnallocatedRow &&
46 Element.StartCol == UnallocatedCol && "already allocated?");
47 assert(Element.Rows > 0 && "signature element must have at least one row");
48 assert(Element.Cols > 0 && Element.Cols <= MaxSignatureCols &&
49 "signature element must have between 1 and 4 columns");
50
51 SemanticInterpretation Interpretation =
52 getInterpretationKind(Element.SemanticKind, ShaderStage, IOTy);
53 if (Interpretation == SemanticInterpretation::NotAllocated)
54 continue;
55
56 assert((Interpretation == SemanticInterpretation::Arbitrary ||
57 Interpretation == SemanticInterpretation::SV ||
58 Interpretation == SemanticInterpretation::SGV) &&
59 "unexpected semantic interpretation for stacked packing, should "
60 "have been diagnosed by Sema");
61
62 if (Element.Rows > MaxSignatureRows - NextRow)
65 static_cast<unsigned>(Index));
66
67 Element.StartRow = NextRow;
68 Element.StartCol = 0;
69 NextRow += Element.Rows;
70 }
71
72 return NextRow;
73}
74
77 Triple::EnvironmentType ShaderStage, IOType IOTy) {
78 assert(ShaderStage == Triple::Pixel && IOTy == IOType::Out &&
79 "indexed packing is only valid for a pixel shader output signature");
80
81 static_assert(MaxSignatureRows <= std::numeric_limits<uint32_t>::digits,
82 "row allocation mask is too small");
83 [[maybe_unused]] uint32_t AllocatedRows = 0;
84 unsigned NumRows = 0;
85 for (auto &&[Index, Element] : enumerate(Elements)) {
86 assert(Element.StartRow == UnallocatedRow &&
87 Element.StartCol == UnallocatedCol && "already allocated?");
88 assert(Element.Rows > 0 && "signature element must have at least one row");
89 assert(Element.Cols > 0 && Element.Cols <= MaxSignatureCols &&
90 "signature element must have between 1 and 4 columns");
91
92 SemanticInterpretation Interpretation =
93 getInterpretationKind(Element.SemanticKind, ShaderStage, IOTy);
94 if (Interpretation == SemanticInterpretation::NotAllocated)
95 continue;
96
97 assert(Interpretation == SemanticInterpretation::Target &&
98 "unexpected semantic interpretation for indexed packing, should "
99 "have been diagnosed by Sema");
100 assert(Element.Rows == 1 && Element.SemanticIndices.size() == 1 &&
101 "target elements must occupy one semantic row");
102
103 const uint32_t Row = Element.SemanticIndices.front();
104 if (Row >= MaxSignatureRows)
107 static_cast<unsigned>(Index));
108
109 const uint32_t RowMask = uint32_t{1} << Row;
110 assert(!(AllocatedRows & RowMask) &&
111 "target semantic indices must be unique, verified in SemaHLSL");
112 AllocatedRows |= RowMask;
113
114 Element.StartRow = Row;
115 Element.StartCol = 0;
116 NumRows = std::max(NumRows, Row + 1);
117 }
118
119 return NumRows;
120}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains some templates that are useful if you are working with the STL at all.
Tagged union holding either a T or a Error.
Definition Error.h:485
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:294
void log(raw_ostream &OS) const override
Print an error message to an output stream.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
static constexpr uint32_t UnallocatedRow
LLVM_ABI Expected< unsigned > packSignatureStacked(MutableArrayRef< SemanticSignatureElement > Elements, Triple::EnvironmentType ShaderStage, IOType IOTy)
Packs eligible signature elements into consecutive rows.
LLVM_ABI SemanticInterpretation getInterpretationKind(dxbc::PSV::SemanticKind SemanticKind, Triple::EnvironmentType ShaderStage, IOType IOTy)
LLVM_ABI Expected< unsigned > packSignatureIndexed(MutableArrayRef< SemanticSignatureElement > Elements, Triple::EnvironmentType ShaderStage, IOType IOTy)
Packs eligible signature elements at rows selected by semantic index.
static constexpr unsigned MaxSignatureRows
static constexpr uint8_t UnallocatedCol
static constexpr unsigned MaxSignatureCols
This is an optimization pass for GlobalISel generic memory operations.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340