blob: c0ceef9e99fb48e14e6f46daeea7196b2e87e6b4 [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
18TString SamplerString(const TType &type)
19{
20 if (IsShadowSampler(type.getBasicType()))
21 {
22 return "SamplerComparisonState";
23 }
24 else
25 {
26 return "SamplerState";
27 }
28}
29
30TString TextureString(const TType &type)
31{
32 switch (type.getBasicType())
33 {
34 case EbtSampler2D: return "Texture2D";
35 case EbtSamplerCube: return "TextureCube";
36 case EbtSamplerExternalOES: return "Texture2D";
37 case EbtSampler2DArray: return "Texture2DArray";
38 case EbtSampler3D: return "Texture3D";
39 case EbtISampler2D: return "Texture2D<int4>";
40 case EbtISampler3D: return "Texture3D<int4>";
41 case EbtISamplerCube: return "Texture2DArray<int4>";
42 case EbtISampler2DArray: return "Texture2DArray<int4>";
43 case EbtUSampler2D: return "Texture2D<uint4>";
44 case EbtUSampler3D: return "Texture3D<uint4>";
45 case EbtUSamplerCube: return "Texture2DArray<uint4>";
46 case EbtUSampler2DArray: return "Texture2DArray<uint4>";
47 case EbtSampler2DShadow: return "Texture2D";
48 case EbtSamplerCubeShadow: return "TextureCube";
49 case EbtSampler2DArrayShadow: return "Texture2DArray";
50 default: UNREACHABLE();
51 }
52
53 return "<unknown texture type>";
54}
55
56TString DecorateUniform(const TString &string, const TType &type)
57{
58 if (type.getBasicType() == EbtSamplerExternalOES)
59 {
60 return "ex_" + string;
61 }
62
63 return Decorate(string);
64}
65
66TString DecorateField(const TString &string, const TStructure &structure)
67{
68 if (structure.name().compare(0, 3, "gl_") != 0)
69 {
70 return Decorate(string);
71 }
72
73 return string;
74}
75
76TString DecoratePrivate(const TString &privateText)
77{
78 return "dx_" + privateText;
79}
80
81TString Decorate(const TString &string)
82{
Jamie Madilld5512cd2014-07-10 17:50:08 -040083 if (string.compare(0, 3, "gl_") != 0)
Jamie Madill033dae62014-06-18 12:56:28 -040084 {
85 return "_" + string;
86 }
87
88 return string;
89}
90
Olli Etuahof5cfc8d2015-08-06 16:36:39 +030091TString DecorateIfNeeded(const TName &name)
92{
93 if (name.isInternal())
94 {
95 return name.getString();
96 }
97 else
98 {
99 return Decorate(name.getString());
100 }
101}
102
Olli Etuaho59f9a642015-08-06 20:38:26 +0300103TString DecorateFunctionIfNeeded(const TName &name)
104{
105 if (name.isInternal())
106 {
107 return TFunction::unmangleName(name.getString());
108 }
109 else
110 {
111 return Decorate(TFunction::unmangleName(name.getString()));
112 }
113}
114
Jamie Madill033dae62014-06-18 12:56:28 -0400115TString TypeString(const TType &type)
116{
117 const TStructure* structure = type.getStruct();
118 if (structure)
119 {
120 const TString& typeName = structure->name();
121 if (typeName != "")
122 {
123 return StructNameString(*structure);
124 }
125 else // Nameless structure, define in place
126 {
Jamie Madill8daaba12014-06-13 10:04:33 -0400127 return StructureHLSL::defineNameless(*structure);
Jamie Madill033dae62014-06-18 12:56:28 -0400128 }
129 }
130 else if (type.isMatrix())
131 {
132 int cols = type.getCols();
133 int rows = type.getRows();
134 return "float" + str(cols) + "x" + str(rows);
135 }
136 else
137 {
138 switch (type.getBasicType())
139 {
140 case EbtFloat:
141 switch (type.getNominalSize())
142 {
143 case 1: return "float";
144 case 2: return "float2";
145 case 3: return "float3";
146 case 4: return "float4";
147 }
148 case EbtInt:
149 switch (type.getNominalSize())
150 {
151 case 1: return "int";
152 case 2: return "int2";
153 case 3: return "int3";
154 case 4: return "int4";
155 }
156 case EbtUInt:
157 switch (type.getNominalSize())
158 {
159 case 1: return "uint";
160 case 2: return "uint2";
161 case 3: return "uint3";
162 case 4: return "uint4";
163 }
164 case EbtBool:
165 switch (type.getNominalSize())
166 {
167 case 1: return "bool";
168 case 2: return "bool2";
169 case 3: return "bool3";
170 case 4: return "bool4";
171 }
172 case EbtVoid:
173 return "void";
174 case EbtSampler2D:
175 case EbtISampler2D:
176 case EbtUSampler2D:
177 case EbtSampler2DArray:
178 case EbtISampler2DArray:
179 case EbtUSampler2DArray:
180 return "sampler2D";
181 case EbtSamplerCube:
182 case EbtISamplerCube:
183 case EbtUSamplerCube:
184 return "samplerCUBE";
185 case EbtSamplerExternalOES:
186 return "sampler2D";
187 default:
188 break;
189 }
190 }
191
192 UNREACHABLE();
193 return "<unknown type>";
194}
195
196TString StructNameString(const TStructure &structure)
197{
198 if (structure.name().empty())
199 {
200 return "";
201 }
202
Jamie Madill9b820842015-02-12 10:40:10 -0500203 // For structures at global scope we use a consistent
204 // translation so that we can link between shader stages.
205 if (structure.atGlobalScope())
206 {
207 return Decorate(structure.name());
208 }
209
Jamie Madill8daaba12014-06-13 10:04:33 -0400210 return "ss" + str(structure.uniqueId()) + "_" + structure.name();
Jamie Madill033dae62014-06-18 12:56:28 -0400211}
212
213TString QualifiedStructNameString(const TStructure &structure, bool useHLSLRowMajorPacking,
214 bool useStd140Packing)
215{
216 if (structure.name() == "")
217 {
218 return "";
219 }
220
221 TString prefix = "";
222
223 // Structs packed with row-major matrices in HLSL are prefixed with "rm"
224 // GLSL column-major maps to HLSL row-major, and the converse is true
225
226 if (useStd140Packing)
227 {
Jamie Madill8daaba12014-06-13 10:04:33 -0400228 prefix += "std_";
Jamie Madill033dae62014-06-18 12:56:28 -0400229 }
230
231 if (useHLSLRowMajorPacking)
232 {
Jamie Madill8daaba12014-06-13 10:04:33 -0400233 prefix += "rm_";
Jamie Madill033dae62014-06-18 12:56:28 -0400234 }
235
236 return prefix + StructNameString(structure);
237}
238
239TString InterpolationString(TQualifier qualifier)
240{
241 switch (qualifier)
242 {
243 case EvqVaryingIn: return "";
244 case EvqFragmentIn: return "";
Jamie Madill033dae62014-06-18 12:56:28 -0400245 case EvqSmoothIn: return "linear";
246 case EvqFlatIn: return "nointerpolation";
247 case EvqCentroidIn: return "centroid";
248 case EvqVaryingOut: return "";
249 case EvqVertexOut: return "";
Jamie Madill033dae62014-06-18 12:56:28 -0400250 case EvqSmoothOut: return "linear";
251 case EvqFlatOut: return "nointerpolation";
252 case EvqCentroidOut: return "centroid";
253 default: UNREACHABLE();
254 }
255
256 return "";
257}
258
259TString QualifierString(TQualifier qualifier)
260{
261 switch (qualifier)
262 {
263 case EvqIn: return "in";
264 case EvqOut: return "inout"; // 'out' results in an HLSL error if not all fields are written, for GLSL it's undefined
265 case EvqInOut: return "inout";
266 case EvqConstReadOnly: return "const";
267 default: UNREACHABLE();
268 }
269
270 return "";
271}
272
273}