Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/MC/DXContainerRootSignature.cpp
213766 views
1
//===- llvm/MC/DXContainerRootSignature.cpp - RootSignature -*- C++ -*-=======//
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
#include "llvm/MC/DXContainerRootSignature.h"
10
#include "llvm/ADT/SmallString.h"
11
#include "llvm/Support/EndianStream.h"
12
13
using namespace llvm;
14
using namespace llvm::mcdxbc;
15
16
static uint32_t writePlaceholder(raw_svector_ostream &Stream) {
17
const uint32_t DummyValue = std::numeric_limits<uint32_t>::max();
18
uint32_t Offset = Stream.tell();
19
support::endian::write(Stream, DummyValue, llvm::endianness::little);
20
return Offset;
21
}
22
23
static void rewriteOffsetToCurrentByte(raw_svector_ostream &Stream,
24
uint32_t Offset) {
25
uint32_t Value =
26
support::endian::byte_swap<uint32_t, llvm::endianness::little>(
27
Stream.tell());
28
Stream.pwrite(reinterpret_cast<const char *>(&Value), sizeof(Value), Offset);
29
}
30
31
size_t RootSignatureDesc::getSize() const {
32
size_t Size =
33
sizeof(dxbc::RTS0::v1::RootSignatureHeader) +
34
ParametersContainer.size() * sizeof(dxbc::RTS0::v1::RootParameterHeader) +
35
StaticSamplers.size() * sizeof(dxbc::RTS0::v1::StaticSampler);
36
37
for (const RootParameterInfo &I : ParametersContainer) {
38
switch (I.Header.ParameterType) {
39
case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit):
40
Size += sizeof(dxbc::RTS0::v1::RootConstants);
41
break;
42
case llvm::to_underlying(dxbc::RootParameterType::CBV):
43
case llvm::to_underlying(dxbc::RootParameterType::SRV):
44
case llvm::to_underlying(dxbc::RootParameterType::UAV):
45
if (Version == 1)
46
Size += sizeof(dxbc::RTS0::v1::RootDescriptor);
47
else
48
Size += sizeof(dxbc::RTS0::v2::RootDescriptor);
49
50
break;
51
case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable):
52
const DescriptorTable &Table =
53
ParametersContainer.getDescriptorTable(I.Location);
54
55
// 4 bytes for the number of ranges in table and
56
// 4 bytes for the ranges offset
57
Size += 2 * sizeof(uint32_t);
58
if (Version == 1)
59
Size += sizeof(dxbc::RTS0::v1::DescriptorRange) * Table.Ranges.size();
60
else
61
Size += sizeof(dxbc::RTS0::v2::DescriptorRange) * Table.Ranges.size();
62
break;
63
}
64
}
65
return Size;
66
}
67
68
void RootSignatureDesc::write(raw_ostream &OS) const {
69
SmallString<256> Storage;
70
raw_svector_ostream BOS(Storage);
71
BOS.reserveExtraSpace(getSize());
72
73
const uint32_t NumParameters = ParametersContainer.size();
74
const uint32_t NumSamplers = StaticSamplers.size();
75
support::endian::write(BOS, Version, llvm::endianness::little);
76
support::endian::write(BOS, NumParameters, llvm::endianness::little);
77
support::endian::write(BOS, RootParameterOffset, llvm::endianness::little);
78
support::endian::write(BOS, NumSamplers, llvm::endianness::little);
79
uint32_t SSO = StaticSamplersOffset;
80
if (NumSamplers > 0)
81
SSO = writePlaceholder(BOS);
82
else
83
support::endian::write(BOS, SSO, llvm::endianness::little);
84
support::endian::write(BOS, Flags, llvm::endianness::little);
85
86
SmallVector<uint32_t> ParamsOffsets;
87
for (const RootParameterInfo &P : ParametersContainer) {
88
support::endian::write(BOS, P.Header.ParameterType,
89
llvm::endianness::little);
90
support::endian::write(BOS, P.Header.ShaderVisibility,
91
llvm::endianness::little);
92
93
ParamsOffsets.push_back(writePlaceholder(BOS));
94
}
95
96
assert(NumParameters == ParamsOffsets.size());
97
for (size_t I = 0; I < NumParameters; ++I) {
98
rewriteOffsetToCurrentByte(BOS, ParamsOffsets[I]);
99
const auto &[Type, Loc] = ParametersContainer.getTypeAndLocForParameter(I);
100
switch (Type) {
101
case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit): {
102
const dxbc::RTS0::v1::RootConstants &Constants =
103
ParametersContainer.getConstant(Loc);
104
support::endian::write(BOS, Constants.ShaderRegister,
105
llvm::endianness::little);
106
support::endian::write(BOS, Constants.RegisterSpace,
107
llvm::endianness::little);
108
support::endian::write(BOS, Constants.Num32BitValues,
109
llvm::endianness::little);
110
break;
111
}
112
case llvm::to_underlying(dxbc::RootParameterType::CBV):
113
case llvm::to_underlying(dxbc::RootParameterType::SRV):
114
case llvm::to_underlying(dxbc::RootParameterType::UAV): {
115
const dxbc::RTS0::v2::RootDescriptor &Descriptor =
116
ParametersContainer.getRootDescriptor(Loc);
117
118
support::endian::write(BOS, Descriptor.ShaderRegister,
119
llvm::endianness::little);
120
support::endian::write(BOS, Descriptor.RegisterSpace,
121
llvm::endianness::little);
122
if (Version > 1)
123
support::endian::write(BOS, Descriptor.Flags, llvm::endianness::little);
124
break;
125
}
126
case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {
127
const DescriptorTable &Table =
128
ParametersContainer.getDescriptorTable(Loc);
129
support::endian::write(BOS, (uint32_t)Table.Ranges.size(),
130
llvm::endianness::little);
131
rewriteOffsetToCurrentByte(BOS, writePlaceholder(BOS));
132
for (const auto &Range : Table) {
133
support::endian::write(BOS, Range.RangeType, llvm::endianness::little);
134
support::endian::write(BOS, Range.NumDescriptors,
135
llvm::endianness::little);
136
support::endian::write(BOS, Range.BaseShaderRegister,
137
llvm::endianness::little);
138
support::endian::write(BOS, Range.RegisterSpace,
139
llvm::endianness::little);
140
if (Version > 1)
141
support::endian::write(BOS, Range.Flags, llvm::endianness::little);
142
support::endian::write(BOS, Range.OffsetInDescriptorsFromTableStart,
143
llvm::endianness::little);
144
}
145
break;
146
}
147
}
148
}
149
if (NumSamplers > 0) {
150
rewriteOffsetToCurrentByte(BOS, SSO);
151
for (const auto &S : StaticSamplers) {
152
support::endian::write(BOS, S.Filter, llvm::endianness::little);
153
support::endian::write(BOS, S.AddressU, llvm::endianness::little);
154
support::endian::write(BOS, S.AddressV, llvm::endianness::little);
155
support::endian::write(BOS, S.AddressW, llvm::endianness::little);
156
support::endian::write(BOS, S.MipLODBias, llvm::endianness::little);
157
support::endian::write(BOS, S.MaxAnisotropy, llvm::endianness::little);
158
support::endian::write(BOS, S.ComparisonFunc, llvm::endianness::little);
159
support::endian::write(BOS, S.BorderColor, llvm::endianness::little);
160
support::endian::write(BOS, S.MinLOD, llvm::endianness::little);
161
support::endian::write(BOS, S.MaxLOD, llvm::endianness::little);
162
support::endian::write(BOS, S.ShaderRegister, llvm::endianness::little);
163
support::endian::write(BOS, S.RegisterSpace, llvm::endianness::little);
164
support::endian::write(BOS, S.ShaderVisibility, llvm::endianness::little);
165
}
166
}
167
assert(Storage.size() == getSize());
168
OS.write(Storage.data(), Storage.size());
169
}
170
171