Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/samples/shader_translator/shader_translator.cpp
1694 views
1
//
2
// Copyright 2002 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 "GLSLANG/ShaderLang.h"
8
9
#include <assert.h>
10
#include <math.h>
11
#include <stdio.h>
12
#include <stdlib.h>
13
#include <string.h>
14
#include <sstream>
15
#include <vector>
16
#include "angle_gl.h"
17
18
#if defined(ANGLE_ENABLE_VULKAN)
19
// SPIR-V tools include for disassembly.
20
# include <spirv-tools/libspirv.hpp>
21
#endif
22
23
//
24
// Return codes from main.
25
//
26
enum TFailCode
27
{
28
ESuccess = 0,
29
EFailUsage,
30
EFailCompile,
31
EFailCompilerCreate,
32
};
33
34
static void usage();
35
static sh::GLenum FindShaderType(const char *fileName);
36
static bool CompileFile(char *fileName, ShHandle compiler, ShCompileOptions compileOptions);
37
static void LogMsg(const char *msg, const char *name, const int num, const char *logName);
38
static void PrintVariable(const std::string &prefix, size_t index, const sh::ShaderVariable &var);
39
static void PrintActiveVariables(ShHandle compiler);
40
41
// If NUM_SOURCE_STRINGS is set to a value > 1, the input file data is
42
// broken into that many chunks. This will affect file/line numbering in
43
// the preprocessor.
44
const unsigned int NUM_SOURCE_STRINGS = 1;
45
typedef std::vector<char *> ShaderSource;
46
static bool ReadShaderSource(const char *fileName, ShaderSource &source);
47
static void FreeShaderSource(ShaderSource &source);
48
49
static bool ParseGLSLOutputVersion(const std::string &, ShShaderOutput *outResult);
50
static bool ParseIntValue(const std::string &, int emptyDefault, int *outValue);
51
52
static void PrintSpirv(const sh::BinaryBlob &blob);
53
54
//
55
// Set up the per compile resources
56
//
57
void GenerateResources(ShBuiltInResources *resources)
58
{
59
sh::InitBuiltInResources(resources);
60
61
resources->MaxVertexAttribs = 8;
62
resources->MaxVertexUniformVectors = 128;
63
resources->MaxVaryingVectors = 8;
64
resources->MaxVertexTextureImageUnits = 0;
65
resources->MaxCombinedTextureImageUnits = 8;
66
resources->MaxTextureImageUnits = 8;
67
resources->MaxFragmentUniformVectors = 16;
68
resources->MaxDrawBuffers = 1;
69
resources->MaxDualSourceDrawBuffers = 1;
70
71
resources->OES_standard_derivatives = 0;
72
resources->OES_EGL_image_external = 0;
73
resources->EXT_geometry_shader = 1;
74
resources->ANGLE_texture_multisample = 0;
75
resources->APPLE_clip_distance = 0;
76
}
77
78
int main(int argc, char *argv[])
79
{
80
TFailCode failCode = ESuccess;
81
82
ShCompileOptions compileOptions = 0;
83
int numCompiles = 0;
84
ShHandle vertexCompiler = 0;
85
ShHandle fragmentCompiler = 0;
86
ShHandle computeCompiler = 0;
87
ShHandle geometryCompiler = 0;
88
ShShaderSpec spec = SH_GLES2_SPEC;
89
ShShaderOutput output = SH_ESSL_OUTPUT;
90
91
#if defined(ANGLE_ENABLE_VULKAN)
92
sh::InitializeGlslang();
93
#endif
94
sh::Initialize();
95
96
ShBuiltInResources resources;
97
GenerateResources(&resources);
98
99
argc--;
100
argv++;
101
for (; (argc >= 1) && (failCode == ESuccess); argc--, argv++)
102
{
103
if (argv[0][0] == '-')
104
{
105
switch (argv[0][1])
106
{
107
case 'i':
108
compileOptions |= SH_INTERMEDIATE_TREE;
109
break;
110
case 'o':
111
compileOptions |= SH_OBJECT_CODE;
112
break;
113
case 'u':
114
compileOptions |= SH_VARIABLES;
115
break;
116
case 's':
117
if (argv[0][2] == '=')
118
{
119
switch (argv[0][3])
120
{
121
case 'e':
122
if (argv[0][4] == '3')
123
{
124
if (argv[0][5] == '1')
125
{
126
spec = SH_GLES3_1_SPEC;
127
}
128
else
129
{
130
spec = SH_GLES3_SPEC;
131
}
132
}
133
else
134
{
135
spec = SH_GLES2_SPEC;
136
}
137
break;
138
case 'w':
139
if (argv[0][4] == '3')
140
{
141
spec = SH_WEBGL3_SPEC;
142
}
143
else if (argv[0][4] == '2')
144
{
145
spec = SH_WEBGL2_SPEC;
146
}
147
else if (argv[0][4] == 'n')
148
{
149
spec = SH_WEBGL_SPEC;
150
}
151
else
152
{
153
spec = SH_WEBGL_SPEC;
154
resources.FragmentPrecisionHigh = 1;
155
}
156
break;
157
case 'd':
158
if (argv[0][4] == 'c')
159
{
160
spec = SH_GL_COMPATIBILITY_SPEC;
161
}
162
else
163
{
164
spec = SH_GL_CORE_SPEC;
165
}
166
break;
167
default:
168
failCode = EFailUsage;
169
}
170
}
171
else
172
{
173
failCode = EFailUsage;
174
}
175
break;
176
case 'b':
177
if (argv[0][2] == '=')
178
{
179
switch (argv[0][3])
180
{
181
case 'e':
182
output = SH_ESSL_OUTPUT;
183
compileOptions |= SH_INITIALIZE_UNINITIALIZED_LOCALS;
184
break;
185
case 'g':
186
if (!ParseGLSLOutputVersion(&argv[0][sizeof("-b=g") - 1], &output))
187
{
188
failCode = EFailUsage;
189
}
190
compileOptions |= SH_INITIALIZE_UNINITIALIZED_LOCALS;
191
break;
192
case 'v':
193
output = SH_SPIRV_VULKAN_OUTPUT;
194
compileOptions |= SH_INITIALIZE_UNINITIALIZED_LOCALS;
195
break;
196
case 'h':
197
if (argv[0][4] == '1' && argv[0][5] == '1')
198
{
199
output = SH_HLSL_4_1_OUTPUT;
200
}
201
else
202
{
203
output = SH_HLSL_3_0_OUTPUT;
204
}
205
break;
206
default:
207
failCode = EFailUsage;
208
}
209
}
210
else
211
{
212
failCode = EFailUsage;
213
}
214
break;
215
case 'x':
216
if (argv[0][2] == '=')
217
{
218
// clang-format off
219
switch (argv[0][3])
220
{
221
case 'i': resources.OES_EGL_image_external = 1; break;
222
case 'd': resources.OES_standard_derivatives = 1; break;
223
case 'r': resources.ARB_texture_rectangle = 1; break;
224
case 'b':
225
if (ParseIntValue(&argv[0][sizeof("-x=b") - 1], 1,
226
&resources.MaxDualSourceDrawBuffers))
227
{
228
resources.EXT_blend_func_extended = 1;
229
}
230
else
231
{
232
failCode = EFailUsage;
233
}
234
break;
235
case 'w':
236
if (ParseIntValue(&argv[0][sizeof("-x=w") - 1], 1,
237
&resources.MaxDrawBuffers))
238
{
239
resources.EXT_draw_buffers = 1;
240
}
241
else
242
{
243
failCode = EFailUsage;
244
}
245
break;
246
case 'g': resources.EXT_frag_depth = 1; break;
247
case 'l': resources.EXT_shader_texture_lod = 1; break;
248
case 'f': resources.EXT_shader_framebuffer_fetch = 1; break;
249
case 'n': resources.NV_shader_framebuffer_fetch = 1; break;
250
case 'a': resources.ARM_shader_framebuffer_fetch = 1; break;
251
case 'm':
252
resources.OVR_multiview2 = 1;
253
resources.OVR_multiview = 1;
254
compileOptions |= SH_INITIALIZE_BUILTINS_FOR_INSTANCED_MULTIVIEW;
255
compileOptions |= SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER;
256
break;
257
case 'y': resources.EXT_YUV_target = 1; break;
258
case 's': resources.OES_sample_variables = 1; break;
259
default: failCode = EFailUsage;
260
}
261
// clang-format on
262
}
263
else
264
{
265
failCode = EFailUsage;
266
}
267
break;
268
default:
269
failCode = EFailUsage;
270
}
271
}
272
else
273
{
274
if (spec != SH_GLES2_SPEC && spec != SH_WEBGL_SPEC)
275
{
276
resources.MaxDrawBuffers = 8;
277
resources.MaxVertexTextureImageUnits = 16;
278
resources.MaxTextureImageUnits = 16;
279
}
280
ShHandle compiler = 0;
281
switch (FindShaderType(argv[0]))
282
{
283
case GL_VERTEX_SHADER:
284
if (vertexCompiler == 0)
285
{
286
vertexCompiler =
287
sh::ConstructCompiler(GL_VERTEX_SHADER, spec, output, &resources);
288
}
289
compiler = vertexCompiler;
290
break;
291
case GL_FRAGMENT_SHADER:
292
if (fragmentCompiler == 0)
293
{
294
fragmentCompiler =
295
sh::ConstructCompiler(GL_FRAGMENT_SHADER, spec, output, &resources);
296
}
297
compiler = fragmentCompiler;
298
break;
299
case GL_COMPUTE_SHADER:
300
if (computeCompiler == 0)
301
{
302
computeCompiler =
303
sh::ConstructCompiler(GL_COMPUTE_SHADER, spec, output, &resources);
304
}
305
compiler = computeCompiler;
306
break;
307
case GL_GEOMETRY_SHADER_EXT:
308
if (geometryCompiler == 0)
309
{
310
geometryCompiler =
311
sh::ConstructCompiler(GL_GEOMETRY_SHADER_EXT, spec, output, &resources);
312
}
313
compiler = geometryCompiler;
314
break;
315
default:
316
break;
317
}
318
if (compiler)
319
{
320
switch (output)
321
{
322
case SH_HLSL_3_0_OUTPUT:
323
case SH_HLSL_4_1_OUTPUT:
324
case SH_HLSL_4_0_FL9_3_OUTPUT:
325
compileOptions &= ~SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER;
326
break;
327
default:
328
break;
329
}
330
331
bool compiled = CompileFile(argv[0], compiler, compileOptions);
332
333
LogMsg("BEGIN", "COMPILER", numCompiles, "INFO LOG");
334
std::string log = sh::GetInfoLog(compiler);
335
puts(log.c_str());
336
LogMsg("END", "COMPILER", numCompiles, "INFO LOG");
337
printf("\n\n");
338
339
if (compiled && (compileOptions & SH_OBJECT_CODE))
340
{
341
LogMsg("BEGIN", "COMPILER", numCompiles, "OBJ CODE");
342
if (output != SH_SPIRV_VULKAN_OUTPUT)
343
{
344
const std::string &code = sh::GetObjectCode(compiler);
345
puts(code.c_str());
346
}
347
else
348
{
349
const sh::BinaryBlob &blob = sh::GetObjectBinaryBlob(compiler);
350
PrintSpirv(blob);
351
}
352
LogMsg("END", "COMPILER", numCompiles, "OBJ CODE");
353
printf("\n\n");
354
}
355
if (compiled && (compileOptions & SH_VARIABLES))
356
{
357
LogMsg("BEGIN", "COMPILER", numCompiles, "VARIABLES");
358
PrintActiveVariables(compiler);
359
LogMsg("END", "COMPILER", numCompiles, "VARIABLES");
360
printf("\n\n");
361
}
362
if (!compiled)
363
failCode = EFailCompile;
364
++numCompiles;
365
}
366
else
367
{
368
failCode = EFailCompilerCreate;
369
}
370
}
371
}
372
373
if ((vertexCompiler == 0) && (fragmentCompiler == 0) && (computeCompiler == 0) &&
374
(geometryCompiler == 0))
375
failCode = EFailUsage;
376
if (failCode == EFailUsage)
377
usage();
378
379
if (vertexCompiler)
380
sh::Destruct(vertexCompiler);
381
if (fragmentCompiler)
382
sh::Destruct(fragmentCompiler);
383
if (computeCompiler)
384
sh::Destruct(computeCompiler);
385
if (geometryCompiler)
386
sh::Destruct(geometryCompiler);
387
388
sh::Finalize();
389
#if defined(ANGLE_ENABLE_VULKAN)
390
sh::FinalizeGlslang();
391
#endif
392
393
return failCode;
394
}
395
396
//
397
// print usage to stdout
398
//
399
void usage()
400
{
401
// clang-format off
402
printf(
403
"Usage: translate [-i -o -u -l -b=e -b=g -b=h9 -x=i -x=d] file1 file2 ...\n"
404
"Where: filename : filename ending in .frag or .vert\n"
405
" -i : print intermediate tree\n"
406
" -o : print translated code\n"
407
" -u : print active attribs, uniforms, varyings and program outputs\n"
408
" -s=e2 : use GLES2 spec (this is by default)\n"
409
" -s=e3 : use GLES3 spec\n"
410
" -s=e31 : use GLES31 spec (in development)\n"
411
" -s=w : use WebGL 1.0 spec\n"
412
" -s=wn : use WebGL 1.0 spec with no highp support in fragment shaders\n"
413
" -s=w2 : use WebGL 2.0 spec\n"
414
" -s=d : use Desktop Core spec (in development)\n"
415
" -s=dc : use Desktop Compatibility spec (in development)\n"
416
" -b=e : output GLSL ES code (this is by default)\n"
417
" -b=g : output GLSL code (compatibility profile)\n"
418
" -b=g[NUM]: output GLSL code (NUM can be 130, 140, 150, 330, 400, 410, 420, 430, "
419
"440, 450)\n"
420
" -b=v : output Vulkan SPIR-V code\n"
421
" -b=h9 : output HLSL9 code\n"
422
" -b=h11 : output HLSL11 code\n"
423
" -x=i : enable GL_OES_EGL_image_external\n"
424
" -x=d : enable GL_OES_EGL_standard_derivatives\n"
425
" -x=r : enable ARB_texture_rectangle\n"
426
" -x=b[NUM]: enable EXT_blend_func_extended (NUM default 1)\n"
427
" -x=w[NUM]: enable EXT_draw_buffers (NUM default 1)\n"
428
" -x=g : enable EXT_frag_depth\n"
429
" -x=l : enable EXT_shader_texture_lod\n"
430
" -x=f : enable EXT_shader_framebuffer_fetch\n"
431
" -x=n : enable NV_shader_framebuffer_fetch\n"
432
" -x=a : enable ARM_shader_framebuffer_fetch\n"
433
" -x=m : enable OVR_multiview\n"
434
" -x=y : enable YUV_target\n"
435
" -x=s : enable OES_sample_variables\n");
436
// clang-format on
437
}
438
439
//
440
// Deduce the shader type from the filename. Files must end in one of the
441
// following extensions:
442
//
443
// .frag* = fragment shader
444
// .vert* = vertex shader
445
//
446
sh::GLenum FindShaderType(const char *fileName)
447
{
448
assert(fileName);
449
450
const char *ext = strrchr(fileName, '.');
451
452
if (ext && strcmp(ext, ".sl") == 0)
453
for (; ext > fileName && ext[0] != '.'; ext--)
454
;
455
456
ext = strrchr(fileName, '.');
457
if (ext)
458
{
459
if (strncmp(ext, ".frag", 5) == 0)
460
return GL_FRAGMENT_SHADER;
461
if (strncmp(ext, ".vert", 5) == 0)
462
return GL_VERTEX_SHADER;
463
if (strncmp(ext, ".comp", 5) == 0)
464
return GL_COMPUTE_SHADER;
465
if (strncmp(ext, ".geom", 5) == 0)
466
return GL_GEOMETRY_SHADER_EXT;
467
}
468
469
return GL_FRAGMENT_SHADER;
470
}
471
472
//
473
// Read a file's data into a string, and compile it using sh::Compile
474
//
475
bool CompileFile(char *fileName, ShHandle compiler, ShCompileOptions compileOptions)
476
{
477
ShaderSource source;
478
if (!ReadShaderSource(fileName, source))
479
return false;
480
481
int ret = sh::Compile(compiler, &source[0], source.size(), compileOptions);
482
483
FreeShaderSource(source);
484
return ret ? true : false;
485
}
486
487
void LogMsg(const char *msg, const char *name, const int num, const char *logName)
488
{
489
printf("#### %s %s %d %s ####\n", msg, name, num, logName);
490
}
491
492
void PrintVariable(const std::string &prefix, size_t index, const sh::ShaderVariable &var)
493
{
494
std::string typeName;
495
switch (var.type)
496
{
497
case GL_FLOAT:
498
typeName = "GL_FLOAT";
499
break;
500
case GL_FLOAT_VEC2:
501
typeName = "GL_FLOAT_VEC2";
502
break;
503
case GL_FLOAT_VEC3:
504
typeName = "GL_FLOAT_VEC3";
505
break;
506
case GL_FLOAT_VEC4:
507
typeName = "GL_FLOAT_VEC4";
508
break;
509
case GL_INT:
510
typeName = "GL_INT";
511
break;
512
case GL_INT_VEC2:
513
typeName = "GL_INT_VEC2";
514
break;
515
case GL_INT_VEC3:
516
typeName = "GL_INT_VEC3";
517
break;
518
case GL_INT_VEC4:
519
typeName = "GL_INT_VEC4";
520
break;
521
case GL_UNSIGNED_INT:
522
typeName = "GL_UNSIGNED_INT";
523
break;
524
case GL_UNSIGNED_INT_VEC2:
525
typeName = "GL_UNSIGNED_INT_VEC2";
526
break;
527
case GL_UNSIGNED_INT_VEC3:
528
typeName = "GL_UNSIGNED_INT_VEC3";
529
break;
530
case GL_UNSIGNED_INT_VEC4:
531
typeName = "GL_UNSIGNED_INT_VEC4";
532
break;
533
case GL_BOOL:
534
typeName = "GL_BOOL";
535
break;
536
case GL_BOOL_VEC2:
537
typeName = "GL_BOOL_VEC2";
538
break;
539
case GL_BOOL_VEC3:
540
typeName = "GL_BOOL_VEC3";
541
break;
542
case GL_BOOL_VEC4:
543
typeName = "GL_BOOL_VEC4";
544
break;
545
case GL_FLOAT_MAT2:
546
typeName = "GL_FLOAT_MAT2";
547
break;
548
case GL_FLOAT_MAT3:
549
typeName = "GL_FLOAT_MAT3";
550
break;
551
case GL_FLOAT_MAT4:
552
typeName = "GL_FLOAT_MAT4";
553
break;
554
case GL_FLOAT_MAT2x3:
555
typeName = "GL_FLOAT_MAT2x3";
556
break;
557
case GL_FLOAT_MAT3x2:
558
typeName = "GL_FLOAT_MAT3x2";
559
break;
560
case GL_FLOAT_MAT4x2:
561
typeName = "GL_FLOAT_MAT4x2";
562
break;
563
case GL_FLOAT_MAT2x4:
564
typeName = "GL_FLOAT_MAT2x4";
565
break;
566
case GL_FLOAT_MAT3x4:
567
typeName = "GL_FLOAT_MAT3x4";
568
break;
569
case GL_FLOAT_MAT4x3:
570
typeName = "GL_FLOAT_MAT4x3";
571
break;
572
573
case GL_SAMPLER_2D:
574
typeName = "GL_SAMPLER_2D";
575
break;
576
case GL_SAMPLER_3D:
577
typeName = "GL_SAMPLER_3D";
578
break;
579
case GL_SAMPLER_CUBE:
580
typeName = "GL_SAMPLER_CUBE";
581
break;
582
case GL_SAMPLER_CUBE_SHADOW:
583
typeName = "GL_SAMPLER_CUBE_SHADOW";
584
break;
585
case GL_SAMPLER_2D_SHADOW:
586
typeName = "GL_SAMPLER_2D_ARRAY_SHADOW";
587
break;
588
case GL_SAMPLER_2D_ARRAY:
589
typeName = "GL_SAMPLER_2D_ARRAY";
590
break;
591
case GL_SAMPLER_2D_ARRAY_SHADOW:
592
typeName = "GL_SAMPLER_2D_ARRAY_SHADOW";
593
break;
594
case GL_SAMPLER_2D_MULTISAMPLE:
595
typeName = "GL_SAMPLER_2D_MULTISAMPLE";
596
break;
597
case GL_IMAGE_2D:
598
typeName = "GL_IMAGE_2D";
599
break;
600
case GL_IMAGE_3D:
601
typeName = "GL_IMAGE_3D";
602
break;
603
case GL_IMAGE_CUBE:
604
typeName = "GL_IMAGE_CUBE";
605
break;
606
case GL_IMAGE_2D_ARRAY:
607
typeName = "GL_IMAGE_2D_ARRAY";
608
break;
609
610
case GL_INT_SAMPLER_2D:
611
typeName = "GL_INT_SAMPLER_2D";
612
break;
613
case GL_INT_SAMPLER_3D:
614
typeName = "GL_INT_SAMPLER_3D";
615
break;
616
case GL_INT_SAMPLER_CUBE:
617
typeName = "GL_INT_SAMPLER_CUBE";
618
break;
619
case GL_INT_SAMPLER_2D_ARRAY:
620
typeName = "GL_INT_SAMPLER_2D_ARRAY";
621
break;
622
case GL_INT_SAMPLER_2D_MULTISAMPLE:
623
typeName = "GL_INT_SAMPLER_2D_MULTISAMPLE";
624
break;
625
case GL_INT_IMAGE_2D:
626
typeName = "GL_INT_IMAGE_2D";
627
break;
628
case GL_INT_IMAGE_3D:
629
typeName = "GL_INT_IMAGE_3D";
630
break;
631
case GL_INT_IMAGE_CUBE:
632
typeName = "GL_INT_IMAGE_CUBE";
633
break;
634
case GL_INT_IMAGE_2D_ARRAY:
635
typeName = "GL_INT_IMAGE_2D_ARRAY";
636
break;
637
638
case GL_UNSIGNED_INT_SAMPLER_2D:
639
typeName = "GL_UNSIGNED_INT_SAMPLER_2D";
640
break;
641
case GL_UNSIGNED_INT_SAMPLER_3D:
642
typeName = "GL_UNSIGNED_INT_SAMPLER_3D";
643
break;
644
case GL_UNSIGNED_INT_SAMPLER_CUBE:
645
typeName = "GL_UNSIGNED_INT_SAMPLER_CUBE";
646
break;
647
case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
648
typeName = "GL_UNSIGNED_INT_SAMPLER_2D_ARRAY";
649
break;
650
case GL_UNSIGNED_INT_ATOMIC_COUNTER:
651
typeName = "GL_UNSIGNED_INT_ATOMIC_COUNTER";
652
break;
653
case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
654
typeName = "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE";
655
break;
656
case GL_UNSIGNED_INT_IMAGE_2D:
657
typeName = "GL_UNSIGNED_INT_IMAGE_2D";
658
break;
659
case GL_UNSIGNED_INT_IMAGE_3D:
660
typeName = "GL_UNSIGNED_INT_IMAGE_3D";
661
break;
662
case GL_UNSIGNED_INT_IMAGE_CUBE:
663
typeName = "GL_UNSIGNED_INT_IMAGE_CUBE";
664
break;
665
case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
666
typeName = "GL_UNSIGNED_INT_IMAGE_2D_ARRAY";
667
break;
668
669
case GL_SAMPLER_EXTERNAL_OES:
670
typeName = "GL_SAMPLER_EXTERNAL_OES";
671
break;
672
case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
673
typeName = "GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT";
674
break;
675
default:
676
typeName = "UNKNOWN";
677
break;
678
}
679
680
printf("%s %u : name=%s, mappedName=%s, type=%s, arraySizes=", prefix.c_str(),
681
static_cast<unsigned int>(index), var.name.c_str(), var.mappedName.c_str(),
682
typeName.c_str());
683
for (unsigned int arraySize : var.arraySizes)
684
{
685
printf("%u ", arraySize);
686
}
687
printf("\n");
688
if (var.fields.size())
689
{
690
std::string structPrefix;
691
for (size_t i = 0; i < prefix.size(); ++i)
692
structPrefix += ' ';
693
printf("%s struct %s\n", structPrefix.c_str(), var.structOrBlockName.c_str());
694
structPrefix += " field";
695
for (size_t i = 0; i < var.fields.size(); ++i)
696
PrintVariable(structPrefix, i, var.fields[i]);
697
}
698
}
699
700
static void PrintActiveVariables(ShHandle compiler)
701
{
702
const std::vector<sh::ShaderVariable> *uniforms = sh::GetUniforms(compiler);
703
const std::vector<sh::ShaderVariable> *inputVaryings = sh::GetInputVaryings(compiler);
704
const std::vector<sh::ShaderVariable> *outputVaryings = sh::GetOutputVaryings(compiler);
705
const std::vector<sh::ShaderVariable> *attributes = sh::GetAttributes(compiler);
706
const std::vector<sh::ShaderVariable> *outputs = sh::GetOutputVariables(compiler);
707
for (size_t varCategory = 0; varCategory < 5; ++varCategory)
708
{
709
size_t numVars = 0;
710
std::string varCategoryName;
711
if (varCategory == 0)
712
{
713
numVars = uniforms->size();
714
varCategoryName = "uniform";
715
}
716
else if (varCategory == 1)
717
{
718
numVars = inputVaryings->size();
719
varCategoryName = "input varying";
720
}
721
else if (varCategory == 2)
722
{
723
numVars = outputVaryings->size();
724
varCategoryName = "output varying";
725
}
726
else if (varCategory == 3)
727
{
728
numVars = attributes->size();
729
varCategoryName = "attribute";
730
}
731
else
732
{
733
numVars = outputs->size();
734
varCategoryName = "output";
735
}
736
737
for (size_t i = 0; i < numVars; ++i)
738
{
739
const sh::ShaderVariable *var;
740
if (varCategory == 0)
741
var = &((*uniforms)[i]);
742
else if (varCategory == 1)
743
var = &((*inputVaryings)[i]);
744
else if (varCategory == 2)
745
var = &((*outputVaryings)[i]);
746
else if (varCategory == 3)
747
var = &((*attributes)[i]);
748
else
749
var = &((*outputs)[i]);
750
751
PrintVariable(varCategoryName, i, *var);
752
}
753
printf("\n");
754
}
755
}
756
757
static bool ReadShaderSource(const char *fileName, ShaderSource &source)
758
{
759
FILE *in = fopen(fileName, "rb");
760
if (!in)
761
{
762
printf("Error: unable to open input file: %s\n", fileName);
763
return false;
764
}
765
766
// Obtain file size.
767
fseek(in, 0, SEEK_END);
768
size_t count = ftell(in);
769
rewind(in);
770
771
int len = (int)ceil((float)count / (float)NUM_SOURCE_STRINGS);
772
source.reserve(NUM_SOURCE_STRINGS);
773
// Notice the usage of do-while instead of a while loop here.
774
// It is there to handle empty files in which case a single empty
775
// string is added to vector.
776
do
777
{
778
char *data = new char[len + 1];
779
size_t nread = fread(data, 1, len, in);
780
data[nread] = '\0';
781
source.push_back(data);
782
783
count -= nread;
784
} while (count > 0);
785
786
fclose(in);
787
return true;
788
}
789
790
static void FreeShaderSource(ShaderSource &source)
791
{
792
for (ShaderSource::size_type i = 0; i < source.size(); ++i)
793
{
794
delete[] source[i];
795
}
796
source.clear();
797
}
798
799
static bool ParseGLSLOutputVersion(const std::string &num, ShShaderOutput *outResult)
800
{
801
if (num.length() == 0)
802
{
803
*outResult = SH_GLSL_COMPATIBILITY_OUTPUT;
804
return true;
805
}
806
std::istringstream input(num);
807
int value;
808
if (!(input >> value && input.eof()))
809
{
810
return false;
811
}
812
813
switch (value)
814
{
815
case 130:
816
*outResult = SH_GLSL_130_OUTPUT;
817
return true;
818
case 140:
819
*outResult = SH_GLSL_140_OUTPUT;
820
return true;
821
case 150:
822
*outResult = SH_GLSL_150_CORE_OUTPUT;
823
return true;
824
case 330:
825
*outResult = SH_GLSL_330_CORE_OUTPUT;
826
return true;
827
case 400:
828
*outResult = SH_GLSL_400_CORE_OUTPUT;
829
return true;
830
case 410:
831
*outResult = SH_GLSL_410_CORE_OUTPUT;
832
return true;
833
case 420:
834
*outResult = SH_GLSL_420_CORE_OUTPUT;
835
return true;
836
case 430:
837
*outResult = SH_GLSL_430_CORE_OUTPUT;
838
return true;
839
case 440:
840
*outResult = SH_GLSL_440_CORE_OUTPUT;
841
return true;
842
case 450:
843
*outResult = SH_GLSL_450_CORE_OUTPUT;
844
return true;
845
default:
846
break;
847
}
848
return false;
849
}
850
851
static bool ParseIntValue(const std::string &num, int emptyDefault, int *outValue)
852
{
853
if (num.length() == 0)
854
{
855
*outValue = emptyDefault;
856
return true;
857
}
858
859
std::istringstream input(num);
860
int value;
861
if (!(input >> value && input.eof()))
862
{
863
return false;
864
}
865
*outValue = value;
866
return true;
867
}
868
869
static void PrintSpirv(const sh::BinaryBlob &blob)
870
{
871
#if defined(ANGLE_ENABLE_VULKAN)
872
spvtools::SpirvTools spirvTools(SPV_ENV_VULKAN_1_1);
873
874
std::string readableSpirv;
875
spirvTools.Disassemble(blob, &readableSpirv, 0);
876
877
puts(readableSpirv.c_str());
878
#endif
879
}
880
881