Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/compiler/translator/ImageFunctionHLSL.cpp
1693 views
1
//
2
// Copyright 2017 The ANGLE Project Authors. All rights reserved.
3
// Use of this source code is governed by a BSD-style license that can be
4
// found in the LICENSE file.
5
//
6
// ImageFunctionHLSL: Class for writing implementations of ESSL image functions into HLSL output.
7
//
8
9
#include "compiler/translator/ImageFunctionHLSL.h"
10
#include "compiler/translator/ImmutableStringBuilder.h"
11
#include "compiler/translator/UtilsHLSL.h"
12
13
namespace sh
14
{
15
16
// static
17
ImmutableString ImageFunctionHLSL::GetImageReference(
18
TInfoSinkBase &out,
19
const ImageFunctionHLSL::ImageFunction &imageFunction)
20
{
21
static const ImmutableString kImageIndexStr("[index]");
22
if (imageFunction.readonly)
23
{
24
static const ImmutableString kReadonlyImagesStr("readonlyImages");
25
ImmutableString suffix(
26
TextureGroupSuffix(imageFunction.image, imageFunction.imageInternalFormat));
27
out << " const uint index = imageIndex - readonlyImageIndexOffset" << suffix.data()
28
<< ";\n";
29
ImmutableStringBuilder imageRefBuilder(kReadonlyImagesStr.length() + suffix.length() +
30
kImageIndexStr.length());
31
imageRefBuilder << kReadonlyImagesStr << suffix << kImageIndexStr;
32
return imageRefBuilder;
33
}
34
else
35
{
36
static const ImmutableString kImagesStr("images");
37
ImmutableString suffix(
38
RWTextureGroupSuffix(imageFunction.image, imageFunction.imageInternalFormat));
39
out << " const uint index = imageIndex - imageIndexOffset" << suffix.data() << ";\n";
40
ImmutableStringBuilder imageRefBuilder(kImagesStr.length() + suffix.length() +
41
kImageIndexStr.length());
42
imageRefBuilder << kImagesStr << suffix << kImageIndexStr;
43
return imageRefBuilder;
44
}
45
}
46
47
void ImageFunctionHLSL::OutputImageFunctionArgumentList(
48
TInfoSinkBase &out,
49
const ImageFunctionHLSL::ImageFunction &imageFunction)
50
{
51
out << "uint imageIndex";
52
53
if (imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::LOAD ||
54
imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::STORE)
55
{
56
switch (imageFunction.image)
57
{
58
case EbtImage2D:
59
case EbtIImage2D:
60
case EbtUImage2D:
61
out << ", int2 p";
62
break;
63
case EbtImage3D:
64
case EbtIImage3D:
65
case EbtUImage3D:
66
case EbtImageCube:
67
case EbtIImageCube:
68
case EbtUImageCube:
69
case EbtImage2DArray:
70
case EbtIImage2DArray:
71
case EbtUImage2DArray:
72
out << ", int3 p";
73
break;
74
default:
75
UNREACHABLE();
76
}
77
78
if (imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::STORE)
79
{
80
switch (imageFunction.image)
81
{
82
case EbtImage2D:
83
case EbtImage3D:
84
case EbtImageCube:
85
case EbtImage2DArray:
86
out << ", float4 data";
87
break;
88
case EbtIImage2D:
89
case EbtIImage3D:
90
case EbtIImageCube:
91
case EbtIImage2DArray:
92
out << ", int4 data";
93
break;
94
case EbtUImage2D:
95
case EbtUImage3D:
96
case EbtUImageCube:
97
case EbtUImage2DArray:
98
out << ", uint4 data";
99
break;
100
default:
101
UNREACHABLE();
102
}
103
}
104
}
105
}
106
107
// static
108
void ImageFunctionHLSL::OutputImageSizeFunctionBody(
109
TInfoSinkBase &out,
110
const ImageFunctionHLSL::ImageFunction &imageFunction,
111
const ImmutableString &imageReference)
112
{
113
if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) ||
114
IsImageCube(imageFunction.image))
115
{
116
// "depth" stores either the number of layers in an array texture or 3D depth
117
out << " uint width; uint height; uint depth;\n"
118
<< " " << imageReference << ".GetDimensions(width, height, depth);\n";
119
}
120
else if (IsImage2D(imageFunction.image))
121
{
122
out << " uint width; uint height;\n"
123
<< " " << imageReference << ".GetDimensions(width, height);\n";
124
}
125
else
126
UNREACHABLE();
127
128
if (strcmp(imageFunction.getReturnType(), "int3") == 0)
129
{
130
out << " return int3(width, height, depth);\n";
131
}
132
else
133
{
134
out << " return int2(width, height);\n";
135
}
136
}
137
138
// static
139
void ImageFunctionHLSL::OutputImageLoadFunctionBody(
140
TInfoSinkBase &out,
141
const ImageFunctionHLSL::ImageFunction &imageFunction,
142
const ImmutableString &imageReference)
143
{
144
if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) ||
145
IsImageCube(imageFunction.image))
146
{
147
out << " return " << imageReference << "[uint3(p.x, p.y, p.z)];\n";
148
}
149
else if (IsImage2D(imageFunction.image))
150
{
151
out << " return " << imageReference << "[uint2(p.x, p.y)];\n";
152
}
153
else
154
UNREACHABLE();
155
}
156
157
// static
158
void ImageFunctionHLSL::OutputImageStoreFunctionBody(
159
TInfoSinkBase &out,
160
const ImageFunctionHLSL::ImageFunction &imageFunction,
161
const ImmutableString &imageReference)
162
{
163
if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) ||
164
IsImage2D(imageFunction.image) || IsImageCube(imageFunction.image))
165
{
166
out << " " << imageReference << "[p] = data;\n";
167
}
168
else
169
UNREACHABLE();
170
}
171
172
ImmutableString ImageFunctionHLSL::ImageFunction::name() const
173
{
174
static const ImmutableString kGlImageName("gl_image");
175
176
ImmutableString suffix(nullptr);
177
if (readonly)
178
{
179
suffix = ImmutableString(TextureTypeSuffix(image, imageInternalFormat));
180
}
181
else
182
{
183
suffix = ImmutableString(RWTextureTypeSuffix(image, imageInternalFormat));
184
}
185
186
ImmutableStringBuilder name(kGlImageName.length() + suffix.length() + 5u);
187
188
name << kGlImageName << suffix;
189
190
switch (method)
191
{
192
case Method::SIZE:
193
name << "Size";
194
break;
195
case Method::LOAD:
196
name << "Load";
197
break;
198
case Method::STORE:
199
name << "Store";
200
break;
201
default:
202
UNREACHABLE();
203
}
204
205
return name;
206
}
207
208
ImageFunctionHLSL::ImageFunction::DataType ImageFunctionHLSL::ImageFunction::getDataType(
209
TLayoutImageInternalFormat format) const
210
{
211
switch (format)
212
{
213
case EiifRGBA32F:
214
case EiifRGBA16F:
215
case EiifR32F:
216
return ImageFunction::DataType::FLOAT4;
217
case EiifRGBA32UI:
218
case EiifRGBA16UI:
219
case EiifRGBA8UI:
220
case EiifR32UI:
221
return ImageFunction::DataType::UINT4;
222
case EiifRGBA32I:
223
case EiifRGBA16I:
224
case EiifRGBA8I:
225
case EiifR32I:
226
return ImageFunction::DataType::INT4;
227
case EiifRGBA8:
228
return ImageFunction::DataType::UNORM_FLOAT4;
229
case EiifRGBA8_SNORM:
230
return ImageFunction::DataType::SNORM_FLOAT4;
231
default:
232
UNREACHABLE();
233
}
234
235
return ImageFunction::DataType::NONE;
236
}
237
238
const char *ImageFunctionHLSL::ImageFunction::getReturnType() const
239
{
240
if (method == ImageFunction::Method::SIZE)
241
{
242
switch (image)
243
{
244
case EbtImage2D:
245
case EbtIImage2D:
246
case EbtUImage2D:
247
case EbtImageCube:
248
case EbtIImageCube:
249
case EbtUImageCube:
250
return "int2";
251
case EbtImage3D:
252
case EbtIImage3D:
253
case EbtUImage3D:
254
case EbtImage2DArray:
255
case EbtIImage2DArray:
256
case EbtUImage2DArray:
257
return "int3";
258
default:
259
UNREACHABLE();
260
}
261
}
262
else if (method == ImageFunction::Method::LOAD)
263
{
264
switch (image)
265
{
266
case EbtImage2D:
267
case EbtImage3D:
268
case EbtImageCube:
269
case EbtImage2DArray:
270
return "float4";
271
case EbtIImage2D:
272
case EbtIImage3D:
273
case EbtIImageCube:
274
case EbtIImage2DArray:
275
return "int4";
276
case EbtUImage2D:
277
case EbtUImage3D:
278
case EbtUImageCube:
279
case EbtUImage2DArray:
280
return "uint4";
281
default:
282
UNREACHABLE();
283
}
284
}
285
else if (method == ImageFunction::Method::STORE)
286
{
287
return "void";
288
}
289
else
290
{
291
UNREACHABLE();
292
}
293
return "";
294
}
295
296
bool ImageFunctionHLSL::ImageFunction::operator<(const ImageFunction &rhs) const
297
{
298
return std::tie(image, type, method, readonly) <
299
std::tie(rhs.image, rhs.type, rhs.method, rhs.readonly);
300
}
301
302
ImmutableString ImageFunctionHLSL::useImageFunction(const ImmutableString &name,
303
const TBasicType &type,
304
TLayoutImageInternalFormat imageInternalFormat,
305
bool readonly)
306
{
307
ASSERT(IsImage(type));
308
ImageFunction imageFunction;
309
imageFunction.image = type;
310
imageFunction.imageInternalFormat = imageInternalFormat;
311
imageFunction.readonly = readonly;
312
imageFunction.type = imageFunction.getDataType(imageInternalFormat);
313
314
if (name == "imageSize")
315
{
316
imageFunction.method = ImageFunction::Method::SIZE;
317
}
318
else if (name == "imageLoad")
319
{
320
imageFunction.method = ImageFunction::Method::LOAD;
321
}
322
else if (name == "imageStore")
323
{
324
imageFunction.method = ImageFunction::Method::STORE;
325
}
326
else
327
UNREACHABLE();
328
329
mUsesImage.insert(imageFunction);
330
return imageFunction.name();
331
}
332
333
void ImageFunctionHLSL::imageFunctionHeader(TInfoSinkBase &out)
334
{
335
for (const ImageFunction &imageFunction : mUsesImage)
336
{
337
// Skip to generate image2D functions here, dynamically generate these
338
// functions when linking, or after dispatch or draw.
339
if (IsImage2D(imageFunction.image))
340
{
341
mUsedImage2DFunctionNames.insert(imageFunction.name().data());
342
continue;
343
}
344
// Function header
345
out << imageFunction.getReturnType() << " " << imageFunction.name() << "(";
346
347
OutputImageFunctionArgumentList(out, imageFunction);
348
349
out << ")\n"
350
"{\n";
351
352
ImmutableString imageReference = GetImageReference(out, imageFunction);
353
if (imageFunction.method == ImageFunction::Method::SIZE)
354
{
355
OutputImageSizeFunctionBody(out, imageFunction, imageReference);
356
}
357
else if (imageFunction.method == ImageFunction::Method::LOAD)
358
{
359
OutputImageLoadFunctionBody(out, imageFunction, imageReference);
360
}
361
else
362
{
363
OutputImageStoreFunctionBody(out, imageFunction, imageReference);
364
}
365
366
out << "}\n"
367
"\n";
368
}
369
}
370
371
} // namespace sh
372
373