zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
OutputHLSL.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2002-2013 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 
7 #include "compiler/OutputHLSL.h"
8 
9 #include "common/angleutils.h"
10 #include "compiler/debug.h"
12 #include "compiler/InfoSink.h"
13 #include "compiler/SearchSymbol.h"
15 
16 #include <algorithm>
17 #include <cfloat>
18 #include <stdio.h>
19 
20 namespace sh
21 {
22 // Integer to TString conversion
24 {
25  char buffer[20];
26  snprintf(buffer, sizeof(buffer), "%d", i);
27  return buffer;
28 }
29 
31  : TIntermTraverser(true, true, true), mContext(context), mOutputType(outputType)
32 {
33  mUnfoldShortCircuit = new UnfoldShortCircuit(context, this);
34  mInsideFunction = false;
35 
36  mUsesTexture2D = false;
37  mUsesTexture2D_bias = false;
38  mUsesTexture2DProj = false;
40  mUsesTexture2DProjLod = false;
41  mUsesTexture2DLod = false;
42  mUsesTextureCube = false;
43  mUsesTextureCube_bias = false;
44  mUsesTextureCubeLod = false;
45  mUsesTexture2DLod0 = false;
47  mUsesTexture2DProjLod0 = false;
49  mUsesTextureCubeLod0 = false;
51  mUsesFragColor = false;
52  mUsesFragData = false;
53  mUsesDepthRange = false;
54  mUsesFragCoord = false;
55  mUsesPointCoord = false;
56  mUsesFrontFacing = false;
57  mUsesPointSize = false;
58  mUsesFragDepth = false;
59  mUsesXor = false;
60  mUsesMod1 = false;
61  mUsesMod2v = false;
62  mUsesMod2f = false;
63  mUsesMod3v = false;
64  mUsesMod3f = false;
65  mUsesMod4v = false;
66  mUsesMod4f = false;
67  mUsesFaceforward1 = false;
68  mUsesFaceforward2 = false;
69  mUsesFaceforward3 = false;
70  mUsesFaceforward4 = false;
71  mUsesAtan2_1 = false;
72  mUsesAtan2_2 = false;
73  mUsesAtan2_3 = false;
74  mUsesAtan2_4 = false;
75 
76  mNumRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1;
77 
78  mScopeDepth = 0;
79 
80  mUniqueIndex = 0;
81 
83  mOutputLod0Function = false;
85 
87 
89  {
91  {
92  mUniformRegister = 3; // Reserve registers for dx_DepthRange, dx_ViewCoords and dx_DepthFront
93  }
94  else
95  {
96  mUniformRegister = 2; // Reserve registers for dx_DepthRange and dx_ViewAdjust
97  }
98  }
99  else
100  {
101  mUniformRegister = 0;
102  }
103 
104  mSamplerRegister = 0;
105 }
106 
108 {
109  delete mUnfoldShortCircuit;
110 }
111 
113 {
115 
116  mContext.treeRoot->traverse(this); // Output the body first to determine what has to go in the header
117  header();
118 
121 }
122 
124 {
125  return mBody;
126 }
127 
129 {
130  return mActiveUniforms;
131 }
132 
134 {
135  int elementSize = type.isMatrix() ? type.getNominalSize() : 1;
136  int arraySize = type.isArray() ? type.getArraySize() : 1;
137 
138  return elementSize * arraySize;
139 }
140 
142 {
143  ShShaderType shaderType = mContext.shaderType;
144  TInfoSinkBase &out = mHeader;
145 
146  for (StructDeclarations::iterator structDeclaration = mStructDeclarations.begin(); structDeclaration != mStructDeclarations.end(); structDeclaration++)
147  {
148  out << *structDeclaration;
149  }
150 
151  for (Constructors::iterator constructor = mConstructors.begin(); constructor != mConstructors.end(); constructor++)
152  {
153  out << *constructor;
154  }
155 
156  TString uniforms;
158  TString attributes;
159 
160  for (ReferencedSymbols::const_iterator uniform = mReferencedUniforms.begin(); uniform != mReferencedUniforms.end(); uniform++)
161  {
162  const TType &type = uniform->second->getType();
163  const TString &name = uniform->second->getSymbol();
164 
165  if (mOutputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType())) // Also declare the texture
166  {
168 
169  uniforms += "uniform SamplerState sampler_" + decorateUniform(name, type) + arrayString(type) +
170  " : register(s" + str(index) + ");\n";
171 
172  uniforms += "uniform " + textureString(type) + " texture_" + decorateUniform(name, type) + arrayString(type) +
173  " : register(t" + str(index) + ");\n";
174  }
175  else
176  {
177  uniforms += "uniform " + typeString(type) + " " + decorateUniform(name, type) + arrayString(type) +
178  " : register(" + registerString(mReferencedUniforms[name]) + ");\n";
179  }
180  }
181 
182  for (ReferencedSymbols::const_iterator varying = mReferencedVaryings.begin(); varying != mReferencedVaryings.end(); varying++)
183  {
184  const TType &type = varying->second->getType();
185  const TString &name = varying->second->getSymbol();
186 
187  // Program linking depends on this exact format
188  varyings += "static " + typeString(type) + " " + decorate(name) + arrayString(type) + " = " + initializer(type) + ";\n";
189  }
190 
191  for (ReferencedSymbols::const_iterator attribute = mReferencedAttributes.begin(); attribute != mReferencedAttributes.end(); attribute++)
192  {
193  const TType &type = attribute->second->getType();
194  const TString &name = attribute->second->getSymbol();
195 
196  attributes += "static " + typeString(type) + " " + decorate(name) + arrayString(type) + " = " + initializer(type) + ";\n";
197  }
198 
199  if (shaderType == SH_FRAGMENT_SHADER)
200  {
201  TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers");
202  const bool usingMRTExtension = (iter != mContext.extensionBehavior().end() && (iter->second == EBhEnable || iter->second == EBhRequire));
203 
204  const unsigned int numColorValues = usingMRTExtension ? mNumRenderTargets : 1;
205 
206  out << "// Varyings\n";
207  out << varyings;
208  out << "\n"
209  "static float4 gl_Color[" << numColorValues << "] =\n"
210  "{\n";
211  for (unsigned int i = 0; i < numColorValues; i++)
212  {
213  out << " float4(0, 0, 0, 0)";
214  if (i + 1 != numColorValues)
215  {
216  out << ",";
217  }
218  out << "\n";
219  }
220  out << "};\n";
221 
222  if (mUsesFragDepth)
223  {
224  out << "static float gl_Depth = 0.0;\n";
225  }
226 
227  if (mUsesFragCoord)
228  {
229  out << "static float4 gl_FragCoord = float4(0, 0, 0, 0);\n";
230  }
231 
232  if (mUsesPointCoord)
233  {
234  out << "static float2 gl_PointCoord = float2(0.5, 0.5);\n";
235  }
236 
237  if (mUsesFrontFacing)
238  {
239  out << "static bool gl_FrontFacing = false;\n";
240  }
241 
242  out << "\n";
243 
244  if (mUsesDepthRange)
245  {
246  out << "struct gl_DepthRangeParameters\n"
247  "{\n"
248  " float near;\n"
249  " float far;\n"
250  " float diff;\n"
251  "};\n"
252  "\n";
253  }
254 
256  {
257  out << "cbuffer DriverConstants : register(b1)\n"
258  "{\n";
259 
260  if (mUsesDepthRange)
261  {
262  out << " float3 dx_DepthRange : packoffset(c0);\n";
263  }
264 
265  if (mUsesFragCoord)
266  {
267  out << " float4 dx_ViewCoords : packoffset(c1);\n";
268  }
269 
271  {
272  out << " float3 dx_DepthFront : packoffset(c2);\n";
273  }
274 
275  out << "};\n";
276  }
277  else
278  {
279  if (mUsesDepthRange)
280  {
281  out << "uniform float3 dx_DepthRange : register(c0);";
282  }
283 
284  if (mUsesFragCoord)
285  {
286  out << "uniform float4 dx_ViewCoords : register(c1);\n";
287  }
288 
290  {
291  out << "uniform float3 dx_DepthFront : register(c2);\n";
292  }
293  }
294 
295  out << "\n";
296 
297  if (mUsesDepthRange)
298  {
299  out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, dx_DepthRange.y, dx_DepthRange.z};\n"
300  "\n";
301  }
302 
303  out << uniforms;
304  out << "\n";
305 
306  if (mUsesTexture2D)
307  {
309  {
310  out << "float4 gl_texture2D(sampler2D s, float2 t)\n"
311  "{\n"
312  " return tex2D(s, t);\n"
313  "}\n"
314  "\n";
315  }
316  else if (mOutputType == SH_HLSL11_OUTPUT)
317  {
318  out << "float4 gl_texture2D(Texture2D t, SamplerState s, float2 uv)\n"
319  "{\n"
320  " return t.Sample(s, uv);\n"
321  "}\n"
322  "\n";
323  }
324  else UNREACHABLE();
325  }
326 
328  {
330  {
331  out << "float4 gl_texture2D(sampler2D s, float2 t, float bias)\n"
332  "{\n"
333  " return tex2Dbias(s, float4(t.x, t.y, 0, bias));\n"
334  "}\n"
335  "\n";
336  }
337  else if (mOutputType == SH_HLSL11_OUTPUT)
338  {
339  out << "float4 gl_texture2D(Texture2D t, SamplerState s, float2 uv, float bias)\n"
340  "{\n"
341  " return t.SampleBias(s, uv, bias);\n"
342  "}\n"
343  "\n";
344  }
345  else UNREACHABLE();
346  }
347 
348  if (mUsesTexture2DProj)
349  {
351  {
352  out << "float4 gl_texture2DProj(sampler2D s, float3 t)\n"
353  "{\n"
354  " return tex2Dproj(s, float4(t.x, t.y, 0, t.z));\n"
355  "}\n"
356  "\n"
357  "float4 gl_texture2DProj(sampler2D s, float4 t)\n"
358  "{\n"
359  " return tex2Dproj(s, t);\n"
360  "}\n"
361  "\n";
362  }
363  else if (mOutputType == SH_HLSL11_OUTPUT)
364  {
365  out << "float4 gl_texture2DProj(Texture2D t, SamplerState s, float3 uvw)\n"
366  "{\n"
367  " return t.Sample(s, float2(uvw.x / uvw.z, uvw.y / uvw.z));\n"
368  "}\n"
369  "\n"
370  "float4 gl_texture2DProj(Texture2D t, SamplerState s, float4 uvw)\n"
371  "{\n"
372  " return t.Sample(s, float2(uvw.x / uvw.w, uvw.y / uvw.w));\n"
373  "}\n"
374  "\n";
375  }
376  else UNREACHABLE();
377  }
378 
380  {
382  {
383  out << "float4 gl_texture2DProj(sampler2D s, float3 t, float bias)\n"
384  "{\n"
385  " return tex2Dbias(s, float4(t.x / t.z, t.y / t.z, 0, bias));\n"
386  "}\n"
387  "\n"
388  "float4 gl_texture2DProj(sampler2D s, float4 t, float bias)\n"
389  "{\n"
390  " return tex2Dbias(s, float4(t.x / t.w, t.y / t.w, 0, bias));\n"
391  "}\n"
392  "\n";
393  }
394  else if (mOutputType == SH_HLSL11_OUTPUT)
395  {
396  out << "float4 gl_texture2DProj(Texture2D t, SamplerState s, float3 uvw, float bias)\n"
397  "{\n"
398  " return t.SampleBias(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), bias);\n"
399  "}\n"
400  "\n"
401  "float4 gl_texture2DProj(Texture2D t, SamplerState s, float4 uvw, float bias)\n"
402  "{\n"
403  " return t.SampleBias(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), bias);\n"
404  "}\n"
405  "\n";
406  }
407  else UNREACHABLE();
408  }
409 
410  if (mUsesTextureCube)
411  {
413  {
414  out << "float4 gl_textureCube(samplerCUBE s, float3 t)\n"
415  "{\n"
416  " return texCUBE(s, t);\n"
417  "}\n"
418  "\n";
419  }
420  else if (mOutputType == SH_HLSL11_OUTPUT)
421  {
422  out << "float4 gl_textureCube(TextureCube t, SamplerState s, float3 uvw)\n"
423  "{\n"
424  " return t.Sample(s, uvw);\n"
425  "}\n"
426  "\n";
427  }
428  else UNREACHABLE();
429  }
430 
432  {
434  {
435  out << "float4 gl_textureCube(samplerCUBE s, float3 t, float bias)\n"
436  "{\n"
437  " return texCUBEbias(s, float4(t.x, t.y, t.z, bias));\n"
438  "}\n"
439  "\n";
440  }
441  else if (mOutputType == SH_HLSL11_OUTPUT)
442  {
443  out << "float4 gl_textureCube(TextureCube t, SamplerState s, float3 uvw, float bias)\n"
444  "{\n"
445  " return t.SampleBias(s, uvw, bias);\n"
446  "}\n"
447  "\n";
448  }
449  else UNREACHABLE();
450  }
451 
452  // These *Lod0 intrinsics are not available in GL fragment shaders.
453  // They are used to sample using discontinuous texture coordinates.
454  if (mUsesTexture2DLod0)
455  {
457  {
458  out << "float4 gl_texture2DLod0(sampler2D s, float2 t)\n"
459  "{\n"
460  " return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n"
461  "}\n"
462  "\n";
463  }
464  else if (mOutputType == SH_HLSL11_OUTPUT)
465  {
466  out << "float4 gl_texture2DLod0(Texture2D t, SamplerState s, float2 uv)\n"
467  "{\n"
468  " return t.SampleLevel(s, uv, 0);\n"
469  "}\n"
470  "\n";
471  }
472  else UNREACHABLE();
473  }
474 
476  {
478  {
479  out << "float4 gl_texture2DLod0(sampler2D s, float2 t, float bias)\n"
480  "{\n"
481  " return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n"
482  "}\n"
483  "\n";
484  }
485  else if (mOutputType == SH_HLSL11_OUTPUT)
486  {
487  out << "float4 gl_texture2DLod0(Texture2D t, SamplerState s, float2 uv, float bias)\n"
488  "{\n"
489  " return t.SampleLevel(s, uv, 0);\n"
490  "}\n"
491  "\n";
492  }
493  else UNREACHABLE();
494  }
495 
497  {
499  {
500  out << "float4 gl_texture2DProjLod0(sampler2D s, float3 t)\n"
501  "{\n"
502  " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n"
503  "}\n"
504  "\n"
505  "float4 gl_texture2DProjLod(sampler2D s, float4 t)\n"
506  "{\n"
507  " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n"
508  "}\n"
509  "\n";
510  }
511  else if (mOutputType == SH_HLSL11_OUTPUT)
512  {
513  out << "float4 gl_texture2DProjLod0(Texture2D t, SamplerState s, float3 uvw)\n"
514  "{\n"
515  " return t.SampleLevel(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), 0);\n"
516  "}\n"
517  "\n"
518  "float4 gl_texture2DProjLod0(Texture2D t, SamplerState s, float4 uvw)\n"
519  "{\n"
520  " return t.SampleLevel(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), 0);\n"
521  "}\n"
522  "\n";
523  }
524  else UNREACHABLE();
525  }
526 
528  {
530  {
531  out << "float4 gl_texture2DProjLod0_bias(sampler2D s, float3 t, float bias)\n"
532  "{\n"
533  " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n"
534  "}\n"
535  "\n"
536  "float4 gl_texture2DProjLod_bias(sampler2D s, float4 t, float bias)\n"
537  "{\n"
538  " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n"
539  "}\n"
540  "\n";
541  }
542  else if (mOutputType == SH_HLSL11_OUTPUT)
543  {
544  out << "float4 gl_texture2DProjLod_bias(Texture2D t, SamplerState s, float3 uvw, float bias)\n"
545  "{\n"
546  " return t.SampleLevel(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), 0);\n"
547  "}\n"
548  "\n"
549  "float4 gl_texture2DProjLod_bias(Texture2D t, SamplerState s, float4 uvw, float bias)\n"
550  "{\n"
551  " return t.SampleLevel(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), 0);\n"
552  "}\n"
553  "\n";
554  }
555  else UNREACHABLE();
556  }
557 
559  {
561  {
562  out << "float4 gl_textureCubeLod0(samplerCUBE s, float3 t)\n"
563  "{\n"
564  " return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n"
565  "}\n"
566  "\n";
567  }
568  else if (mOutputType == SH_HLSL11_OUTPUT)
569  {
570  out << "float4 gl_textureCubeLod0(TextureCube t, SamplerState s, float3 uvw)\n"
571  "{\n"
572  " return t.SampleLevel(s, uvw, 0);\n"
573  "}\n"
574  "\n";
575  }
576  else UNREACHABLE();
577  }
578 
580  {
582  {
583  out << "float4 gl_textureCubeLod0(samplerCUBE s, float3 t, float bias)\n"
584  "{\n"
585  " return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n"
586  "}\n"
587  "\n";
588  }
589  else if (mOutputType == SH_HLSL11_OUTPUT)
590  {
591  out << "float4 gl_textureCubeLod0(TextureCube t, SamplerState s, float3 uvw, float bias)\n"
592  "{\n"
593  " return t.SampleLevel(s, uvw, 0);\n"
594  "}\n"
595  "\n";
596  }
597  else UNREACHABLE();
598  }
599 
600  if (usingMRTExtension && mNumRenderTargets > 1)
601  {
602  out << "#define GL_USES_MRT\n";
603  }
604 
605  if (mUsesFragColor)
606  {
607  out << "#define GL_USES_FRAG_COLOR\n";
608  }
609 
610  if (mUsesFragData)
611  {
612  out << "#define GL_USES_FRAG_DATA\n";
613  }
614  }
615  else // Vertex shader
616  {
617  out << "// Attributes\n";
618  out << attributes;
619  out << "\n"
620  "static float4 gl_Position = float4(0, 0, 0, 0);\n";
621 
622  if (mUsesPointSize)
623  {
624  out << "static float gl_PointSize = float(1);\n";
625  }
626 
627  out << "\n"
628  "// Varyings\n";
629  out << varyings;
630  out << "\n";
631 
632  if (mUsesDepthRange)
633  {
634  out << "struct gl_DepthRangeParameters\n"
635  "{\n"
636  " float near;\n"
637  " float far;\n"
638  " float diff;\n"
639  "};\n"
640  "\n";
641  }
642 
644  {
645  if (mUsesDepthRange)
646  {
647  out << "cbuffer DriverConstants : register(b1)\n"
648  "{\n"
649  " float3 dx_DepthRange : packoffset(c0);\n"
650  "};\n"
651  "\n";
652  }
653  }
654  else
655  {
656  if (mUsesDepthRange)
657  {
658  out << "uniform float3 dx_DepthRange : register(c0);\n";
659  }
660 
661  out << "uniform float4 dx_ViewAdjust : register(c1);\n"
662  "\n";
663  }
664 
665  if (mUsesDepthRange)
666  {
667  out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, dx_DepthRange.y, dx_DepthRange.z};\n"
668  "\n";
669  }
670 
671  out << uniforms;
672  out << "\n";
673 
674  if (mUsesTexture2D)
675  {
677  {
678  out << "float4 gl_texture2D(sampler2D s, float2 t)\n"
679  "{\n"
680  " return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n"
681  "}\n"
682  "\n";
683  }
684  else if (mOutputType == SH_HLSL11_OUTPUT)
685  {
686  out << "float4 gl_texture2D(Texture2D t, SamplerState s, float2 uv)\n"
687  "{\n"
688  " return t.SampleLevel(s, uv, 0);\n"
689  "}\n"
690  "\n";
691  }
692  else UNREACHABLE();
693  }
694 
695  if (mUsesTexture2DLod)
696  {
698  {
699  out << "float4 gl_texture2DLod(sampler2D s, float2 t, float lod)\n"
700  "{\n"
701  " return tex2Dlod(s, float4(t.x, t.y, 0, lod));\n"
702  "}\n"
703  "\n";
704  }
705  else if (mOutputType == SH_HLSL11_OUTPUT)
706  {
707  out << "float4 gl_texture2DLod(Texture2D t, SamplerState s, float2 uv, float lod)\n"
708  "{\n"
709  " return t.SampleLevel(s, uv, lod);\n"
710  "}\n"
711  "\n";
712  }
713  else UNREACHABLE();
714  }
715 
716  if (mUsesTexture2DProj)
717  {
719  {
720  out << "float4 gl_texture2DProj(sampler2D s, float3 t)\n"
721  "{\n"
722  " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n"
723  "}\n"
724  "\n"
725  "float4 gl_texture2DProj(sampler2D s, float4 t)\n"
726  "{\n"
727  " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n"
728  "}\n"
729  "\n";
730  }
731  else if (mOutputType == SH_HLSL11_OUTPUT)
732  {
733  out << "float4 gl_texture2DProj(Texture2D t, SamplerState s, float3 uvw)\n"
734  "{\n"
735  " return t.SampleLevel(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), 0);\n"
736  "}\n"
737  "\n"
738  "float4 gl_texture2DProj(Texture2D t, SamplerState s, float4 uvw)\n"
739  "{\n"
740  " return t.SampleLevel(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), 0);\n"
741  "}\n"
742  "\n";
743  }
744  else UNREACHABLE();
745  }
746 
748  {
750  {
751  out << "float4 gl_texture2DProjLod(sampler2D s, float3 t, float lod)\n"
752  "{\n"
753  " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, lod));\n"
754  "}\n"
755  "\n"
756  "float4 gl_texture2DProjLod(sampler2D s, float4 t, float lod)\n"
757  "{\n"
758  " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, lod));\n"
759  "}\n"
760  "\n";
761  }
762  else if (mOutputType == SH_HLSL11_OUTPUT)
763  {
764  out << "float4 gl_texture2DProj(Texture2D t, SamplerState s, float3 uvw, float lod)\n"
765  "{\n"
766  " return t.SampleLevel(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), lod);\n"
767  "}\n"
768  "\n"
769  "float4 gl_texture2DProj(Texture2D t, SamplerState s, float4 uvw)\n"
770  "{\n"
771  " return t.SampleLevel(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), lod);\n"
772  "}\n"
773  "\n";
774  }
775  else UNREACHABLE();
776  }
777 
778  if (mUsesTextureCube)
779  {
781  {
782  out << "float4 gl_textureCube(samplerCUBE s, float3 t)\n"
783  "{\n"
784  " return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n"
785  "}\n"
786  "\n";
787  }
788  else if (mOutputType == SH_HLSL11_OUTPUT)
789  {
790  out << "float4 gl_textureCube(TextureCube t, SamplerState s, float3 uvw)\n"
791  "{\n"
792  " return t.SampleLevel(s, uvw, 0);\n"
793  "}\n"
794  "\n";
795  }
796  else UNREACHABLE();
797  }
798 
800  {
802  {
803  out << "float4 gl_textureCubeLod(samplerCUBE s, float3 t, float lod)\n"
804  "{\n"
805  " return texCUBElod(s, float4(t.x, t.y, t.z, lod));\n"
806  "}\n"
807  "\n";
808  }
809  else if (mOutputType == SH_HLSL11_OUTPUT)
810  {
811  out << "float4 gl_textureCubeLod(TextureCube t, SamplerState s, float3 uvw, float lod)\n"
812  "{\n"
813  " return t.SampleLevel(s, uvw, lod);\n"
814  "}\n"
815  "\n";
816  }
817  else UNREACHABLE();
818  }
819  }
820 
821  if (mUsesFragCoord)
822  {
823  out << "#define GL_USES_FRAG_COORD\n";
824  }
825 
826  if (mUsesPointCoord)
827  {
828  out << "#define GL_USES_POINT_COORD\n";
829  }
830 
831  if (mUsesFrontFacing)
832  {
833  out << "#define GL_USES_FRONT_FACING\n";
834  }
835 
836  if (mUsesPointSize)
837  {
838  out << "#define GL_USES_POINT_SIZE\n";
839  }
840 
841  if (mUsesFragDepth)
842  {
843  out << "#define GL_USES_FRAG_DEPTH\n";
844  }
845 
846  if (mUsesDepthRange)
847  {
848  out << "#define GL_USES_DEPTH_RANGE\n";
849  }
850 
851  if (mUsesXor)
852  {
853  out << "bool xor(bool p, bool q)\n"
854  "{\n"
855  " return (p || q) && !(p && q);\n"
856  "}\n"
857  "\n";
858  }
859 
860  if (mUsesMod1)
861  {
862  out << "float mod(float x, float y)\n"
863  "{\n"
864  " return x - y * floor(x / y);\n"
865  "}\n"
866  "\n";
867  }
868 
869  if (mUsesMod2v)
870  {
871  out << "float2 mod(float2 x, float2 y)\n"
872  "{\n"
873  " return x - y * floor(x / y);\n"
874  "}\n"
875  "\n";
876  }
877 
878  if (mUsesMod2f)
879  {
880  out << "float2 mod(float2 x, float y)\n"
881  "{\n"
882  " return x - y * floor(x / y);\n"
883  "}\n"
884  "\n";
885  }
886 
887  if (mUsesMod3v)
888  {
889  out << "float3 mod(float3 x, float3 y)\n"
890  "{\n"
891  " return x - y * floor(x / y);\n"
892  "}\n"
893  "\n";
894  }
895 
896  if (mUsesMod3f)
897  {
898  out << "float3 mod(float3 x, float y)\n"
899  "{\n"
900  " return x - y * floor(x / y);\n"
901  "}\n"
902  "\n";
903  }
904 
905  if (mUsesMod4v)
906  {
907  out << "float4 mod(float4 x, float4 y)\n"
908  "{\n"
909  " return x - y * floor(x / y);\n"
910  "}\n"
911  "\n";
912  }
913 
914  if (mUsesMod4f)
915  {
916  out << "float4 mod(float4 x, float y)\n"
917  "{\n"
918  " return x - y * floor(x / y);\n"
919  "}\n"
920  "\n";
921  }
922 
923  if (mUsesFaceforward1)
924  {
925  out << "float faceforward(float N, float I, float Nref)\n"
926  "{\n"
927  " if(dot(Nref, I) >= 0)\n"
928  " {\n"
929  " return -N;\n"
930  " }\n"
931  " else\n"
932  " {\n"
933  " return N;\n"
934  " }\n"
935  "}\n"
936  "\n";
937  }
938 
939  if (mUsesFaceforward2)
940  {
941  out << "float2 faceforward(float2 N, float2 I, float2 Nref)\n"
942  "{\n"
943  " if(dot(Nref, I) >= 0)\n"
944  " {\n"
945  " return -N;\n"
946  " }\n"
947  " else\n"
948  " {\n"
949  " return N;\n"
950  " }\n"
951  "}\n"
952  "\n";
953  }
954 
955  if (mUsesFaceforward3)
956  {
957  out << "float3 faceforward(float3 N, float3 I, float3 Nref)\n"
958  "{\n"
959  " if(dot(Nref, I) >= 0)\n"
960  " {\n"
961  " return -N;\n"
962  " }\n"
963  " else\n"
964  " {\n"
965  " return N;\n"
966  " }\n"
967  "}\n"
968  "\n";
969  }
970 
971  if (mUsesFaceforward4)
972  {
973  out << "float4 faceforward(float4 N, float4 I, float4 Nref)\n"
974  "{\n"
975  " if(dot(Nref, I) >= 0)\n"
976  " {\n"
977  " return -N;\n"
978  " }\n"
979  " else\n"
980  " {\n"
981  " return N;\n"
982  " }\n"
983  "}\n"
984  "\n";
985  }
986 
987  if (mUsesAtan2_1)
988  {
989  out << "float atanyx(float y, float x)\n"
990  "{\n"
991  " if(x == 0 && y == 0) x = 1;\n" // Avoid producing a NaN
992  " return atan2(y, x);\n"
993  "}\n";
994  }
995 
996  if (mUsesAtan2_2)
997  {
998  out << "float2 atanyx(float2 y, float2 x)\n"
999  "{\n"
1000  " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
1001  " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
1002  " return float2(atan2(y[0], x[0]), atan2(y[1], x[1]));\n"
1003  "}\n";
1004  }
1005 
1006  if (mUsesAtan2_3)
1007  {
1008  out << "float3 atanyx(float3 y, float3 x)\n"
1009  "{\n"
1010  " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
1011  " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
1012  " if(x[2] == 0 && y[2] == 0) x[2] = 1;\n"
1013  " return float3(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]));\n"
1014  "}\n";
1015  }
1016 
1017  if (mUsesAtan2_4)
1018  {
1019  out << "float4 atanyx(float4 y, float4 x)\n"
1020  "{\n"
1021  " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
1022  " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
1023  " if(x[2] == 0 && y[2] == 0) x[2] = 1;\n"
1024  " if(x[3] == 0 && y[3] == 0) x[3] = 1;\n"
1025  " return float4(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]), atan2(y[3], x[3]));\n"
1026  "}\n";
1027  }
1028 }
1029 
1031 {
1032  TInfoSinkBase &out = mBody;
1033 
1034  TString name = node->getSymbol();
1035 
1036  if (name == "gl_FragColor")
1037  {
1038  out << "gl_Color[0]";
1039  mUsesFragColor = true;
1040  }
1041  else if (name == "gl_FragData")
1042  {
1043  out << "gl_Color";
1044  mUsesFragData = true;
1045  }
1046  else if (name == "gl_DepthRange")
1047  {
1048  mUsesDepthRange = true;
1049  out << name;
1050  }
1051  else if (name == "gl_FragCoord")
1052  {
1053  mUsesFragCoord = true;
1054  out << name;
1055  }
1056  else if (name == "gl_PointCoord")
1057  {
1058  mUsesPointCoord = true;
1059  out << name;
1060  }
1061  else if (name == "gl_FrontFacing")
1062  {
1063  mUsesFrontFacing = true;
1064  out << name;
1065  }
1066  else if (name == "gl_PointSize")
1067  {
1068  mUsesPointSize = true;
1069  out << name;
1070  }
1071  else if (name == "gl_FragDepthEXT")
1072  {
1073  mUsesFragDepth = true;
1074  out << "gl_Depth";
1075  }
1076  else
1077  {
1078  TQualifier qualifier = node->getQualifier();
1079 
1080  if (qualifier == EvqUniform)
1081  {
1082  mReferencedUniforms[name] = node;
1083  out << decorateUniform(name, node->getType());
1084  }
1085  else if (qualifier == EvqAttribute)
1086  {
1087  mReferencedAttributes[name] = node;
1088  out << decorate(name);
1089  }
1090  else if (qualifier == EvqVaryingOut || qualifier == EvqInvariantVaryingOut || qualifier == EvqVaryingIn || qualifier == EvqInvariantVaryingIn)
1091  {
1092  mReferencedVaryings[name] = node;
1093  out << decorate(name);
1094  }
1095  else
1096  {
1097  out << decorate(name);
1098  }
1099  }
1100 }
1101 
1103 {
1104  TInfoSinkBase &out = mBody;
1105 
1106  switch (node->getOp())
1107  {
1108  case EOpAssign: outputTriplet(visit, "(", " = ", ")"); break;
1109  case EOpInitialize:
1110  if (visit == PreVisit)
1111  {
1112  // GLSL allows to write things like "float x = x;" where a new variable x is defined
1113  // and the value of an existing variable x is assigned. HLSL uses C semantics (the
1114  // new variable is created before the assignment is evaluated), so we need to convert
1115  // this to "float t = x, x = t;".
1116 
1117  TIntermSymbol *symbolNode = node->getLeft()->getAsSymbolNode();
1118  TIntermTyped *expression = node->getRight();
1119 
1120  sh::SearchSymbol searchSymbol(symbolNode->getSymbol());
1121  expression->traverse(&searchSymbol);
1122  bool sameSymbol = searchSymbol.foundMatch();
1123 
1124  if (sameSymbol)
1125  {
1126  // Type already printed
1127  out << "t" + str(mUniqueIndex) + " = ";
1128  expression->traverse(this);
1129  out << ", ";
1130  symbolNode->traverse(this);
1131  out << " = t" + str(mUniqueIndex);
1132 
1133  mUniqueIndex++;
1134  return false;
1135  }
1136  }
1137  else if (visit == InVisit)
1138  {
1139  out << " = ";
1140  }
1141  break;
1142  case EOpAddAssign: outputTriplet(visit, "(", " += ", ")"); break;
1143  case EOpSubAssign: outputTriplet(visit, "(", " -= ", ")"); break;
1144  case EOpMulAssign: outputTriplet(visit, "(", " *= ", ")"); break;
1145  case EOpVectorTimesScalarAssign: outputTriplet(visit, "(", " *= ", ")"); break;
1146  case EOpMatrixTimesScalarAssign: outputTriplet(visit, "(", " *= ", ")"); break;
1148  if (visit == PreVisit)
1149  {
1150  out << "(";
1151  }
1152  else if (visit == InVisit)
1153  {
1154  out << " = mul(";
1155  node->getLeft()->traverse(this);
1156  out << ", transpose(";
1157  }
1158  else
1159  {
1160  out << ")))";
1161  }
1162  break;
1164  if (visit == PreVisit)
1165  {
1166  out << "(";
1167  }
1168  else if (visit == InVisit)
1169  {
1170  out << " = mul(";
1171  node->getLeft()->traverse(this);
1172  out << ", ";
1173  }
1174  else
1175  {
1176  out << "))";
1177  }
1178  break;
1179  case EOpDivAssign: outputTriplet(visit, "(", " /= ", ")"); break;
1180  case EOpIndexDirect: outputTriplet(visit, "", "[", "]"); break;
1181  case EOpIndexIndirect: outputTriplet(visit, "", "[", "]"); break;
1182  case EOpIndexDirectStruct:
1183  if (visit == InVisit)
1184  {
1185  const TStructure* structure = node->getLeft()->getType().getStruct();
1187  const TField* field = structure->fields()[index->getIConst(0)];
1188  out << "." + decorateField(field->name(), node->getLeft()->getType());
1189 
1190  return false;
1191  }
1192  break;
1193  case EOpVectorSwizzle:
1194  if (visit == InVisit)
1195  {
1196  out << ".";
1197 
1199 
1200  if (swizzle)
1201  {
1202  TIntermSequence &sequence = swizzle->getSequence();
1203 
1204  for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++)
1205  {
1206  TIntermConstantUnion *element = (*sit)->getAsConstantUnion();
1207 
1208  if (element)
1209  {
1210  int i = element->getIConst(0);
1211 
1212  switch (i)
1213  {
1214  case 0: out << "x"; break;
1215  case 1: out << "y"; break;
1216  case 2: out << "z"; break;
1217  case 3: out << "w"; break;
1218  default: UNREACHABLE();
1219  }
1220  }
1221  else UNREACHABLE();
1222  }
1223  }
1224  else UNREACHABLE();
1225 
1226  return false; // Fully processed
1227  }
1228  break;
1229  case EOpAdd: outputTriplet(visit, "(", " + ", ")"); break;
1230  case EOpSub: outputTriplet(visit, "(", " - ", ")"); break;
1231  case EOpMul: outputTriplet(visit, "(", " * ", ")"); break;
1232  case EOpDiv: outputTriplet(visit, "(", " / ", ")"); break;
1233  case EOpEqual:
1234  case EOpNotEqual:
1235  if (node->getLeft()->isScalar())
1236  {
1237  if (node->getOp() == EOpEqual)
1238  {
1239  outputTriplet(visit, "(", " == ", ")");
1240  }
1241  else
1242  {
1243  outputTriplet(visit, "(", " != ", ")");
1244  }
1245  }
1246  else if (node->getLeft()->getBasicType() == EbtStruct)
1247  {
1248  if (node->getOp() == EOpEqual)
1249  {
1250  out << "(";
1251  }
1252  else
1253  {
1254  out << "!(";
1255  }
1256 
1257  const TFieldList &fields = node->getLeft()->getType().getStruct()->fields();
1258 
1259  for (size_t i = 0; i < fields.size(); i++)
1260  {
1261  const TField *field = fields[i];
1262 
1263  node->getLeft()->traverse(this);
1264  out << "." + decorateField(field->name(), node->getLeft()->getType()) + " == ";
1265  node->getRight()->traverse(this);
1266  out << "." + decorateField(field->name(), node->getLeft()->getType());
1267 
1268  if (i < fields.size() - 1)
1269  {
1270  out << " && ";
1271  }
1272  }
1273 
1274  out << ")";
1275 
1276  return false;
1277  }
1278  else
1279  {
1280  ASSERT(node->getLeft()->isMatrix() || node->getLeft()->isVector());
1281 
1282  if (node->getOp() == EOpEqual)
1283  {
1284  outputTriplet(visit, "all(", " == ", ")");
1285  }
1286  else
1287  {
1288  outputTriplet(visit, "!all(", " == ", ")");
1289  }
1290  }
1291  break;
1292  case EOpLessThan: outputTriplet(visit, "(", " < ", ")"); break;
1293  case EOpGreaterThan: outputTriplet(visit, "(", " > ", ")"); break;
1294  case EOpLessThanEqual: outputTriplet(visit, "(", " <= ", ")"); break;
1295  case EOpGreaterThanEqual: outputTriplet(visit, "(", " >= ", ")"); break;
1296  case EOpVectorTimesScalar: outputTriplet(visit, "(", " * ", ")"); break;
1297  case EOpMatrixTimesScalar: outputTriplet(visit, "(", " * ", ")"); break;
1298  case EOpVectorTimesMatrix: outputTriplet(visit, "mul(", ", transpose(", "))"); break;
1299  case EOpMatrixTimesVector: outputTriplet(visit, "mul(transpose(", "), ", ")"); break;
1300  case EOpMatrixTimesMatrix: outputTriplet(visit, "transpose(mul(transpose(", "), transpose(", ")))"); break;
1301  case EOpLogicalOr:
1302  out << "s" << mUnfoldShortCircuit->getNextTemporaryIndex();
1303  return false;
1304  case EOpLogicalXor:
1305  mUsesXor = true;
1306  outputTriplet(visit, "xor(", ", ", ")");
1307  break;
1308  case EOpLogicalAnd:
1309  out << "s" << mUnfoldShortCircuit->getNextTemporaryIndex();
1310  return false;
1311  default: UNREACHABLE();
1312  }
1313 
1314  return true;
1315 }
1316 
1318 {
1319  switch (node->getOp())
1320  {
1321  case EOpNegative: outputTriplet(visit, "(-", "", ")"); break;
1322  case EOpVectorLogicalNot: outputTriplet(visit, "(!", "", ")"); break;
1323  case EOpLogicalNot: outputTriplet(visit, "(!", "", ")"); break;
1324  case EOpPostIncrement: outputTriplet(visit, "(", "", "++)"); break;
1325  case EOpPostDecrement: outputTriplet(visit, "(", "", "--)"); break;
1326  case EOpPreIncrement: outputTriplet(visit, "(++", "", ")"); break;
1327  case EOpPreDecrement: outputTriplet(visit, "(--", "", ")"); break;
1328  case EOpConvIntToBool:
1329  case EOpConvFloatToBool:
1330  switch (node->getOperand()->getType().getNominalSize())
1331  {
1332  case 1: outputTriplet(visit, "bool(", "", ")"); break;
1333  case 2: outputTriplet(visit, "bool2(", "", ")"); break;
1334  case 3: outputTriplet(visit, "bool3(", "", ")"); break;
1335  case 4: outputTriplet(visit, "bool4(", "", ")"); break;
1336  default: UNREACHABLE();
1337  }
1338  break;
1339  case EOpConvBoolToFloat:
1340  case EOpConvIntToFloat:
1341  switch (node->getOperand()->getType().getNominalSize())
1342  {
1343  case 1: outputTriplet(visit, "float(", "", ")"); break;
1344  case 2: outputTriplet(visit, "float2(", "", ")"); break;
1345  case 3: outputTriplet(visit, "float3(", "", ")"); break;
1346  case 4: outputTriplet(visit, "float4(", "", ")"); break;
1347  default: UNREACHABLE();
1348  }
1349  break;
1350  case EOpConvFloatToInt:
1351  case EOpConvBoolToInt:
1352  switch (node->getOperand()->getType().getNominalSize())
1353  {
1354  case 1: outputTriplet(visit, "int(", "", ")"); break;
1355  case 2: outputTriplet(visit, "int2(", "", ")"); break;
1356  case 3: outputTriplet(visit, "int3(", "", ")"); break;
1357  case 4: outputTriplet(visit, "int4(", "", ")"); break;
1358  default: UNREACHABLE();
1359  }
1360  break;
1361  case EOpRadians: outputTriplet(visit, "radians(", "", ")"); break;
1362  case EOpDegrees: outputTriplet(visit, "degrees(", "", ")"); break;
1363  case EOpSin: outputTriplet(visit, "sin(", "", ")"); break;
1364  case EOpCos: outputTriplet(visit, "cos(", "", ")"); break;
1365  case EOpTan: outputTriplet(visit, "tan(", "", ")"); break;
1366  case EOpAsin: outputTriplet(visit, "asin(", "", ")"); break;
1367  case EOpAcos: outputTriplet(visit, "acos(", "", ")"); break;
1368  case EOpAtan: outputTriplet(visit, "atan(", "", ")"); break;
1369  case EOpExp: outputTriplet(visit, "exp(", "", ")"); break;
1370  case EOpLog: outputTriplet(visit, "log(", "", ")"); break;
1371  case EOpExp2: outputTriplet(visit, "exp2(", "", ")"); break;
1372  case EOpLog2: outputTriplet(visit, "log2(", "", ")"); break;
1373  case EOpSqrt: outputTriplet(visit, "sqrt(", "", ")"); break;
1374  case EOpInverseSqrt: outputTriplet(visit, "rsqrt(", "", ")"); break;
1375  case EOpAbs: outputTriplet(visit, "abs(", "", ")"); break;
1376  case EOpSign: outputTriplet(visit, "sign(", "", ")"); break;
1377  case EOpFloor: outputTriplet(visit, "floor(", "", ")"); break;
1378  case EOpCeil: outputTriplet(visit, "ceil(", "", ")"); break;
1379  case EOpFract: outputTriplet(visit, "frac(", "", ")"); break;
1380  case EOpLength: outputTriplet(visit, "length(", "", ")"); break;
1381  case EOpNormalize: outputTriplet(visit, "normalize(", "", ")"); break;
1382  case EOpDFdx:
1384  {
1385  outputTriplet(visit, "(", "", ", 0.0)");
1386  }
1387  else
1388  {
1389  outputTriplet(visit, "ddx(", "", ")");
1390  }
1391  break;
1392  case EOpDFdy:
1394  {
1395  outputTriplet(visit, "(", "", ", 0.0)");
1396  }
1397  else
1398  {
1399  outputTriplet(visit, "ddy(", "", ")");
1400  }
1401  break;
1402  case EOpFwidth:
1404  {
1405  outputTriplet(visit, "(", "", ", 0.0)");
1406  }
1407  else
1408  {
1409  outputTriplet(visit, "fwidth(", "", ")");
1410  }
1411  break;
1412  case EOpAny: outputTriplet(visit, "any(", "", ")"); break;
1413  case EOpAll: outputTriplet(visit, "all(", "", ")"); break;
1414  default: UNREACHABLE();
1415  }
1416 
1417  return true;
1418 }
1419 
1421 {
1422  TInfoSinkBase &out = mBody;
1423 
1424  switch (node->getOp())
1425  {
1426  case EOpSequence:
1427  {
1428  if (mInsideFunction)
1429  {
1431  out << "{\n";
1432 
1433  mScopeDepth++;
1434 
1435  if (mScopeBracket.size() < mScopeDepth)
1436  {
1437  mScopeBracket.push_back(0); // New scope level
1438  }
1439  else
1440  {
1441  mScopeBracket[mScopeDepth - 1]++; // New scope at existing level
1442  }
1443  }
1444 
1445  for (TIntermSequence::iterator sit = node->getSequence().begin(); sit != node->getSequence().end(); sit++)
1446  {
1447  outputLineDirective((*sit)->getLine().first_line);
1448 
1449  traverseStatements(*sit);
1450 
1451  out << ";\n";
1452  }
1453 
1454  if (mInsideFunction)
1455  {
1457  out << "}\n";
1458 
1459  mScopeDepth--;
1460  }
1461 
1462  return false;
1463  }
1464  case EOpDeclaration:
1465  if (visit == PreVisit)
1466  {
1467  TIntermSequence &sequence = node->getSequence();
1468  TIntermTyped *variable = sequence[0]->getAsTyped();
1469 
1470  if (variable && (variable->getQualifier() == EvqTemporary || variable->getQualifier() == EvqGlobal))
1471  {
1472  if (variable->getType().getStruct())
1473  {
1474  addConstructor(variable->getType(), scopedStruct(variable->getType().getStruct()->name()), NULL);
1475  }
1476 
1477  if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration
1478  {
1479  if (!mInsideFunction)
1480  {
1481  out << "static ";
1482  }
1483 
1484  out << typeString(variable->getType()) + " ";
1485 
1486  for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++)
1487  {
1488  TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
1489 
1490  if (symbol)
1491  {
1492  symbol->traverse(this);
1493  out << arrayString(symbol->getType());
1494  out << " = " + initializer(variable->getType());
1495  }
1496  else
1497  {
1498  (*sit)->traverse(this);
1499  }
1500 
1501  if (*sit != sequence.back())
1502  {
1503  out << ", ";
1504  }
1505  }
1506  }
1507  else if (variable->getAsSymbolNode() && variable->getAsSymbolNode()->getSymbol() == "") // Type (struct) declaration
1508  {
1509  // Already added to constructor map
1510  }
1511  else UNREACHABLE();
1512  }
1513  else if (variable && (variable->getQualifier() == EvqVaryingOut || variable->getQualifier() == EvqInvariantVaryingOut))
1514  {
1515  for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++)
1516  {
1517  TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
1518 
1519  if (symbol)
1520  {
1521  // Vertex (output) varyings which are declared but not written to should still be declared to allow successful linking
1522  mReferencedVaryings[symbol->getSymbol()] = symbol;
1523  }
1524  else
1525  {
1526  (*sit)->traverse(this);
1527  }
1528  }
1529  }
1530 
1531  return false;
1532  }
1533  else if (visit == InVisit)
1534  {
1535  out << ", ";
1536  }
1537  break;
1538  case EOpPrototype:
1539  if (visit == PreVisit)
1540  {
1541  out << typeString(node->getType()) << " " << decorate(node->getName()) << (mOutputLod0Function ? "Lod0(" : "(");
1542 
1543  TIntermSequence &arguments = node->getSequence();
1544 
1545  for (unsigned int i = 0; i < arguments.size(); i++)
1546  {
1547  TIntermSymbol *symbol = arguments[i]->getAsSymbolNode();
1548 
1549  if (symbol)
1550  {
1551  out << argumentString(symbol);
1552 
1553  if (i < arguments.size() - 1)
1554  {
1555  out << ", ";
1556  }
1557  }
1558  else UNREACHABLE();
1559  }
1560 
1561  out << ");\n";
1562 
1563  // Also prototype the Lod0 variant if needed
1565  {
1566  mOutputLod0Function = true;
1567  node->traverse(this);
1568  mOutputLod0Function = false;
1569  }
1570 
1571  return false;
1572  }
1573  break;
1574  case EOpComma: outputTriplet(visit, "(", ", ", ")"); break;
1575  case EOpFunction:
1576  {
1578 
1579  out << typeString(node->getType()) << " ";
1580 
1581  if (name == "main")
1582  {
1583  out << "gl_main(";
1584  }
1585  else
1586  {
1587  out << decorate(name) << (mOutputLod0Function ? "Lod0(" : "(");
1588  }
1589 
1590  TIntermSequence &sequence = node->getSequence();
1591  TIntermSequence &arguments = sequence[0]->getAsAggregate()->getSequence();
1592 
1593  for (unsigned int i = 0; i < arguments.size(); i++)
1594  {
1595  TIntermSymbol *symbol = arguments[i]->getAsSymbolNode();
1596 
1597  if (symbol)
1598  {
1599  if (symbol->getType().getStruct())
1600  {
1601  addConstructor(symbol->getType(), scopedStruct(symbol->getType().getStruct()->name()), NULL);
1602  }
1603 
1604  out << argumentString(symbol);
1605 
1606  if (i < arguments.size() - 1)
1607  {
1608  out << ", ";
1609  }
1610  }
1611  else UNREACHABLE();
1612  }
1613 
1614  out << ")\n"
1615  "{\n";
1616 
1617  if (sequence.size() > 1)
1618  {
1619  mInsideFunction = true;
1620  sequence[1]->traverse(this);
1621  mInsideFunction = false;
1622  }
1623 
1624  out << "}\n";
1625 
1627  {
1628  if (name != "main")
1629  {
1630  mOutputLod0Function = true;
1631  node->traverse(this);
1632  mOutputLod0Function = false;
1633  }
1634  }
1635 
1636  return false;
1637  }
1638  break;
1639  case EOpFunctionCall:
1640  {
1643 
1644  if (node->isUserDefined())
1645  {
1646  out << decorate(name) << (lod0 ? "Lod0(" : "(");
1647  }
1648  else
1649  {
1650  if (name == "texture2D")
1651  {
1652  if (!lod0)
1653  {
1654  if (node->getSequence().size() == 2)
1655  {
1656  mUsesTexture2D = true;
1657  }
1658  else if (node->getSequence().size() == 3)
1659  {
1660  mUsesTexture2D_bias = true;
1661  }
1662  else UNREACHABLE();
1663 
1664  out << "gl_texture2D(";
1665  }
1666  else
1667  {
1668  if (node->getSequence().size() == 2)
1669  {
1670  mUsesTexture2DLod0 = true;
1671  }
1672  else if (node->getSequence().size() == 3)
1673  {
1674  mUsesTexture2DLod0_bias = true;
1675  }
1676  else UNREACHABLE();
1677 
1678  out << "gl_texture2DLod0(";
1679  }
1680  }
1681  else if (name == "texture2DProj")
1682  {
1683  if (!lod0)
1684  {
1685  if (node->getSequence().size() == 2)
1686  {
1687  mUsesTexture2DProj = true;
1688  }
1689  else if (node->getSequence().size() == 3)
1690  {
1691  mUsesTexture2DProj_bias = true;
1692  }
1693  else UNREACHABLE();
1694 
1695  out << "gl_texture2DProj(";
1696  }
1697  else
1698  {
1699  if (node->getSequence().size() == 2)
1700  {
1701  mUsesTexture2DProjLod0 = true;
1702  }
1703  else if (node->getSequence().size() == 3)
1704  {
1706  }
1707  else UNREACHABLE();
1708 
1709  out << "gl_texture2DProjLod0(";
1710  }
1711  }
1712  else if (name == "textureCube")
1713  {
1714  if (!lod0)
1715  {
1716  if (node->getSequence().size() == 2)
1717  {
1718  mUsesTextureCube = true;
1719  }
1720  else if (node->getSequence().size() == 3)
1721  {
1722  mUsesTextureCube_bias = true;
1723  }
1724  else UNREACHABLE();
1725 
1726  out << "gl_textureCube(";
1727  }
1728  else
1729  {
1730  if (node->getSequence().size() == 2)
1731  {
1732  mUsesTextureCubeLod0 = true;
1733  }
1734  else if (node->getSequence().size() == 3)
1735  {
1737  }
1738  else UNREACHABLE();
1739 
1740  out << "gl_textureCubeLod0(";
1741  }
1742  }
1743  else if (name == "texture2DLod")
1744  {
1745  if (node->getSequence().size() == 3)
1746  {
1747  mUsesTexture2DLod = true;
1748  }
1749  else UNREACHABLE();
1750 
1751  out << "gl_texture2DLod(";
1752  }
1753  else if (name == "texture2DProjLod")
1754  {
1755  if (node->getSequence().size() == 3)
1756  {
1757  mUsesTexture2DProjLod = true;
1758  }
1759  else UNREACHABLE();
1760 
1761  out << "gl_texture2DProjLod(";
1762  }
1763  else if (name == "textureCubeLod")
1764  {
1765  if (node->getSequence().size() == 3)
1766  {
1767  mUsesTextureCubeLod = true;
1768  }
1769  else UNREACHABLE();
1770 
1771  out << "gl_textureCubeLod(";
1772  }
1773  else UNREACHABLE();
1774  }
1775 
1776  TIntermSequence &arguments = node->getSequence();
1777 
1778  for (TIntermSequence::iterator arg = arguments.begin(); arg != arguments.end(); arg++)
1779  {
1780  if (mOutputType == SH_HLSL11_OUTPUT && IsSampler((*arg)->getAsTyped()->getBasicType()))
1781  {
1782  out << "texture_";
1783  (*arg)->traverse(this);
1784  out << ", sampler_";
1785  }
1786 
1787  (*arg)->traverse(this);
1788 
1789  if (arg < arguments.end() - 1)
1790  {
1791  out << ", ";
1792  }
1793  }
1794 
1795  out << ")";
1796 
1797  return false;
1798  }
1799  break;
1800  case EOpParameters: outputTriplet(visit, "(", ", ", ")\n{\n"); break;
1801  case EOpConstructFloat:
1802  addConstructor(node->getType(), "vec1", &node->getSequence());
1803  outputTriplet(visit, "vec1(", "", ")");
1804  break;
1805  case EOpConstructVec2:
1806  addConstructor(node->getType(), "vec2", &node->getSequence());
1807  outputTriplet(visit, "vec2(", ", ", ")");
1808  break;
1809  case EOpConstructVec3:
1810  addConstructor(node->getType(), "vec3", &node->getSequence());
1811  outputTriplet(visit, "vec3(", ", ", ")");
1812  break;
1813  case EOpConstructVec4:
1814  addConstructor(node->getType(), "vec4", &node->getSequence());
1815  outputTriplet(visit, "vec4(", ", ", ")");
1816  break;
1817  case EOpConstructBool:
1818  addConstructor(node->getType(), "bvec1", &node->getSequence());
1819  outputTriplet(visit, "bvec1(", "", ")");
1820  break;
1821  case EOpConstructBVec2:
1822  addConstructor(node->getType(), "bvec2", &node->getSequence());
1823  outputTriplet(visit, "bvec2(", ", ", ")");
1824  break;
1825  case EOpConstructBVec3:
1826  addConstructor(node->getType(), "bvec3", &node->getSequence());
1827  outputTriplet(visit, "bvec3(", ", ", ")");
1828  break;
1829  case EOpConstructBVec4:
1830  addConstructor(node->getType(), "bvec4", &node->getSequence());
1831  outputTriplet(visit, "bvec4(", ", ", ")");
1832  break;
1833  case EOpConstructInt:
1834  addConstructor(node->getType(), "ivec1", &node->getSequence());
1835  outputTriplet(visit, "ivec1(", "", ")");
1836  break;
1837  case EOpConstructIVec2:
1838  addConstructor(node->getType(), "ivec2", &node->getSequence());
1839  outputTriplet(visit, "ivec2(", ", ", ")");
1840  break;
1841  case EOpConstructIVec3:
1842  addConstructor(node->getType(), "ivec3", &node->getSequence());
1843  outputTriplet(visit, "ivec3(", ", ", ")");
1844  break;
1845  case EOpConstructIVec4:
1846  addConstructor(node->getType(), "ivec4", &node->getSequence());
1847  outputTriplet(visit, "ivec4(", ", ", ")");
1848  break;
1849  case EOpConstructMat2:
1850  addConstructor(node->getType(), "mat2", &node->getSequence());
1851  outputTriplet(visit, "mat2(", ", ", ")");
1852  break;
1853  case EOpConstructMat3:
1854  addConstructor(node->getType(), "mat3", &node->getSequence());
1855  outputTriplet(visit, "mat3(", ", ", ")");
1856  break;
1857  case EOpConstructMat4:
1858  addConstructor(node->getType(), "mat4", &node->getSequence());
1859  outputTriplet(visit, "mat4(", ", ", ")");
1860  break;
1861  case EOpConstructStruct:
1862  addConstructor(node->getType(), scopedStruct(node->getType().getStruct()->name()), &node->getSequence());
1863  outputTriplet(visit, structLookup(node->getType().getStruct()->name()) + "_ctor(", ", ", ")");
1864  break;
1865  case EOpLessThan: outputTriplet(visit, "(", " < ", ")"); break;
1866  case EOpGreaterThan: outputTriplet(visit, "(", " > ", ")"); break;
1867  case EOpLessThanEqual: outputTriplet(visit, "(", " <= ", ")"); break;
1868  case EOpGreaterThanEqual: outputTriplet(visit, "(", " >= ", ")"); break;
1869  case EOpVectorEqual: outputTriplet(visit, "(", " == ", ")"); break;
1870  case EOpVectorNotEqual: outputTriplet(visit, "(", " != ", ")"); break;
1871  case EOpMod:
1872  {
1873  // We need to look at the number of components in both arguments
1874  switch (node->getSequence()[0]->getAsTyped()->getNominalSize() * 10
1875  + node->getSequence()[1]->getAsTyped()->getNominalSize())
1876  {
1877  case 11: mUsesMod1 = true; break;
1878  case 22: mUsesMod2v = true; break;
1879  case 21: mUsesMod2f = true; break;
1880  case 33: mUsesMod3v = true; break;
1881  case 31: mUsesMod3f = true; break;
1882  case 44: mUsesMod4v = true; break;
1883  case 41: mUsesMod4f = true; break;
1884  default: UNREACHABLE();
1885  }
1886 
1887  outputTriplet(visit, "mod(", ", ", ")");
1888  }
1889  break;
1890  case EOpPow: outputTriplet(visit, "pow(", ", ", ")"); break;
1891  case EOpAtan:
1892  ASSERT(node->getSequence().size() == 2); // atan(x) is a unary operator
1893  switch (node->getSequence()[0]->getAsTyped()->getNominalSize())
1894  {
1895  case 1: mUsesAtan2_1 = true; break;
1896  case 2: mUsesAtan2_2 = true; break;
1897  case 3: mUsesAtan2_3 = true; break;
1898  case 4: mUsesAtan2_4 = true; break;
1899  default: UNREACHABLE();
1900  }
1901  outputTriplet(visit, "atanyx(", ", ", ")");
1902  break;
1903  case EOpMin: outputTriplet(visit, "min(", ", ", ")"); break;
1904  case EOpMax: outputTriplet(visit, "max(", ", ", ")"); break;
1905  case EOpClamp: outputTriplet(visit, "clamp(", ", ", ")"); break;
1906  case EOpMix: outputTriplet(visit, "lerp(", ", ", ")"); break;
1907  case EOpStep: outputTriplet(visit, "step(", ", ", ")"); break;
1908  case EOpSmoothStep: outputTriplet(visit, "smoothstep(", ", ", ")"); break;
1909  case EOpDistance: outputTriplet(visit, "distance(", ", ", ")"); break;
1910  case EOpDot: outputTriplet(visit, "dot(", ", ", ")"); break;
1911  case EOpCross: outputTriplet(visit, "cross(", ", ", ")"); break;
1912  case EOpFaceForward:
1913  {
1914  switch (node->getSequence()[0]->getAsTyped()->getNominalSize()) // Number of components in the first argument
1915  {
1916  case 1: mUsesFaceforward1 = true; break;
1917  case 2: mUsesFaceforward2 = true; break;
1918  case 3: mUsesFaceforward3 = true; break;
1919  case 4: mUsesFaceforward4 = true; break;
1920  default: UNREACHABLE();
1921  }
1922 
1923  outputTriplet(visit, "faceforward(", ", ", ")");
1924  }
1925  break;
1926  case EOpReflect: outputTriplet(visit, "reflect(", ", ", ")"); break;
1927  case EOpRefract: outputTriplet(visit, "refract(", ", ", ")"); break;
1928  case EOpMul: outputTriplet(visit, "(", " * ", ")"); break;
1929  default: UNREACHABLE();
1930  }
1931 
1932  return true;
1933 }
1934 
1936 {
1937  TInfoSinkBase &out = mBody;
1938 
1939  if (node->usesTernaryOperator())
1940  {
1941  out << "s" << mUnfoldShortCircuit->getNextTemporaryIndex();
1942  }
1943  else // if/else statement
1944  {
1946 
1947  out << "if(";
1948 
1949  node->getCondition()->traverse(this);
1950 
1951  out << ")\n";
1952 
1954  out << "{\n";
1955 
1956  if (node->getTrueBlock())
1957  {
1959  }
1960 
1962  out << ";\n}\n";
1963 
1964  if (node->getFalseBlock())
1965  {
1966  out << "else\n";
1967 
1969  out << "{\n";
1970 
1973 
1975  out << ";\n}\n";
1976  }
1977  }
1978 
1979  return false;
1980 }
1981 
1983 {
1985 }
1986 
1988 {
1989  bool wasDiscontinuous = mInsideDiscontinuousLoop;
1990 
1992  {
1994  }
1995 
1997  {
1998  if (handleExcessiveLoop(node))
1999  {
2000  return false;
2001  }
2002  }
2003 
2004  TInfoSinkBase &out = mBody;
2005 
2006  if (node->getType() == ELoopDoWhile)
2007  {
2008  out << "{do\n";
2009 
2011  out << "{\n";
2012  }
2013  else
2014  {
2015  out << "{for(";
2016 
2017  if (node->getInit())
2018  {
2019  node->getInit()->traverse(this);
2020  }
2021 
2022  out << "; ";
2023 
2024  if (node->getCondition())
2025  {
2026  node->getCondition()->traverse(this);
2027  }
2028 
2029  out << "; ";
2030 
2031  if (node->getExpression())
2032  {
2033  node->getExpression()->traverse(this);
2034  }
2035 
2036  out << ")\n";
2037 
2039  out << "{\n";
2040  }
2041 
2042  if (node->getBody())
2043  {
2044  traverseStatements(node->getBody());
2045  }
2046 
2048  out << ";}\n";
2049 
2050  if (node->getType() == ELoopDoWhile)
2051  {
2053  out << "while(\n";
2054 
2055  node->getCondition()->traverse(this);
2056 
2057  out << ");";
2058  }
2059 
2060  out << "}\n";
2061 
2062  mInsideDiscontinuousLoop = wasDiscontinuous;
2063 
2064  return false;
2065 }
2066 
2068 {
2069  TInfoSinkBase &out = mBody;
2070 
2071  switch (node->getFlowOp())
2072  {
2073  case EOpKill: outputTriplet(visit, "discard;\n", "", ""); break;
2074  case EOpBreak:
2075  if (visit == PreVisit)
2076  {
2077  if (mExcessiveLoopIndex)
2078  {
2079  out << "{Break";
2081  out << " = true; break;}\n";
2082  }
2083  else
2084  {
2085  out << "break;\n";
2086  }
2087  }
2088  break;
2089  case EOpContinue: outputTriplet(visit, "continue;\n", "", ""); break;
2090  case EOpReturn:
2091  if (visit == PreVisit)
2092  {
2093  if (node->getExpression())
2094  {
2095  out << "return ";
2096  }
2097  else
2098  {
2099  out << "return;\n";
2100  }
2101  }
2102  else if (visit == PostVisit)
2103  {
2104  if (node->getExpression())
2105  {
2106  out << ";\n";
2107  }
2108  }
2109  break;
2110  default: UNREACHABLE();
2111  }
2112 
2113  return true;
2114 }
2115 
2117 {
2118  if (isSingleStatement(node))
2119  {
2121  }
2122 
2123  node->traverse(this);
2124 }
2125 
2127 {
2128  TIntermAggregate *aggregate = node->getAsAggregate();
2129 
2130  if (aggregate)
2131  {
2132  if (aggregate->getOp() == EOpSequence)
2133  {
2134  return false;
2135  }
2136  else
2137  {
2138  for (TIntermSequence::iterator sit = aggregate->getSequence().begin(); sit != aggregate->getSequence().end(); sit++)
2139  {
2140  if (!isSingleStatement(*sit))
2141  {
2142  return false;
2143  }
2144  }
2145 
2146  return true;
2147  }
2148  }
2149 
2150  return true;
2151 }
2152 
2153 // Handle loops with more than 254 iterations (unsupported by D3D9) by splitting them
2154 // (The D3D documentation says 255 iterations, but the compiler complains at anything more than 254).
2156 {
2157  const int MAX_LOOP_ITERATIONS = 254;
2158  TInfoSinkBase &out = mBody;
2159 
2160  // Parse loops of the form:
2161  // for(int index = initial; index [comparator] limit; index += increment)
2163  TOperator comparator = EOpNull;
2164  int initial = 0;
2165  int limit = 0;
2166  int increment = 0;
2167 
2168  // Parse index name and intial value
2169  if (node->getInit())
2170  {
2172 
2173  if (init)
2174  {
2175  TIntermSequence &sequence = init->getSequence();
2176  TIntermTyped *variable = sequence[0]->getAsTyped();
2177 
2178  if (variable && variable->getQualifier() == EvqTemporary)
2179  {
2180  TIntermBinary *assign = variable->getAsBinaryNode();
2181 
2182  if (assign->getOp() == EOpInitialize)
2183  {
2184  TIntermSymbol *symbol = assign->getLeft()->getAsSymbolNode();
2185  TIntermConstantUnion *constant = assign->getRight()->getAsConstantUnion();
2186 
2187  if (symbol && constant)
2188  {
2189  if (constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)
2190  {
2191  index = symbol;
2192  initial = constant->getIConst(0);
2193  }
2194  }
2195  }
2196  }
2197  }
2198  }
2199 
2200  // Parse comparator and limit value
2201  if (index != NULL && node->getCondition())
2202  {
2203  TIntermBinary *test = node->getCondition()->getAsBinaryNode();
2204 
2205  if (test && test->getLeft()->getAsSymbolNode()->getId() == index->getId())
2206  {
2207  TIntermConstantUnion *constant = test->getRight()->getAsConstantUnion();
2208 
2209  if (constant)
2210  {
2211  if (constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)
2212  {
2213  comparator = test->getOp();
2214  limit = constant->getIConst(0);
2215  }
2216  }
2217  }
2218  }
2219 
2220  // Parse increment
2221  if (index != NULL && comparator != EOpNull && node->getExpression())
2222  {
2223  TIntermBinary *binaryTerminal = node->getExpression()->getAsBinaryNode();
2224  TIntermUnary *unaryTerminal = node->getExpression()->getAsUnaryNode();
2225 
2226  if (binaryTerminal)
2227  {
2228  TOperator op = binaryTerminal->getOp();
2229  TIntermConstantUnion *constant = binaryTerminal->getRight()->getAsConstantUnion();
2230 
2231  if (constant)
2232  {
2233  if (constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)
2234  {
2235  int value = constant->getIConst(0);
2236 
2237  switch (op)
2238  {
2239  case EOpAddAssign: increment = value; break;
2240  case EOpSubAssign: increment = -value; break;
2241  default: UNIMPLEMENTED();
2242  }
2243  }
2244  }
2245  }
2246  else if (unaryTerminal)
2247  {
2248  TOperator op = unaryTerminal->getOp();
2249 
2250  switch (op)
2251  {
2252  case EOpPostIncrement: increment = 1; break;
2253  case EOpPostDecrement: increment = -1; break;
2254  case EOpPreIncrement: increment = 1; break;
2255  case EOpPreDecrement: increment = -1; break;
2256  default: UNIMPLEMENTED();
2257  }
2258  }
2259  }
2260 
2261  if (index != NULL && comparator != EOpNull && increment != 0)
2262  {
2263  if (comparator == EOpLessThanEqual)
2264  {
2265  comparator = EOpLessThan;
2266  limit += 1;
2267  }
2268 
2269  if (comparator == EOpLessThan)
2270  {
2271  int iterations = (limit - initial) / increment;
2272 
2273  if (iterations <= MAX_LOOP_ITERATIONS)
2274  {
2275  return false; // Not an excessive loop
2276  }
2277 
2278  TIntermSymbol *restoreIndex = mExcessiveLoopIndex;
2280 
2281  out << "{int ";
2282  index->traverse(this);
2283  out << ";\n"
2284  "bool Break";
2285  index->traverse(this);
2286  out << " = false;\n";
2287 
2288  bool firstLoopFragment = true;
2289 
2290  while (iterations > 0)
2291  {
2292  int clampedLimit = initial + increment * std::min(MAX_LOOP_ITERATIONS, iterations);
2293 
2294  if (!firstLoopFragment)
2295  {
2296  out << "if(!Break";
2297  index->traverse(this);
2298  out << ") {\n";
2299  }
2300 
2301  if (iterations <= MAX_LOOP_ITERATIONS) // Last loop fragment
2302  {
2303  mExcessiveLoopIndex = NULL; // Stops setting the Break flag
2304  }
2305 
2306  // for(int index = initial; index < clampedLimit; index += increment)
2307 
2308  out << "for(";
2309  index->traverse(this);
2310  out << " = ";
2311  out << initial;
2312 
2313  out << "; ";
2314  index->traverse(this);
2315  out << " < ";
2316  out << clampedLimit;
2317 
2318  out << "; ";
2319  index->traverse(this);
2320  out << " += ";
2321  out << increment;
2322  out << ")\n";
2323 
2325  out << "{\n";
2326 
2327  if (node->getBody())
2328  {
2329  node->getBody()->traverse(this);
2330  }
2331 
2333  out << ";}\n";
2334 
2335  if (!firstLoopFragment)
2336  {
2337  out << "}\n";
2338  }
2339 
2340  firstLoopFragment = false;
2341 
2342  initial += MAX_LOOP_ITERATIONS * increment;
2343  iterations -= MAX_LOOP_ITERATIONS;
2344  }
2345 
2346  out << "}";
2347 
2348  mExcessiveLoopIndex = restoreIndex;
2349 
2350  return true;
2351  }
2352  else UNIMPLEMENTED();
2353  }
2354 
2355  return false; // Not handled as an excessive loop
2356 }
2357 
2358 void OutputHLSL::outputTriplet(Visit visit, const TString &preString, const TString &inString, const TString &postString)
2359 {
2360  TInfoSinkBase &out = mBody;
2361 
2362  if (visit == PreVisit)
2363  {
2364  out << preString;
2365  }
2366  else if (visit == InVisit)
2367  {
2368  out << inString;
2369  }
2370  else if (visit == PostVisit)
2371  {
2372  out << postString;
2373  }
2374 }
2375 
2377 {
2378  if ((mContext.compileOptions & SH_LINE_DIRECTIVES) && (line > 0))
2379  {
2380  mBody << "\n";
2381  mBody << "#line " << line;
2382 
2383  if (mContext.sourcePath)
2384  {
2385  mBody << " \"" << mContext.sourcePath << "\"";
2386  }
2387 
2388  mBody << "\n";
2389  }
2390 }
2391 
2393 {
2394  TQualifier qualifier = symbol->getQualifier();
2395  const TType &type = symbol->getType();
2396  TString name = symbol->getSymbol();
2397 
2398  if (name.empty()) // HLSL demands named arguments, also for prototypes
2399  {
2400  name = "x" + str(mUniqueIndex++);
2401  }
2402  else
2403  {
2404  name = decorate(name);
2405  }
2406 
2408  {
2409  return qualifierString(qualifier) + " " + textureString(type) + " texture_" + name + arrayString(type) + ", " +
2410  qualifierString(qualifier) + " SamplerState sampler_" + name + arrayString(type);
2411  }
2412 
2413  return qualifierString(qualifier) + " " + typeString(type) + " " + name + arrayString(type);
2414 }
2415 
2417 {
2418  switch(qualifier)
2419  {
2420  case EvqIn: return "in";
2421  case EvqOut: return "out";
2422  case EvqInOut: return "inout";
2423  case EvqConstReadOnly: return "const";
2424  default: UNREACHABLE();
2425  }
2426 
2427  return "";
2428 }
2429 
2431 {
2432  if (type.getBasicType() == EbtStruct)
2433  {
2434  const TString& typeName = type.getStruct()->name();
2435  if (typeName != "")
2436  {
2437  return structLookup(typeName);
2438  }
2439  else // Nameless structure, define in place
2440  {
2441  const TFieldList &fields = type.getStruct()->fields();
2442 
2443  TString string = "struct\n"
2444  "{\n";
2445 
2446  for (unsigned int i = 0; i < fields.size(); i++)
2447  {
2448  const TField *field = fields[i];
2449 
2450  string += " " + typeString(*field->type()) + " " + decorate(field->name()) + arrayString(*field->type()) + ";\n";
2451  }
2452 
2453  string += "} ";
2454 
2455  return string;
2456  }
2457  }
2458  else if (type.isMatrix())
2459  {
2460  switch (type.getNominalSize())
2461  {
2462  case 2: return "float2x2";
2463  case 3: return "float3x3";
2464  case 4: return "float4x4";
2465  }
2466  }
2467  else
2468  {
2469  switch (type.getBasicType())
2470  {
2471  case EbtFloat:
2472  switch (type.getNominalSize())
2473  {
2474  case 1: return "float";
2475  case 2: return "float2";
2476  case 3: return "float3";
2477  case 4: return "float4";
2478  }
2479  case EbtInt:
2480  switch (type.getNominalSize())
2481  {
2482  case 1: return "int";
2483  case 2: return "int2";
2484  case 3: return "int3";
2485  case 4: return "int4";
2486  }
2487  case EbtBool:
2488  switch (type.getNominalSize())
2489  {
2490  case 1: return "bool";
2491  case 2: return "bool2";
2492  case 3: return "bool3";
2493  case 4: return "bool4";
2494  }
2495  case EbtVoid:
2496  return "void";
2497  case EbtSampler2D:
2498  return "sampler2D";
2499  case EbtSamplerCube:
2500  return "samplerCUBE";
2501  case EbtSamplerExternalOES:
2502  return "sampler2D";
2503  default:
2504  break;
2505  }
2506  }
2507 
2508  UNREACHABLE();
2509  return "<unknown type>";
2510 }
2511 
2513 {
2514  switch (type.getBasicType())
2515  {
2516  case EbtSampler2D:
2517  return "Texture2D";
2518  case EbtSamplerCube:
2519  return "TextureCube";
2520  case EbtSamplerExternalOES:
2521  return "Texture2D";
2522  default:
2523  break;
2524  }
2525 
2526  UNREACHABLE();
2527  return "<unknown texture type>";
2528 }
2529 
2531 {
2532  if (!type.isArray())
2533  {
2534  return "";
2535  }
2536 
2537  return "[" + str(type.getArraySize()) + "]";
2538 }
2539 
2541 {
2542  TString string;
2543 
2544  size_t size = type.getObjectSize();
2545  for (size_t component = 0; component < size; component++)
2546  {
2547  string += "0";
2548 
2549  if (component + 1 < size)
2550  {
2551  string += ", ";
2552  }
2553  }
2554 
2555  return "{" + string + "}";
2556 }
2557 
2558 void OutputHLSL::addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters)
2559 {
2560  if (name == "")
2561  {
2562  return; // Nameless structures don't have constructors
2563  }
2564 
2565  if (type.getStruct() && mStructNames.find(decorate(name)) != mStructNames.end())
2566  {
2567  return; // Already added
2568  }
2569 
2570  TType ctorType = type;
2571  ctorType.clearArrayness();
2572  ctorType.setPrecision(EbpHigh);
2573  ctorType.setQualifier(EvqTemporary);
2574 
2575  TString ctorName = type.getStruct() ? decorate(name) : name;
2576 
2577  typedef std::vector<TType> ParameterArray;
2578  ParameterArray ctorParameters;
2579 
2580  if (type.getStruct())
2581  {
2582  mStructNames.insert(decorate(name));
2583 
2584  TString structure;
2585  structure += "struct " + decorate(name) + "\n"
2586  "{\n";
2587 
2588  const TFieldList &fields = type.getStruct()->fields();
2589 
2590  for (unsigned int i = 0; i < fields.size(); i++)
2591  {
2592  const TField *field = fields[i];
2593 
2594  structure += " " + typeString(*field->type()) + " " + decorateField(field->name(), type) + arrayString(*field->type()) + ";\n";
2595  }
2596 
2597  structure += "};\n";
2598 
2599  if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structure) == mStructDeclarations.end())
2600  {
2601  mStructDeclarations.push_back(structure);
2602  }
2603 
2604  for (unsigned int i = 0; i < fields.size(); i++)
2605  {
2606  ctorParameters.push_back(*fields[i]->type());
2607  }
2608  }
2609  else if (parameters)
2610  {
2611  for (TIntermSequence::const_iterator parameter = parameters->begin(); parameter != parameters->end(); parameter++)
2612  {
2613  ctorParameters.push_back((*parameter)->getAsTyped()->getType());
2614  }
2615  }
2616  else UNREACHABLE();
2617 
2618  TString constructor;
2619 
2620  if (ctorType.getStruct())
2621  {
2622  constructor += ctorName + " " + ctorName + "_ctor(";
2623  }
2624  else // Built-in type
2625  {
2626  constructor += typeString(ctorType) + " " + ctorName + "(";
2627  }
2628 
2629  for (unsigned int parameter = 0; parameter < ctorParameters.size(); parameter++)
2630  {
2631  const TType &type = ctorParameters[parameter];
2632 
2633  constructor += typeString(type) + " x" + str(parameter) + arrayString(type);
2634 
2635  if (parameter < ctorParameters.size() - 1)
2636  {
2637  constructor += ", ";
2638  }
2639  }
2640 
2641  constructor += ")\n"
2642  "{\n";
2643 
2644  if (ctorType.getStruct())
2645  {
2646  constructor += " " + ctorName + " structure = {";
2647  }
2648  else
2649  {
2650  constructor += " return " + typeString(ctorType) + "(";
2651  }
2652 
2653  if (ctorType.isMatrix() && ctorParameters.size() == 1)
2654  {
2655  int dim = ctorType.getNominalSize();
2656  const TType &parameter = ctorParameters[0];
2657 
2658  if (parameter.isScalar())
2659  {
2660  for (int row = 0; row < dim; row++)
2661  {
2662  for (int col = 0; col < dim; col++)
2663  {
2664  constructor += TString((row == col) ? "x0" : "0.0");
2665 
2666  if (row < dim - 1 || col < dim - 1)
2667  {
2668  constructor += ", ";
2669  }
2670  }
2671  }
2672  }
2673  else if (parameter.isMatrix())
2674  {
2675  for (int row = 0; row < dim; row++)
2676  {
2677  for (int col = 0; col < dim; col++)
2678  {
2679  if (row < parameter.getNominalSize() && col < parameter.getNominalSize())
2680  {
2681  constructor += TString("x0") + "[" + str(row) + "]" + "[" + str(col) + "]";
2682  }
2683  else
2684  {
2685  constructor += TString((row == col) ? "1.0" : "0.0");
2686  }
2687 
2688  if (row < dim - 1 || col < dim - 1)
2689  {
2690  constructor += ", ";
2691  }
2692  }
2693  }
2694  }
2695  else UNREACHABLE();
2696  }
2697  else
2698  {
2699  size_t remainingComponents = ctorType.getObjectSize();
2700  size_t parameterIndex = 0;
2701 
2702  while (remainingComponents > 0)
2703  {
2704  const TType &parameter = ctorParameters[parameterIndex];
2705  const size_t parameterSize = parameter.getObjectSize();
2706  bool moreParameters = parameterIndex + 1 < ctorParameters.size();
2707 
2708  constructor += "x" + str(parameterIndex);
2709 
2710  if (parameter.isScalar())
2711  {
2712  ASSERT(parameterSize <= remainingComponents);
2713  remainingComponents -= parameterSize;
2714  }
2715  else if (parameter.isVector())
2716  {
2717  if (remainingComponents == parameterSize || moreParameters)
2718  {
2719  ASSERT(parameterSize <= remainingComponents);
2720  remainingComponents -= parameterSize;
2721  }
2722  else if (remainingComponents < static_cast<size_t>(parameter.getNominalSize()))
2723  {
2724  switch (remainingComponents)
2725  {
2726  case 1: constructor += ".x"; break;
2727  case 2: constructor += ".xy"; break;
2728  case 3: constructor += ".xyz"; break;
2729  case 4: constructor += ".xyzw"; break;
2730  default: UNREACHABLE();
2731  }
2732 
2733  remainingComponents = 0;
2734  }
2735  else UNREACHABLE();
2736  }
2737  else if (parameter.isMatrix() || parameter.getStruct())
2738  {
2739  ASSERT(remainingComponents == parameterSize || moreParameters);
2740  ASSERT(parameterSize <= remainingComponents);
2741 
2742  remainingComponents -= parameterSize;
2743  }
2744  else UNREACHABLE();
2745 
2746  if (moreParameters)
2747  {
2748  parameterIndex++;
2749  }
2750 
2751  if (remainingComponents)
2752  {
2753  constructor += ", ";
2754  }
2755  }
2756  }
2757 
2758  if (ctorType.getStruct())
2759  {
2760  constructor += "};\n"
2761  " return structure;\n"
2762  "}\n";
2763  }
2764  else
2765  {
2766  constructor += ");\n"
2767  "}\n";
2768  }
2769 
2770  mConstructors.insert(constructor);
2771 }
2772 
2774 {
2775  TInfoSinkBase &out = mBody;
2776 
2777  if (type.getBasicType() == EbtStruct)
2778  {
2779  out << structLookup(type.getStruct()->name()) + "_ctor(";
2780 
2781  const TFieldList &fields = type.getStruct()->fields();
2782 
2783  for (size_t i = 0; i < fields.size(); i++)
2784  {
2785  const TType *fieldType = fields[i]->type();
2786 
2787  constUnion = writeConstantUnion(*fieldType, constUnion);
2788 
2789  if (i != fields.size() - 1)
2790  {
2791  out << ", ";
2792  }
2793  }
2794 
2795  out << ")";
2796  }
2797  else
2798  {
2799  size_t size = type.getObjectSize();
2800  bool writeType = size > 1;
2801 
2802  if (writeType)
2803  {
2804  out << typeString(type) << "(";
2805  }
2806 
2807  for (size_t i = 0; i < size; i++, constUnion++)
2808  {
2809  switch (constUnion->getType())
2810  {
2811  case EbtFloat: out << std::min(FLT_MAX, std::max(-FLT_MAX, constUnion->getFConst())); break;
2812  case EbtInt: out << constUnion->getIConst(); break;
2813  case EbtBool: out << constUnion->getBConst(); break;
2814  default: UNREACHABLE();
2815  }
2816 
2817  if (i != size - 1)
2818  {
2819  out << ", ";
2820  }
2821  }
2822 
2823  if (writeType)
2824  {
2825  out << ")";
2826  }
2827  }
2828 
2829  return constUnion;
2830 }
2831 
2832 TString OutputHLSL::scopeString(unsigned int depthLimit)
2833 {
2834  TString string;
2835 
2836  for (unsigned int i = 0; i < mScopeBracket.size() && i < depthLimit; i++)
2837  {
2838  string += "_" + str(i);
2839  }
2840 
2841  return string;
2842 }
2843 
2845 {
2846  if (typeName == "")
2847  {
2848  return typeName;
2849  }
2850 
2851  return typeName + scopeString(mScopeDepth);
2852 }
2853 
2855 {
2856  for (int depth = mScopeDepth; depth >= 0; depth--)
2857  {
2858  TString scopedName = decorate(typeName + scopeString(depth));
2859 
2860  for (StructNames::iterator structName = mStructNames.begin(); structName != mStructNames.end(); structName++)
2861  {
2862  if (*structName == scopedName)
2863  {
2864  return scopedName;
2865  }
2866  }
2867  }
2868 
2869  UNREACHABLE(); // Should have found a matching constructor
2870 
2871  return typeName;
2872 }
2873 
2875 {
2876  if (string.compare(0, 3, "gl_") != 0 && string.compare(0, 3, "dx_") != 0)
2877  {
2878  return "_" + string;
2879  }
2880 
2881  return string;
2882 }
2883 
2885 {
2886  if (type.getBasicType() == EbtSamplerExternalOES)
2887  {
2888  return "ex_" + string;
2889  }
2890 
2891  return decorate(string);
2892 }
2893 
2894 TString OutputHLSL::decorateField(const TString &string, const TType &structure)
2895 {
2896  if (structure.getStruct()->name().compare(0, 3, "gl_") != 0)
2897  {
2898  return decorate(string);
2899  }
2900 
2901  return string;
2902 }
2903 
2905 {
2906  ASSERT(operand->getQualifier() == EvqUniform);
2907 
2908  if (IsSampler(operand->getBasicType()))
2909  {
2910  return "s" + str(samplerRegister(operand));
2911  }
2912 
2913  return "c" + str(uniformRegister(operand));
2914 }
2915 
2917 {
2918  const TType &type = sampler->getType();
2919  ASSERT(IsSampler(type.getBasicType()));
2920 
2921  int index = mSamplerRegister;
2922  mSamplerRegister += sampler->totalRegisterCount();
2923 
2924  declareUniform(type, sampler->getSymbol(), index);
2925 
2926  return index;
2927 }
2928 
2930 {
2931  const TType &type = uniform->getType();
2932  ASSERT(!IsSampler(type.getBasicType()));
2933 
2934  int index = mUniformRegister;
2935  mUniformRegister += uniform->totalRegisterCount();
2936 
2937  declareUniform(type, uniform->getSymbol(), index);
2938 
2939  return index;
2940 }
2941 
2943 {
2944  TStructure *structure = type.getStruct();
2945 
2946  if (!structure)
2947  {
2948  mActiveUniforms.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), type.getArraySize(), index));
2949  }
2950  else
2951  {
2952  const TFieldList &fields = structure->fields();
2953 
2954  if (type.isArray())
2955  {
2956  int elementIndex = index;
2957 
2958  for (int i = 0; i < type.getArraySize(); i++)
2959  {
2960  for (size_t j = 0; j < fields.size(); j++)
2961  {
2962  const TType &fieldType = *fields[j]->type();
2963  const TString uniformName = name + "[" + str(i) + "]." + fields[j]->name();
2964  declareUniform(fieldType, uniformName, elementIndex);
2965  elementIndex += fieldType.totalRegisterCount();
2966  }
2967  }
2968  }
2969  else
2970  {
2971  int fieldIndex = index;
2972 
2973  for (size_t i = 0; i < fields.size(); i++)
2974  {
2975  const TType &fieldType = *fields[i]->type();
2976  const TString uniformName = name + "." + fields[i]->name();
2977  declareUniform(fieldType, uniformName, fieldIndex);
2978  fieldIndex += fieldType.totalRegisterCount();
2979  }
2980  }
2981  }
2982 }
2983 
2985 {
2986  if (type.getBasicType() == EbtFloat)
2987  {
2988  if (type.isScalar())
2989  {
2990  return GL_FLOAT;
2991  }
2992  else if (type.isVector())
2993  {
2994  switch(type.getNominalSize())
2995  {
2996  case 2: return GL_FLOAT_VEC2;
2997  case 3: return GL_FLOAT_VEC3;
2998  case 4: return GL_FLOAT_VEC4;
2999  default: UNREACHABLE();
3000  }
3001  }
3002  else if (type.isMatrix())
3003  {
3004  switch(type.getNominalSize())
3005  {
3006  case 2: return GL_FLOAT_MAT2;
3007  case 3: return GL_FLOAT_MAT3;
3008  case 4: return GL_FLOAT_MAT4;
3009  default: UNREACHABLE();
3010  }
3011  }
3012  else UNREACHABLE();
3013  }
3014  else if (type.getBasicType() == EbtInt)
3015  {
3016  if (type.isScalar())
3017  {
3018  return GL_INT;
3019  }
3020  else if (type.isVector())
3021  {
3022  switch(type.getNominalSize())
3023  {
3024  case 2: return GL_INT_VEC2;
3025  case 3: return GL_INT_VEC3;
3026  case 4: return GL_INT_VEC4;
3027  default: UNREACHABLE();
3028  }
3029  }
3030  else UNREACHABLE();
3031  }
3032  else if (type.getBasicType() == EbtBool)
3033  {
3034  if (type.isScalar())
3035  {
3036  return GL_BOOL;
3037  }
3038  else if (type.isVector())
3039  {
3040  switch(type.getNominalSize())
3041  {
3042  case 2: return GL_BOOL_VEC2;
3043  case 3: return GL_BOOL_VEC3;
3044  case 4: return GL_BOOL_VEC4;
3045  default: UNREACHABLE();
3046  }
3047  }
3048  else UNREACHABLE();
3049  }
3050  else if (type.getBasicType() == EbtSampler2D)
3051  {
3052  return GL_SAMPLER_2D;
3053  }
3054  else if (type.getBasicType() == EbtSamplerCube)
3055  {
3056  return GL_SAMPLER_CUBE;
3057  }
3058  else UNREACHABLE();
3059 
3060  return GL_NONE;
3061 }
3062 
3064 {
3065  if (type.getBasicType() == EbtFloat)
3066  {
3067  switch (type.getPrecision())
3068  {
3069  case EbpHigh: return GL_HIGH_FLOAT;
3070  case EbpMedium: return GL_MEDIUM_FLOAT;
3071  case EbpLow: return GL_LOW_FLOAT;
3072  case EbpUndefined:
3073  // Should be defined as the default precision by the parser
3074  default: UNREACHABLE();
3075  }
3076  }
3077  else if (type.getBasicType() == EbtInt)
3078  {
3079  switch (type.getPrecision())
3080  {
3081  case EbpHigh: return GL_HIGH_INT;
3082  case EbpMedium: return GL_MEDIUM_INT;
3083  case EbpLow: return GL_LOW_INT;
3084  case EbpUndefined:
3085  // Should be defined as the default precision by the parser
3086  default: UNREACHABLE();
3087  }
3088  }
3089 
3090  // Other types (boolean, sampler) don't have a precision
3091  return GL_NONE;
3092 }
3093 
3094 }
bool isUserDefined() const
Definition: intermediate.h:475
TOperator
Definition: intermediate.h:29
EGLSurface EGLint attribute
Definition: eglext.h:301
TInfoSinkBase mBody
Definition: OutputHLSL.h:80
void setPrecision(TPrecision p)
Definition: Types.h:112
bool mUsesTexture2DProj
Definition: OutputHLSL.h:92
Visit
Definition: intermediate.h:524
TOperator getOp() const
Definition: intermediate.h:389
TQualifier
Definition: BaseTypes.h:81
static TString initializer(const TType &type)
bool getBConst()
Definition: ConstantUnion.h:27
#define GL_INT_VEC4
Definition: gl2.h:384
bool mUsesTextureCubeLod0
Definition: OutputHLSL.h:102
bool mUsesFaceforward4
Definition: OutputHLSL.h:123
TIntermSequence & getSequence()
Definition: intermediate.h:469
TIntermNode * getTrueBlock() const
Definition: intermediate.h:514
Definition: Types.h:19
TIntermTyped * getCondition()
Definition: intermediate.h:301
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: gl2ext.h:845
const ShShaderOutput mOutputType
Definition: OutputHLSL.h:74
ShShaderType shaderType
Definition: ParseHelper.h:47
ActiveUniforms mActiveUniforms
Definition: OutputHLSL.h:162
void visitConstantUnion(TIntermConstantUnion *)
unsigned int GLenum
Definition: gl2.h:23
int getId() const
Definition: intermediate.h:348
TIntermTyped * getLeft() const
Definition: intermediate.h:413
#define NULL
Definition: ftobjs.h:61
bool mUsesDepthRange
Definition: OutputHLSL.h:106
#define GL_FLOAT_MAT2
Definition: gl2.h:389
bool mUsesTexture2DProj_bias
Definition: OutputHLSL.h:93
std::vector< Uniform > ActiveUniforms
Definition: Uniform.h:31
virtual TIntermAggregate * getAsAggregate()
Definition: intermediate.h:223
virtual TIntermSymbol * getAsSymbolNode()
Definition: intermediate.h:357
void outputTriplet(Visit visit, const TString &preString, const TString &inString, const TString &postString)
bool IsSampler(TBasicType type)
Definition: BaseTypes.h:70
bool mUsesPointCoord
Definition: OutputHLSL.h:108
bool mUsesFaceforward2
Definition: OutputHLSL.h:121
const TString & name() const
Definition: Types.h:56
TOperator getFlowOp()
Definition: intermediate.h:329
TIntermNode * getFalseBlock() const
Definition: intermediate.h:515
TString textureString(const TType &type)
TIntermTyped * getRight() const
Definition: intermediate.h:414
int totalRegisterCount() const
Definition: intermediate.h:267
static void init(struct bs2b *bs2b)
Definition: bs2b.c:46
#define GL_SAMPLER_2D
Definition: gl2.h:392
TBasicType getBasicType() const
Definition: intermediate.h:254
#define GL_BOOL
Definition: gl2.h:385
#define GL_MEDIUM_FLOAT
Definition: gl2.h:420
bool visitLoop(Visit visit, TIntermLoop *)
int32_t j
Definition: e_log.c:102
virtual TIntermConstantUnion * getAsConstantUnion()
Definition: intermediate.h:375
TBasicType getBasicType() const
Definition: Types.h:108
int getNominalSize() const
Definition: Types.h:118
TString registerString(TIntermSymbol *operand)
const char * sourcePath
Definition: ParseHelper.h:50
EGLImageKHR EGLint * name
Definition: eglext.h:284
OutputHLSL(TParseContext &context, const ShBuiltInResources &resources, ShShaderOutput outputType)
Definition: OutputHLSL.cpp:30
bool mUsesFragData
Definition: OutputHLSL.h:105
const TString & name() const
Definition: Types.h:30
#define GL_SAMPLER_CUBE
Definition: gl2.h:393
GLenum GLenum variable
Definition: glew.h:12631
virtual TIntermBinary * getAsBinaryNode()
Definition: intermediate.h:224
bool mContainsLoopDiscontinuity
Definition: OutputHLSL.h:146
int uniformRegister(TIntermSymbol *uniform)
TQualifier getQualifier() const
Definition: intermediate.h:255
void outputLineDirective(int line)
#define GL_BOOL_VEC2
Definition: gl2.h:386
static TString decorateField(const TString &string, const TType &structure)
Definition: Types.h:93
void setQualifier(TQualifier q)
Definition: Types.h:115
#define GL_FLOAT_MAT3
Definition: gl2.h:390
bool handleExcessiveLoop(TIntermLoop *node)
bool isMatrix() const
Definition: intermediate.h:259
#define GL_LOW_INT
Definition: gl2.h:422
bool mInsideDiscontinuousLoop
Definition: OutputHLSL.h:148
#define GL_INT_VEC2
Definition: gl2.h:382
#define GL_FLOAT_VEC4
Definition: gl2.h:381
int compileOptions
Definition: ParseHelper.h:49
bool isScalar() const
Definition: intermediate.h:262
StructDeclarations mStructDeclarations
Definition: OutputHLSL.h:138
bool isArray() const
Definition: Types.h:162
bool isVector() const
Definition: intermediate.h:261
StructNames mStructNames
Definition: OutputHLSL.h:135
int vectorSize(const TType &type) const
Definition: OutputHLSL.cpp:133
bool isScalar() const
Definition: Types.h:168
static GLenum glVariablePrecision(const TType &type)
static GLenum glVariableType(const TType &type)
bool mUsesFaceforward3
Definition: OutputHLSL.h:122
virtual TIntermConstantUnion * getAsConstantUnion()
Definition: intermediate.h:222
EGLContext EGLenum EGLClientBuffer buffer
Definition: eglext.h:87
int mSamplerRegister
Definition: OutputHLSL.h:153
TPrecision getPrecision() const
Definition: Types.h:111
bool mUsesTexture2DProjLod
Definition: OutputHLSL.h:94
static TString arrayString(const TType &type)
const ConstantUnion * writeConstantUnion(const TType &type, const ConstantUnion *constUnion)
bool mInsideFunction
Definition: OutputHLSL.h:76
TType * type()
Definition: Types.h:27
TString str(int i)
Definition: OutputHLSL.cpp:23
GLenum GLenum GLvoid * row
Definition: glew.h:4447
#define GL_MEDIUM_INT
Definition: gl2.h:423
const ActiveUniforms & getUniforms()
Definition: OutputHLSL.cpp:128
#define GL_HIGH_FLOAT
Definition: gl2.h:421
#define ASSERT(expression)
Definition: debug.h:36
bool mUsesTextureCubeLod0_bias
Definition: OutputHLSL.h:103
float getFConst()
Definition: ConstantUnion.h:26
bool mUsesTexture2D_bias
Definition: OutputHLSL.h:90
bool visitUnary(Visit visit, TIntermUnary *)
#define true
Definition: ftrandom.c:49
bool mUsesTextureCubeLod
Definition: OutputHLSL.h:97
void visitSymbol(TIntermSymbol *)
bool mUsesTexture2D
Definition: OutputHLSL.h:89
TInfoSinkBase & getBodyStream()
Definition: OutputHLSL.cpp:123
GLuint GLsizei GLsizei GLchar * uniformName
Definition: glew.h:6668
bool visitBranch(Visit visit, TIntermBranch *)
int totalRegisterCount() const
Definition: Types.h:147
virtual void traverse(TIntermTraverser *)=0
TIntermNode * getCondition() const
Definition: intermediate.h:513
#define GL_BOOL_VEC3
Definition: gl2.h:387
#define GL_INT
Definition: gl2.h:239
const TSourceLoc & getLine() const
Definition: intermediate.h:217
const TType & getType() const
Definition: intermediate.h:251
virtual TIntermUnary * getAsUnaryNode()
Definition: intermediate.h:225
TIntermNode * getBody()
Definition: intermediate.h:303
TInfoSink & infoSink()
Definition: ParseHelper.h:65
ConstantUnion * getUnionArrayPointer() const
Definition: intermediate.h:369
void traverse(TIntermNode *node)
TBasicType getType() const
TIntermTyped * getExpression()
Definition: intermediate.h:330
const TString & getName() const
Definition: intermediate.h:472
GLsizei const GLchar *const * varyings
Definition: glew.h:10393
#define UNREACHABLE()
Definition: debug.h:47
GLint limit
Definition: glew.h:11829
#define GL_NONE
Definition: gl2.h:456
GLint GLenum GLsizei GLsizei GLsizei depth
Definition: gl2ext.h:845
GLuint index
Definition: glew.h:1800
bool isVector() const
Definition: Types.h:167
#define GL_FLOAT_VEC2
Definition: gl2.h:379
TIntermTyped * getOperand()
Definition: intermediate.h:440
UnfoldShortCircuit * mUnfoldShortCircuit
Definition: OutputHLSL.h:75
bool mUsesFragCoord
Definition: OutputHLSL.h:107
TString scopeString(unsigned int depthLimit)
#define GL_INT_VEC3
Definition: gl2.h:383
virtual void traverse(TIntermTraverser *)
bool mUsesFaceforward1
Definition: OutputHLSL.h:120
#define GL_FLOAT_MAT4
Definition: gl2.h:391
int getIConst(int index) const
Definition: intermediate.h:371
std::basic_string< char, std::char_traits< char >, TStringAllocator > TString
Definition: Common.h:41
TString scopedStruct(const TString &typeName)
bool mUsesTexture2DLod0
Definition: OutputHLSL.h:98
int last_line
Definition: Common.h:21
int mNumRenderTargets
Definition: OutputHLSL.h:129
bool usesTernaryOperator() const
Definition: intermediate.h:512
bool mUsesFrontFacing
Definition: OutputHLSL.h:109
static TString qualifierString(TQualifier qualifier)
EGLSurface EGLint void ** value
Definition: eglext.h:301
static TString unmangleName(const TString &mangledName)
Definition: SymbolTable.h:146
#define GL_LOW_FLOAT
Definition: gl2.h:419
ReferencedSymbols mReferencedAttributes
Definition: OutputHLSL.h:85
int samplerRegister(TIntermSymbol *sampler)
void declareUniform(const TType &type, const TString &name, int index)
bool mUsesTexture2DProjLod0
Definition: OutputHLSL.h:100
TIntermNode * treeRoot
Definition: ParseHelper.h:51
bool visitAggregate(Visit visit, TIntermAggregate *)
ReferencedSymbols mReferencedUniforms
Definition: OutputHLSL.h:84
bool visitSelection(Visit visit, TIntermSelection *)
int getArraySize() const
Definition: Types.h:163
TIntermTyped * getExpression()
Definition: intermediate.h:302
#define GL_BOOL_VEC4
Definition: gl2.h:388
ScopeBracket mScopeBracket
Definition: OutputHLSL.h:141
GLsizei const GLcharARB ** string
Definition: glew.h:5638
TString structLookup(const TString &typeName)
void clearArrayness()
Definition: Types.h:165
const TExtensionBehavior & extensionBehavior() const
Definition: ParseHelper.h:102
void traverseStatements(TIntermNode *node)
ReferencedSymbols mReferencedVaryings
Definition: OutputHLSL.h:86
void addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters)
int mUniformRegister
Definition: OutputHLSL.h:152
bool isMatrix() const
Definition: Types.h:159
ShShaderType
Definition: ShaderLang.h:48
virtual void traverse(TIntermTraverser *)
int first_line
Definition: Common.h:19
bool containsLoopDiscontinuity(TIntermNode *node)
ShShaderOutput
Definition: ShaderLang.h:80
size_t getObjectSize() const
Definition: SymbolTable.cpp:61
#define GL_FLOAT
Definition: gl2.h:241
const TFieldList & fields() const
Definition: Types.h:57
TStructure * getStruct() const
Definition: Types.h:170
bool mUsesTexture2DLod
Definition: OutputHLSL.h:91
const TString & getSymbol() const
Definition: intermediate.h:349
#define min(x, y)
Definition: os.h:75
bool mOutputLod0Function
Definition: OutputHLSL.h:147
bool mUsesTexture2DProjLod0_bias
Definition: OutputHLSL.h:101
bool mUsesFragDepth
Definition: OutputHLSL.h:111
TParseContext * context
bool isSingleStatement(TIntermNode *node)
TInfoSinkBase obj
Definition: InfoSink.h:112
TParseContext & mContext
Definition: OutputHLSL.h:73
int i
Definition: pngrutil.c:1377
Constructors mConstructors
Definition: OutputHLSL.h:132
const char * c_str() const
Definition: InfoSink.h:97
#define GL_FLOAT_VEC3
Definition: gl2.h:380
bool mUsesTexture2DLod0_bias
Definition: OutputHLSL.h:99
bool mUsesTextureCube
Definition: OutputHLSL.h:95
TIntermNode * getInit()
Definition: intermediate.h:300
#define max(x, y)
Definition: os.h:79
bool mUsesTextureCube_bias
Definition: OutputHLSL.h:96
int getNominalSize() const
Definition: intermediate.h:257
GLuint sampler
Definition: glew.h:3464
unsigned int mScopeDepth
Definition: OutputHLSL.h:142
virtual TIntermSymbol * getAsSymbolNode()
Definition: intermediate.h:227
static TString decorate(const TString &string)
#define UNIMPLEMENTED()
Definition: debug.h:42
#define GL_HIGH_INT
Definition: gl2.h:424
TString argumentString(const TIntermSymbol *symbol)
TInfoSinkBase mHeader
Definition: OutputHLSL.h:79
TIntermSymbol * mExcessiveLoopIndex
Definition: OutputHLSL.h:150
TString typeString(const TType &type)
static TString decorateUniform(const TString &string, const TType &type)
bool mUsesFragColor
Definition: OutputHLSL.h:104
bool visitBinary(Visit visit, TIntermBinary *)
bool mUsesPointSize
Definition: OutputHLSL.h:110
GLsizei size
Definition: gl2ext.h:1467
GLuint GLenum swizzle
Definition: glew.h:7559
TLoopType getType() const
Definition: intermediate.h:299