Line data Source code
1 : //
2 : // Copyright (c) 2014 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 : // UtilsHLSL.cpp:
7 : // Utility methods for GLSL to HLSL translation.
8 : //
9 :
10 : #include "compiler/translator/UtilsHLSL.h"
11 : #include "compiler/translator/IntermNode.h"
12 : #include "compiler/translator/StructureHLSL.h"
13 : #include "compiler/translator/SymbolTable.h"
14 :
15 : namespace sh
16 : {
17 :
18 0 : TString SamplerString(const TBasicType type)
19 : {
20 0 : if (IsShadowSampler(type))
21 : {
22 0 : return "SamplerComparisonState";
23 : }
24 : else
25 : {
26 0 : return "SamplerState";
27 : }
28 : }
29 :
30 0 : TString SamplerString(HLSLTextureSamplerGroup type)
31 : {
32 0 : if (type >= HLSL_COMPARISON_SAMPLER_GROUP_BEGIN && type <= HLSL_COMPARISON_SAMPLER_GROUP_END)
33 : {
34 0 : return "SamplerComparisonState";
35 : }
36 : else
37 : {
38 0 : return "SamplerState";
39 : }
40 : }
41 :
42 0 : HLSLTextureSamplerGroup TextureGroup(const TBasicType type)
43 : {
44 0 : switch (type)
45 : {
46 : case EbtSampler2D:
47 0 : return HLSL_TEXTURE_2D;
48 : case EbtSamplerCube:
49 0 : return HLSL_TEXTURE_CUBE;
50 : case EbtSamplerExternalOES:
51 0 : return HLSL_TEXTURE_2D;
52 : case EbtSampler2DArray:
53 0 : return HLSL_TEXTURE_2D_ARRAY;
54 : case EbtSampler3D:
55 0 : return HLSL_TEXTURE_3D;
56 : case EbtISampler2D:
57 0 : return HLSL_TEXTURE_2D_INT4;
58 : case EbtISampler3D:
59 0 : return HLSL_TEXTURE_3D_INT4;
60 : case EbtISamplerCube:
61 0 : return HLSL_TEXTURE_2D_ARRAY_INT4;
62 : case EbtISampler2DArray:
63 0 : return HLSL_TEXTURE_2D_ARRAY_INT4;
64 : case EbtUSampler2D:
65 0 : return HLSL_TEXTURE_2D_UINT4;
66 : case EbtUSampler3D:
67 0 : return HLSL_TEXTURE_3D_UINT4;
68 : case EbtUSamplerCube:
69 0 : return HLSL_TEXTURE_2D_ARRAY_UINT4;
70 : case EbtUSampler2DArray:
71 0 : return HLSL_TEXTURE_2D_ARRAY_UINT4;
72 : case EbtSampler2DShadow:
73 0 : return HLSL_TEXTURE_2D_COMPARISON;
74 : case EbtSamplerCubeShadow:
75 0 : return HLSL_TEXTURE_CUBE_COMPARISON;
76 : case EbtSampler2DArrayShadow:
77 0 : return HLSL_TEXTURE_2D_ARRAY_COMPARISON;
78 : default:
79 0 : UNREACHABLE();
80 : }
81 : return HLSL_TEXTURE_UNKNOWN;
82 : }
83 :
84 0 : TString TextureString(const HLSLTextureSamplerGroup type)
85 : {
86 0 : switch (type)
87 : {
88 : case HLSL_TEXTURE_2D:
89 0 : return "Texture2D";
90 : case HLSL_TEXTURE_CUBE:
91 0 : return "TextureCube";
92 : case HLSL_TEXTURE_2D_ARRAY:
93 0 : return "Texture2DArray";
94 : case HLSL_TEXTURE_3D:
95 0 : return "Texture3D";
96 : case HLSL_TEXTURE_2D_INT4:
97 0 : return "Texture2D<int4>";
98 : case HLSL_TEXTURE_3D_INT4:
99 0 : return "Texture3D<int4>";
100 : case HLSL_TEXTURE_2D_ARRAY_INT4:
101 0 : return "Texture2DArray<int4>";
102 : case HLSL_TEXTURE_2D_UINT4:
103 0 : return "Texture2D<uint4>";
104 : case HLSL_TEXTURE_3D_UINT4:
105 0 : return "Texture3D<uint4>";
106 : case HLSL_TEXTURE_2D_ARRAY_UINT4:
107 0 : return "Texture2DArray<uint4>";
108 : case HLSL_TEXTURE_2D_COMPARISON:
109 0 : return "Texture2D";
110 : case HLSL_TEXTURE_CUBE_COMPARISON:
111 0 : return "TextureCube";
112 : case HLSL_TEXTURE_2D_ARRAY_COMPARISON:
113 0 : return "Texture2DArray";
114 : default:
115 0 : UNREACHABLE();
116 : }
117 :
118 : return "<unknown texture type>";
119 : }
120 :
121 0 : TString TextureString(const TBasicType type)
122 : {
123 0 : return TextureString(TextureGroup(type));
124 : }
125 :
126 0 : TString TextureGroupSuffix(const HLSLTextureSamplerGroup type)
127 : {
128 0 : switch (type)
129 : {
130 : case HLSL_TEXTURE_2D:
131 0 : return "2D";
132 : case HLSL_TEXTURE_CUBE:
133 0 : return "Cube";
134 : case HLSL_TEXTURE_2D_ARRAY:
135 0 : return "2DArray";
136 : case HLSL_TEXTURE_3D:
137 0 : return "3D";
138 : case HLSL_TEXTURE_2D_INT4:
139 0 : return "2D_int4_";
140 : case HLSL_TEXTURE_3D_INT4:
141 0 : return "3D_int4_";
142 : case HLSL_TEXTURE_2D_ARRAY_INT4:
143 0 : return "2DArray_int4_";
144 : case HLSL_TEXTURE_2D_UINT4:
145 0 : return "2D_uint4_";
146 : case HLSL_TEXTURE_3D_UINT4:
147 0 : return "3D_uint4_";
148 : case HLSL_TEXTURE_2D_ARRAY_UINT4:
149 0 : return "2DArray_uint4_";
150 : case HLSL_TEXTURE_2D_COMPARISON:
151 0 : return "2D_comparison";
152 : case HLSL_TEXTURE_CUBE_COMPARISON:
153 0 : return "Cube_comparison";
154 : case HLSL_TEXTURE_2D_ARRAY_COMPARISON:
155 0 : return "2DArray_comparison";
156 : default:
157 0 : UNREACHABLE();
158 : }
159 :
160 : return "<unknown texture type>";
161 : }
162 :
163 0 : TString TextureGroupSuffix(const TBasicType type)
164 : {
165 0 : return TextureGroupSuffix(TextureGroup(type));
166 : }
167 :
168 0 : TString TextureTypeSuffix(const TBasicType type)
169 : {
170 0 : switch (type)
171 : {
172 : case EbtISamplerCube:
173 0 : return "Cube_int4_";
174 : case EbtUSamplerCube:
175 0 : return "Cube_uint4_";
176 : case EbtSamplerExternalOES:
177 0 : return "_External";
178 : default:
179 : // All other types are identified by their group suffix
180 0 : return TextureGroupSuffix(type);
181 : }
182 : }
183 :
184 0 : TString DecorateUniform(const TName &name, const TType &type)
185 : {
186 0 : return DecorateIfNeeded(name);
187 : }
188 :
189 0 : TString DecorateField(const TString &string, const TStructure &structure)
190 : {
191 0 : if (structure.name().compare(0, 3, "gl_") != 0)
192 : {
193 0 : return Decorate(string);
194 : }
195 :
196 0 : return string;
197 : }
198 :
199 0 : TString DecoratePrivate(const TString &privateText)
200 : {
201 0 : return "dx_" + privateText;
202 : }
203 :
204 0 : TString Decorate(const TString &string)
205 : {
206 0 : if (string.compare(0, 3, "gl_") != 0)
207 : {
208 0 : return "_" + string;
209 : }
210 :
211 0 : return string;
212 : }
213 :
214 0 : TString DecorateIfNeeded(const TName &name)
215 : {
216 0 : if (name.isInternal())
217 : {
218 0 : return name.getString();
219 : }
220 : else
221 : {
222 0 : return Decorate(name.getString());
223 : }
224 : }
225 :
226 0 : TString DecorateFunctionIfNeeded(const TName &name)
227 : {
228 0 : if (name.isInternal())
229 : {
230 0 : return TFunction::unmangleName(name.getString());
231 : }
232 : else
233 : {
234 0 : return Decorate(TFunction::unmangleName(name.getString()));
235 : }
236 : }
237 :
238 0 : TString TypeString(const TType &type)
239 : {
240 0 : const TStructure* structure = type.getStruct();
241 0 : if (structure)
242 : {
243 0 : const TString& typeName = structure->name();
244 0 : if (typeName != "")
245 : {
246 0 : return StructNameString(*structure);
247 : }
248 : else // Nameless structure, define in place
249 : {
250 0 : return StructureHLSL::defineNameless(*structure);
251 : }
252 : }
253 0 : else if (type.isMatrix())
254 : {
255 0 : int cols = type.getCols();
256 0 : int rows = type.getRows();
257 0 : return "float" + str(cols) + "x" + str(rows);
258 : }
259 : else
260 : {
261 0 : switch (type.getBasicType())
262 : {
263 : case EbtFloat:
264 0 : switch (type.getNominalSize())
265 : {
266 0 : case 1: return "float";
267 0 : case 2: return "float2";
268 0 : case 3: return "float3";
269 0 : case 4: return "float4";
270 : }
271 : case EbtInt:
272 0 : switch (type.getNominalSize())
273 : {
274 0 : case 1: return "int";
275 0 : case 2: return "int2";
276 0 : case 3: return "int3";
277 0 : case 4: return "int4";
278 : }
279 : case EbtUInt:
280 0 : switch (type.getNominalSize())
281 : {
282 0 : case 1: return "uint";
283 0 : case 2: return "uint2";
284 0 : case 3: return "uint3";
285 0 : case 4: return "uint4";
286 : }
287 : case EbtBool:
288 0 : switch (type.getNominalSize())
289 : {
290 0 : case 1: return "bool";
291 0 : case 2: return "bool2";
292 0 : case 3: return "bool3";
293 0 : case 4: return "bool4";
294 : }
295 : case EbtVoid:
296 0 : return "void";
297 : case EbtSampler2D:
298 : case EbtISampler2D:
299 : case EbtUSampler2D:
300 : case EbtSampler2DArray:
301 : case EbtISampler2DArray:
302 : case EbtUSampler2DArray:
303 0 : return "sampler2D";
304 : case EbtSamplerCube:
305 : case EbtISamplerCube:
306 : case EbtUSamplerCube:
307 0 : return "samplerCUBE";
308 : case EbtSamplerExternalOES:
309 0 : return "sampler2D";
310 : default:
311 0 : break;
312 : }
313 : }
314 :
315 0 : UNREACHABLE();
316 : return "<unknown type>";
317 : }
318 :
319 0 : TString StructNameString(const TStructure &structure)
320 : {
321 0 : if (structure.name().empty())
322 : {
323 0 : return "";
324 : }
325 :
326 : // For structures at global scope we use a consistent
327 : // translation so that we can link between shader stages.
328 0 : if (structure.atGlobalScope())
329 : {
330 0 : return Decorate(structure.name());
331 : }
332 :
333 0 : return "ss" + str(structure.uniqueId()) + "_" + structure.name();
334 : }
335 :
336 0 : TString QualifiedStructNameString(const TStructure &structure, bool useHLSLRowMajorPacking,
337 : bool useStd140Packing)
338 : {
339 0 : if (structure.name() == "")
340 : {
341 0 : return "";
342 : }
343 :
344 0 : TString prefix = "";
345 :
346 : // Structs packed with row-major matrices in HLSL are prefixed with "rm"
347 : // GLSL column-major maps to HLSL row-major, and the converse is true
348 :
349 0 : if (useStd140Packing)
350 : {
351 0 : prefix += "std_";
352 : }
353 :
354 0 : if (useHLSLRowMajorPacking)
355 : {
356 0 : prefix += "rm_";
357 : }
358 :
359 0 : return prefix + StructNameString(structure);
360 : }
361 :
362 0 : TString InterpolationString(TQualifier qualifier)
363 : {
364 0 : switch (qualifier)
365 : {
366 0 : case EvqVaryingIn: return "";
367 0 : case EvqFragmentIn: return "";
368 0 : case EvqSmoothIn: return "linear";
369 0 : case EvqFlatIn: return "nointerpolation";
370 0 : case EvqCentroidIn: return "centroid";
371 0 : case EvqVaryingOut: return "";
372 0 : case EvqVertexOut: return "";
373 0 : case EvqSmoothOut: return "linear";
374 0 : case EvqFlatOut: return "nointerpolation";
375 0 : case EvqCentroidOut: return "centroid";
376 0 : default: UNREACHABLE();
377 : }
378 :
379 : return "";
380 : }
381 :
382 0 : TString QualifierString(TQualifier qualifier)
383 : {
384 0 : switch (qualifier)
385 : {
386 0 : case EvqIn: return "in";
387 0 : case EvqOut: return "inout"; // 'out' results in an HLSL error if not all fields are written, for GLSL it's undefined
388 0 : case EvqInOut: return "inout";
389 0 : case EvqConstReadOnly: return "const";
390 0 : default: UNREACHABLE();
391 : }
392 :
393 : return "";
394 : }
395 :
396 0 : TString DisambiguateFunctionName(const TIntermSequence *parameters)
397 : {
398 0 : TString disambiguatingString;
399 0 : for (auto parameter : *parameters)
400 : {
401 0 : const TType ¶mType = parameter->getAsTyped()->getType();
402 : // Disambiguation is needed for float2x2 and float4 parameters. These are the only parameter
403 : // types that HLSL thinks are identical. float2x3 and float3x2 are different types, for
404 : // example. Other parameter types are not added to function names to avoid making function
405 : // names longer.
406 0 : if (paramType.getObjectSize() == 4 && paramType.getBasicType() == EbtFloat)
407 : {
408 0 : disambiguatingString += "_" + TypeString(paramType);
409 : }
410 : }
411 0 : return disambiguatingString;
412 : }
413 :
414 : } // namespace sh
|