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