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/StructureHLSL.h"
12#include "compiler/translator/SymbolTable.h"
13
14namespace sh
15{
16
17TString SamplerString(const TType &type)
18{
19    if (IsShadowSampler(type.getBasicType()))
20    {
21        return "SamplerComparisonState";
22    }
23    else
24    {
25        return "SamplerState";
26    }
27}
28
29TString TextureString(const TType &type)
30{
31    switch (type.getBasicType())
32    {
33      case EbtSampler2D:            return "Texture2D";
34      case EbtSamplerCube:          return "TextureCube";
35      case EbtSamplerExternalOES:   return "Texture2D";
36      case EbtSampler2DArray:       return "Texture2DArray";
37      case EbtSampler3D:            return "Texture3D";
38      case EbtISampler2D:           return "Texture2D<int4>";
39      case EbtISampler3D:           return "Texture3D<int4>";
40      case EbtISamplerCube:         return "Texture2DArray<int4>";
41      case EbtISampler2DArray:      return "Texture2DArray<int4>";
42      case EbtUSampler2D:           return "Texture2D<uint4>";
43      case EbtUSampler3D:           return "Texture3D<uint4>";
44      case EbtUSamplerCube:         return "Texture2DArray<uint4>";
45      case EbtUSampler2DArray:      return "Texture2DArray<uint4>";
46      case EbtSampler2DShadow:      return "Texture2D";
47      case EbtSamplerCubeShadow:    return "TextureCube";
48      case EbtSampler2DArrayShadow: return "Texture2DArray";
49      default: UNREACHABLE();
50    }
51
52    return "<unknown texture type>";
53}
54
55TString DecorateUniform(const TString &string, const TType &type)
56{
57    if (type.getBasicType() == EbtSamplerExternalOES)
58    {
59        return "ex_" + string;
60    }
61
62    return Decorate(string);
63}
64
65TString DecorateField(const TString &string, const TStructure &structure)
66{
67    if (structure.name().compare(0, 3, "gl_") != 0)
68    {
69        return Decorate(string);
70    }
71
72    return string;
73}
74
75TString DecoratePrivate(const TString &privateText)
76{
77    return "dx_" + privateText;
78}
79
80TString Decorate(const TString &string)
81{
82    if (string.compare(0, 3, "gl_") != 0)
83    {
84        return "_" + string;
85    }
86
87    return string;
88}
89
90TString TypeString(const TType &type)
91{
92    const TStructure* structure = type.getStruct();
93    if (structure)
94    {
95        const TString& typeName = structure->name();
96        if (typeName != "")
97        {
98            return StructNameString(*structure);
99        }
100        else   // Nameless structure, define in place
101        {
102            return StructureHLSL::defineNameless(*structure);
103        }
104    }
105    else if (type.isMatrix())
106    {
107        int cols = type.getCols();
108        int rows = type.getRows();
109        return "float" + str(cols) + "x" + str(rows);
110    }
111    else
112    {
113        switch (type.getBasicType())
114        {
115          case EbtFloat:
116            switch (type.getNominalSize())
117            {
118              case 1: return "float";
119              case 2: return "float2";
120              case 3: return "float3";
121              case 4: return "float4";
122            }
123          case EbtInt:
124            switch (type.getNominalSize())
125            {
126              case 1: return "int";
127              case 2: return "int2";
128              case 3: return "int3";
129              case 4: return "int4";
130            }
131          case EbtUInt:
132            switch (type.getNominalSize())
133            {
134              case 1: return "uint";
135              case 2: return "uint2";
136              case 3: return "uint3";
137              case 4: return "uint4";
138            }
139          case EbtBool:
140            switch (type.getNominalSize())
141            {
142              case 1: return "bool";
143              case 2: return "bool2";
144              case 3: return "bool3";
145              case 4: return "bool4";
146            }
147          case EbtVoid:
148            return "void";
149          case EbtSampler2D:
150          case EbtISampler2D:
151          case EbtUSampler2D:
152          case EbtSampler2DArray:
153          case EbtISampler2DArray:
154          case EbtUSampler2DArray:
155            return "sampler2D";
156          case EbtSamplerCube:
157          case EbtISamplerCube:
158          case EbtUSamplerCube:
159            return "samplerCUBE";
160          case EbtSamplerExternalOES:
161            return "sampler2D";
162          default:
163            break;
164        }
165    }
166
167    UNREACHABLE();
168    return "<unknown type>";
169}
170
171TString StructNameString(const TStructure &structure)
172{
173    if (structure.name().empty())
174    {
175        return "";
176    }
177
178    return "ss" + str(structure.uniqueId()) + "_" + structure.name();
179}
180
181TString QualifiedStructNameString(const TStructure &structure, bool useHLSLRowMajorPacking,
182                                  bool useStd140Packing)
183{
184    if (structure.name() == "")
185    {
186        return "";
187    }
188
189    TString prefix = "";
190
191    // Structs packed with row-major matrices in HLSL are prefixed with "rm"
192    // GLSL column-major maps to HLSL row-major, and the converse is true
193
194    if (useStd140Packing)
195    {
196        prefix += "std_";
197    }
198
199    if (useHLSLRowMajorPacking)
200    {
201        prefix += "rm_";
202    }
203
204    return prefix + StructNameString(structure);
205}
206
207TString InterpolationString(TQualifier qualifier)
208{
209    switch (qualifier)
210    {
211      case EvqVaryingIn:           return "";
212      case EvqFragmentIn:          return "";
213      case EvqInvariantVaryingIn:  return "";
214      case EvqSmoothIn:            return "linear";
215      case EvqFlatIn:              return "nointerpolation";
216      case EvqCentroidIn:          return "centroid";
217      case EvqVaryingOut:          return "";
218      case EvqVertexOut:           return "";
219      case EvqInvariantVaryingOut: return "";
220      case EvqSmoothOut:           return "linear";
221      case EvqFlatOut:             return "nointerpolation";
222      case EvqCentroidOut:         return "centroid";
223      default: UNREACHABLE();
224    }
225
226    return "";
227}
228
229TString QualifierString(TQualifier qualifier)
230{
231    switch (qualifier)
232    {
233      case EvqIn:            return "in";
234      case EvqOut:           return "inout"; // 'out' results in an HLSL error if not all fields are written, for GLSL it's undefined
235      case EvqInOut:         return "inout";
236      case EvqConstReadOnly: return "const";
237      default: UNREACHABLE();
238    }
239
240    return "";
241}
242
243}
244