blob: 4394c2f9d345e24bc74f02c6bce6ce949647b87a [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
Jamie Madill033dae62014-06-18 12:56:28 -0400103TString TypeString(const TType &type)
104{
105 const TStructure* structure = type.getStruct();
106 if (structure)
107 {
108 const TString& typeName = structure->name();
109 if (typeName != "")
110 {
111 return StructNameString(*structure);
112 }
113 else // Nameless structure, define in place
114 {
Jamie Madill8daaba12014-06-13 10:04:33 -0400115 return StructureHLSL::defineNameless(*structure);
Jamie Madill033dae62014-06-18 12:56:28 -0400116 }
117 }
118 else if (type.isMatrix())
119 {
120 int cols = type.getCols();
121 int rows = type.getRows();
122 return "float" + str(cols) + "x" + str(rows);
123 }
124 else
125 {
126 switch (type.getBasicType())
127 {
128 case EbtFloat:
129 switch (type.getNominalSize())
130 {
131 case 1: return "float";
132 case 2: return "float2";
133 case 3: return "float3";
134 case 4: return "float4";
135 }
136 case EbtInt:
137 switch (type.getNominalSize())
138 {
139 case 1: return "int";
140 case 2: return "int2";
141 case 3: return "int3";
142 case 4: return "int4";
143 }
144 case EbtUInt:
145 switch (type.getNominalSize())
146 {
147 case 1: return "uint";
148 case 2: return "uint2";
149 case 3: return "uint3";
150 case 4: return "uint4";
151 }
152 case EbtBool:
153 switch (type.getNominalSize())
154 {
155 case 1: return "bool";
156 case 2: return "bool2";
157 case 3: return "bool3";
158 case 4: return "bool4";
159 }
160 case EbtVoid:
161 return "void";
162 case EbtSampler2D:
163 case EbtISampler2D:
164 case EbtUSampler2D:
165 case EbtSampler2DArray:
166 case EbtISampler2DArray:
167 case EbtUSampler2DArray:
168 return "sampler2D";
169 case EbtSamplerCube:
170 case EbtISamplerCube:
171 case EbtUSamplerCube:
172 return "samplerCUBE";
173 case EbtSamplerExternalOES:
174 return "sampler2D";
175 default:
176 break;
177 }
178 }
179
180 UNREACHABLE();
181 return "<unknown type>";
182}
183
184TString StructNameString(const TStructure &structure)
185{
186 if (structure.name().empty())
187 {
188 return "";
189 }
190
Jamie Madill9b820842015-02-12 10:40:10 -0500191 // For structures at global scope we use a consistent
192 // translation so that we can link between shader stages.
193 if (structure.atGlobalScope())
194 {
195 return Decorate(structure.name());
196 }
197
Jamie Madill8daaba12014-06-13 10:04:33 -0400198 return "ss" + str(structure.uniqueId()) + "_" + structure.name();
Jamie Madill033dae62014-06-18 12:56:28 -0400199}
200
201TString QualifiedStructNameString(const TStructure &structure, bool useHLSLRowMajorPacking,
202 bool useStd140Packing)
203{
204 if (structure.name() == "")
205 {
206 return "";
207 }
208
209 TString prefix = "";
210
211 // Structs packed with row-major matrices in HLSL are prefixed with "rm"
212 // GLSL column-major maps to HLSL row-major, and the converse is true
213
214 if (useStd140Packing)
215 {
Jamie Madill8daaba12014-06-13 10:04:33 -0400216 prefix += "std_";
Jamie Madill033dae62014-06-18 12:56:28 -0400217 }
218
219 if (useHLSLRowMajorPacking)
220 {
Jamie Madill8daaba12014-06-13 10:04:33 -0400221 prefix += "rm_";
Jamie Madill033dae62014-06-18 12:56:28 -0400222 }
223
224 return prefix + StructNameString(structure);
225}
226
227TString InterpolationString(TQualifier qualifier)
228{
229 switch (qualifier)
230 {
231 case EvqVaryingIn: return "";
232 case EvqFragmentIn: return "";
Jamie Madill033dae62014-06-18 12:56:28 -0400233 case EvqSmoothIn: return "linear";
234 case EvqFlatIn: return "nointerpolation";
235 case EvqCentroidIn: return "centroid";
236 case EvqVaryingOut: return "";
237 case EvqVertexOut: return "";
Jamie Madill033dae62014-06-18 12:56:28 -0400238 case EvqSmoothOut: return "linear";
239 case EvqFlatOut: return "nointerpolation";
240 case EvqCentroidOut: return "centroid";
241 default: UNREACHABLE();
242 }
243
244 return "";
245}
246
247TString QualifierString(TQualifier qualifier)
248{
249 switch (qualifier)
250 {
251 case EvqIn: return "in";
252 case EvqOut: return "inout"; // 'out' results in an HLSL error if not all fields are written, for GLSL it's undefined
253 case EvqInOut: return "inout";
254 case EvqConstReadOnly: return "const";
255 default: UNREACHABLE();
256 }
257
258 return "";
259}
260
261}