Test compiling shaders with given resource limits using GTest.
[platform/upstream/glslang.git] / StandAlone / ResourceLimits.cpp
1 //
2 // Copyright (C) 2016 Google, Inc.
3 //
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions
8 // are met:
9 //
10 //    Redistributions of source code must retain the above copyright
11 //    notice, this list of conditions and the following disclaimer.
12 //
13 //    Redistributions in binary form must reproduce the above
14 //    copyright notice, this list of conditions and the following
15 //    disclaimer in the documentation and/or other materials provided
16 //    with the distribution.
17 //
18 //    Neither the name of Google Inc. nor the names of its
19 //    contributors may be used to endorse or promote products derived
20 //    from this software without specific prior written permission.
21 //
22 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 // POSSIBILITY OF SUCH DAMAGE.
34
35 #include <string.h>
36 #include <sstream>
37
38 #include "ResourceLimits.h"
39
40 namespace glslang {
41
42 const TBuiltInResource DefaultTBuiltInResource = {
43     /* .MaxLights = */ 32,
44     /* .MaxClipPlanes = */ 6,
45     /* .MaxTextureUnits = */ 32,
46     /* .MaxTextureCoords = */ 32,
47     /* .MaxVertexAttribs = */ 64,
48     /* .MaxVertexUniformComponents = */ 4096,
49     /* .MaxVaryingFloats = */ 64,
50     /* .MaxVertexTextureImageUnits = */ 32,
51     /* .MaxCombinedTextureImageUnits = */ 80,
52     /* .MaxTextureImageUnits = */ 32,
53     /* .MaxFragmentUniformComponents = */ 4096,
54     /* .MaxDrawBuffers = */ 32,
55     /* .MaxVertexUniformVectors = */ 128,
56     /* .MaxVaryingVectors = */ 8,
57     /* .MaxFragmentUniformVectors = */ 16,
58     /* .MaxVertexOutputVectors = */ 16,
59     /* .MaxFragmentInputVectors = */ 15,
60     /* .MinProgramTexelOffset = */ -8,
61     /* .MaxProgramTexelOffset = */ 7,
62     /* .MaxClipDistances = */ 8,
63     /* .MaxComputeWorkGroupCountX = */ 65535,
64     /* .MaxComputeWorkGroupCountY = */ 65535,
65     /* .MaxComputeWorkGroupCountZ = */ 65535,
66     /* .MaxComputeWorkGroupSizeX = */ 1024,
67     /* .MaxComputeWorkGroupSizeY = */ 1024,
68     /* .MaxComputeWorkGroupSizeZ = */ 64,
69     /* .MaxComputeUniformComponents = */ 1024,
70     /* .MaxComputeTextureImageUnits = */ 16,
71     /* .MaxComputeImageUniforms = */ 8,
72     /* .MaxComputeAtomicCounters = */ 8,
73     /* .MaxComputeAtomicCounterBuffers = */ 1,
74     /* .MaxVaryingComponents = */ 60,
75     /* .MaxVertexOutputComponents = */ 64,
76     /* .MaxGeometryInputComponents = */ 64,
77     /* .MaxGeometryOutputComponents = */ 128,
78     /* .MaxFragmentInputComponents = */ 128,
79     /* .MaxImageUnits = */ 8,
80     /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8,
81     /* .MaxCombinedShaderOutputResources = */ 8,
82     /* .MaxImageSamples = */ 0,
83     /* .MaxVertexImageUniforms = */ 0,
84     /* .MaxTessControlImageUniforms = */ 0,
85     /* .MaxTessEvaluationImageUniforms = */ 0,
86     /* .MaxGeometryImageUniforms = */ 0,
87     /* .MaxFragmentImageUniforms = */ 8,
88     /* .MaxCombinedImageUniforms = */ 8,
89     /* .MaxGeometryTextureImageUnits = */ 16,
90     /* .MaxGeometryOutputVertices = */ 256,
91     /* .MaxGeometryTotalOutputComponents = */ 1024,
92     /* .MaxGeometryUniformComponents = */ 1024,
93     /* .MaxGeometryVaryingComponents = */ 64,
94     /* .MaxTessControlInputComponents = */ 128,
95     /* .MaxTessControlOutputComponents = */ 128,
96     /* .MaxTessControlTextureImageUnits = */ 16,
97     /* .MaxTessControlUniformComponents = */ 1024,
98     /* .MaxTessControlTotalOutputComponents = */ 4096,
99     /* .MaxTessEvaluationInputComponents = */ 128,
100     /* .MaxTessEvaluationOutputComponents = */ 128,
101     /* .MaxTessEvaluationTextureImageUnits = */ 16,
102     /* .MaxTessEvaluationUniformComponents = */ 1024,
103     /* .MaxTessPatchComponents = */ 120,
104     /* .MaxPatchVertices = */ 32,
105     /* .MaxTessGenLevel = */ 64,
106     /* .MaxViewports = */ 16,
107     /* .MaxVertexAtomicCounters = */ 0,
108     /* .MaxTessControlAtomicCounters = */ 0,
109     /* .MaxTessEvaluationAtomicCounters = */ 0,
110     /* .MaxGeometryAtomicCounters = */ 0,
111     /* .MaxFragmentAtomicCounters = */ 8,
112     /* .MaxCombinedAtomicCounters = */ 8,
113     /* .MaxAtomicCounterBindings = */ 1,
114     /* .MaxVertexAtomicCounterBuffers = */ 0,
115     /* .MaxTessControlAtomicCounterBuffers = */ 0,
116     /* .MaxTessEvaluationAtomicCounterBuffers = */ 0,
117     /* .MaxGeometryAtomicCounterBuffers = */ 0,
118     /* .MaxFragmentAtomicCounterBuffers = */ 1,
119     /* .MaxCombinedAtomicCounterBuffers = */ 1,
120     /* .MaxAtomicCounterBufferSize = */ 16384,
121     /* .MaxTransformFeedbackBuffers = */ 4,
122     /* .MaxTransformFeedbackInterleavedComponents = */ 64,
123     /* .MaxCullDistances = */ 8,
124     /* .MaxCombinedClipAndCullDistances = */ 8,
125     /* .MaxSamples = */ 4,
126     /* .limits = */ {
127         /* .nonInductiveForLoops = */ 1,
128         /* .whileLoops = */ 1,
129         /* .doWhileLoops = */ 1,
130         /* .generalUniformIndexing = */ 1,
131         /* .generalAttributeMatrixVectorIndexing = */ 1,
132         /* .generalVaryingIndexing = */ 1,
133         /* .generalSamplerIndexing = */ 1,
134         /* .generalVariableIndexing = */ 1,
135         /* .generalConstantMatrixVectorIndexing = */ 1,
136     }};
137
138 std::string GetDefaultTBuiltInResourceString()
139 {
140     std::ostringstream ostream;
141
142     ostream << "MaxLights "                                 << DefaultTBuiltInResource.maxLights << "\n"
143             << "MaxClipPlanes "                             << DefaultTBuiltInResource.maxClipPlanes << "\n"
144             << "MaxTextureUnits "                           << DefaultTBuiltInResource.maxTextureUnits << "\n"
145             << "MaxTextureCoords "                          << DefaultTBuiltInResource.maxTextureCoords << "\n"
146             << "MaxVertexAttribs "                          << DefaultTBuiltInResource.maxVertexAttribs << "\n"
147             << "MaxVertexUniformComponents "                << DefaultTBuiltInResource.maxVertexUniformComponents << "\n"
148             << "MaxVaryingFloats "                          << DefaultTBuiltInResource.maxVaryingFloats << "\n"
149             << "MaxVertexTextureImageUnits "                << DefaultTBuiltInResource.maxVertexTextureImageUnits << "\n"
150             << "MaxCombinedTextureImageUnits "              << DefaultTBuiltInResource.maxCombinedTextureImageUnits << "\n"
151             << "MaxTextureImageUnits "                      << DefaultTBuiltInResource.maxTextureImageUnits << "\n"
152             << "MaxFragmentUniformComponents "              << DefaultTBuiltInResource.maxFragmentUniformComponents << "\n"
153             << "MaxDrawBuffers "                            << DefaultTBuiltInResource.maxDrawBuffers << "\n"
154             << "MaxVertexUniformVectors "                   << DefaultTBuiltInResource.maxVertexUniformVectors << "\n"
155             << "MaxVaryingVectors "                         << DefaultTBuiltInResource.maxVaryingVectors << "\n"
156             << "MaxFragmentUniformVectors "                 << DefaultTBuiltInResource.maxFragmentUniformVectors << "\n"
157             << "MaxVertexOutputVectors "                    << DefaultTBuiltInResource.maxVertexOutputVectors << "\n"
158             << "MaxFragmentInputVectors "                   << DefaultTBuiltInResource.maxFragmentInputVectors << "\n"
159             << "MinProgramTexelOffset "                     << DefaultTBuiltInResource.minProgramTexelOffset << "\n"
160             << "MaxProgramTexelOffset "                     << DefaultTBuiltInResource.maxProgramTexelOffset << "\n"
161             << "MaxClipDistances "                          << DefaultTBuiltInResource.maxClipDistances << "\n"
162             << "MaxComputeWorkGroupCountX "                 << DefaultTBuiltInResource.maxComputeWorkGroupCountX << "\n"
163             << "MaxComputeWorkGroupCountY "                 << DefaultTBuiltInResource.maxComputeWorkGroupCountY << "\n"
164             << "MaxComputeWorkGroupCountZ "                 << DefaultTBuiltInResource.maxComputeWorkGroupCountZ << "\n"
165             << "MaxComputeWorkGroupSizeX "                  << DefaultTBuiltInResource.maxComputeWorkGroupSizeX << "\n"
166             << "MaxComputeWorkGroupSizeY "                  << DefaultTBuiltInResource.maxComputeWorkGroupSizeY << "\n"
167             << "MaxComputeWorkGroupSizeZ "                  << DefaultTBuiltInResource.maxComputeWorkGroupSizeZ << "\n"
168             << "MaxComputeUniformComponents "               << DefaultTBuiltInResource.maxComputeUniformComponents << "\n"
169             << "MaxComputeTextureImageUnits "               << DefaultTBuiltInResource.maxComputeTextureImageUnits << "\n"
170             << "MaxComputeImageUniforms "                   << DefaultTBuiltInResource.maxComputeImageUniforms << "\n"
171             << "MaxComputeAtomicCounters "                  << DefaultTBuiltInResource.maxComputeAtomicCounters << "\n"
172             << "MaxComputeAtomicCounterBuffers "            << DefaultTBuiltInResource.maxComputeAtomicCounterBuffers << "\n"
173             << "MaxVaryingComponents "                      << DefaultTBuiltInResource.maxVaryingComponents << "\n"
174             << "MaxVertexOutputComponents "                 << DefaultTBuiltInResource.maxVertexOutputComponents << "\n"
175             << "MaxGeometryInputComponents "                << DefaultTBuiltInResource.maxGeometryInputComponents << "\n"
176             << "MaxGeometryOutputComponents "               << DefaultTBuiltInResource.maxGeometryOutputComponents << "\n"
177             << "MaxFragmentInputComponents "                << DefaultTBuiltInResource.maxFragmentInputComponents << "\n"
178             << "MaxImageUnits "                             << DefaultTBuiltInResource.maxImageUnits << "\n"
179             << "MaxCombinedImageUnitsAndFragmentOutputs "   << DefaultTBuiltInResource.maxCombinedImageUnitsAndFragmentOutputs << "\n"
180             << "MaxCombinedShaderOutputResources "          << DefaultTBuiltInResource.maxCombinedShaderOutputResources << "\n"
181             << "MaxImageSamples "                           << DefaultTBuiltInResource.maxImageSamples << "\n"
182             << "MaxVertexImageUniforms "                    << DefaultTBuiltInResource.maxVertexImageUniforms << "\n"
183             << "MaxTessControlImageUniforms "               << DefaultTBuiltInResource.maxTessControlImageUniforms << "\n"
184             << "MaxTessEvaluationImageUniforms "            << DefaultTBuiltInResource.maxTessEvaluationImageUniforms << "\n"
185             << "MaxGeometryImageUniforms "                  << DefaultTBuiltInResource.maxGeometryImageUniforms << "\n"
186             << "MaxFragmentImageUniforms "                  << DefaultTBuiltInResource.maxFragmentImageUniforms << "\n"
187             << "MaxCombinedImageUniforms "                  << DefaultTBuiltInResource.maxCombinedImageUniforms << "\n"
188             << "MaxGeometryTextureImageUnits "              << DefaultTBuiltInResource.maxGeometryTextureImageUnits << "\n"
189             << "MaxGeometryOutputVertices "                 << DefaultTBuiltInResource.maxGeometryOutputVertices << "\n"
190             << "MaxGeometryTotalOutputComponents "          << DefaultTBuiltInResource.maxGeometryTotalOutputComponents << "\n"
191             << "MaxGeometryUniformComponents "              << DefaultTBuiltInResource.maxGeometryUniformComponents << "\n"
192             << "MaxGeometryVaryingComponents "              << DefaultTBuiltInResource.maxGeometryVaryingComponents << "\n"
193             << "MaxTessControlInputComponents "             << DefaultTBuiltInResource.maxTessControlInputComponents << "\n"
194             << "MaxTessControlOutputComponents "            << DefaultTBuiltInResource.maxTessControlOutputComponents << "\n"
195             << "MaxTessControlTextureImageUnits "           << DefaultTBuiltInResource.maxTessControlTextureImageUnits << "\n"
196             << "MaxTessControlUniformComponents "           << DefaultTBuiltInResource.maxTessControlUniformComponents << "\n"
197             << "MaxTessControlTotalOutputComponents "       << DefaultTBuiltInResource.maxTessControlTotalOutputComponents << "\n"
198             << "MaxTessEvaluationInputComponents "          << DefaultTBuiltInResource.maxTessEvaluationInputComponents << "\n"
199             << "MaxTessEvaluationOutputComponents "         << DefaultTBuiltInResource.maxTessEvaluationOutputComponents << "\n"
200             << "MaxTessEvaluationTextureImageUnits "        << DefaultTBuiltInResource.maxTessEvaluationTextureImageUnits << "\n"
201             << "MaxTessEvaluationUniformComponents "        << DefaultTBuiltInResource.maxTessEvaluationUniformComponents << "\n"
202             << "MaxTessPatchComponents "                    << DefaultTBuiltInResource.maxTessPatchComponents << "\n"
203             << "MaxPatchVertices "                          << DefaultTBuiltInResource.maxPatchVertices << "\n"
204             << "MaxTessGenLevel "                           << DefaultTBuiltInResource.maxTessGenLevel << "\n"
205             << "MaxViewports "                              << DefaultTBuiltInResource.maxViewports << "\n"
206             << "MaxVertexAtomicCounters "                   << DefaultTBuiltInResource.maxVertexAtomicCounters << "\n"
207             << "MaxTessControlAtomicCounters "              << DefaultTBuiltInResource.maxTessControlAtomicCounters << "\n"
208             << "MaxTessEvaluationAtomicCounters "           << DefaultTBuiltInResource.maxTessEvaluationAtomicCounters << "\n"
209             << "MaxGeometryAtomicCounters "                 << DefaultTBuiltInResource.maxGeometryAtomicCounters << "\n"
210             << "MaxFragmentAtomicCounters "                 << DefaultTBuiltInResource.maxFragmentAtomicCounters << "\n"
211             << "MaxCombinedAtomicCounters "                 << DefaultTBuiltInResource.maxCombinedAtomicCounters << "\n"
212             << "MaxAtomicCounterBindings "                  << DefaultTBuiltInResource.maxAtomicCounterBindings << "\n"
213             << "MaxVertexAtomicCounterBuffers "             << DefaultTBuiltInResource.maxVertexAtomicCounterBuffers << "\n"
214             << "MaxTessControlAtomicCounterBuffers "        << DefaultTBuiltInResource.maxTessControlAtomicCounterBuffers << "\n"
215             << "MaxTessEvaluationAtomicCounterBuffers "     << DefaultTBuiltInResource.maxTessEvaluationAtomicCounterBuffers << "\n"
216             << "MaxGeometryAtomicCounterBuffers "           << DefaultTBuiltInResource.maxGeometryAtomicCounterBuffers << "\n"
217             << "MaxFragmentAtomicCounterBuffers "           << DefaultTBuiltInResource.maxFragmentAtomicCounterBuffers << "\n"
218             << "MaxCombinedAtomicCounterBuffers "           << DefaultTBuiltInResource.maxCombinedAtomicCounterBuffers << "\n"
219             << "MaxAtomicCounterBufferSize "                << DefaultTBuiltInResource.maxAtomicCounterBufferSize << "\n"
220             << "MaxTransformFeedbackBuffers "               << DefaultTBuiltInResource.maxTransformFeedbackBuffers << "\n"
221             << "MaxTransformFeedbackInterleavedComponents " << DefaultTBuiltInResource.maxTransformFeedbackInterleavedComponents << "\n"
222             << "MaxCullDistances "                          << DefaultTBuiltInResource.maxCullDistances << "\n"
223             << "MaxCombinedClipAndCullDistances "           << DefaultTBuiltInResource.maxCombinedClipAndCullDistances << "\n"
224             << "MaxSamples "                                << DefaultTBuiltInResource.maxSamples << "\n"
225
226             << "nonInductiveForLoops "                      << DefaultTBuiltInResource.limits.nonInductiveForLoops << "\n"
227             << "whileLoops "                                << DefaultTBuiltInResource.limits.whileLoops << "\n"
228             << "doWhileLoops "                              << DefaultTBuiltInResource.limits.doWhileLoops << "\n"
229             << "generalUniformIndexing "                    << DefaultTBuiltInResource.limits.generalUniformIndexing << "\n"
230             << "generalAttributeMatrixVectorIndexing "      << DefaultTBuiltInResource.limits.generalAttributeMatrixVectorIndexing << "\n"
231             << "generalVaryingIndexing "                    << DefaultTBuiltInResource.limits.generalVaryingIndexing << "\n"
232             << "generalSamplerIndexing "                    << DefaultTBuiltInResource.limits.generalSamplerIndexing << "\n"
233             << "generalVariableIndexing "                   << DefaultTBuiltInResource.limits.generalVariableIndexing << "\n"
234             << "generalConstantMatrixVectorIndexing "       << DefaultTBuiltInResource.limits.generalConstantMatrixVectorIndexing << "\n"
235       ;
236
237     return ostream.str();
238 }
239
240 void DecodeResourceLimits(TBuiltInResource* resources, char* config) {
241     const char* delims = " \t\n\r";
242     const char* token = strtok(config, delims);
243     while (token) {
244         const char* valueStr = strtok(0, delims);
245         if (valueStr == 0 || ! (valueStr[0] == '-' || (valueStr[0] >= '0' && valueStr[0] <= '9'))) {
246             printf("Error: '%s' bad .conf file.  Each name must be followed by one number.\n", valueStr ? valueStr : "");
247             return;
248         }
249         int value = atoi(valueStr);
250
251         if (strcmp(token, "MaxLights") == 0)
252             resources->maxLights = value;
253         else if (strcmp(token, "MaxClipPlanes") == 0)
254             resources->maxClipPlanes = value;
255         else if (strcmp(token, "MaxTextureUnits") == 0)
256             resources->maxTextureUnits = value;
257         else if (strcmp(token, "MaxTextureCoords") == 0)
258             resources->maxTextureCoords = value;
259         else if (strcmp(token, "MaxVertexAttribs") == 0)
260             resources->maxVertexAttribs = value;
261         else if (strcmp(token, "MaxVertexUniformComponents") == 0)
262             resources->maxVertexUniformComponents = value;
263         else if (strcmp(token, "MaxVaryingFloats") == 0)
264             resources->maxVaryingFloats = value;
265         else if (strcmp(token, "MaxVertexTextureImageUnits") == 0)
266             resources->maxVertexTextureImageUnits = value;
267         else if (strcmp(token, "MaxCombinedTextureImageUnits") == 0)
268             resources->maxCombinedTextureImageUnits = value;
269         else if (strcmp(token, "MaxTextureImageUnits") == 0)
270             resources->maxTextureImageUnits = value;
271         else if (strcmp(token, "MaxFragmentUniformComponents") == 0)
272             resources->maxFragmentUniformComponents = value;
273         else if (strcmp(token, "MaxDrawBuffers") == 0)
274             resources->maxDrawBuffers = value;
275         else if (strcmp(token, "MaxVertexUniformVectors") == 0)
276             resources->maxVertexUniformVectors = value;
277         else if (strcmp(token, "MaxVaryingVectors") == 0)
278             resources->maxVaryingVectors = value;
279         else if (strcmp(token, "MaxFragmentUniformVectors") == 0)
280             resources->maxFragmentUniformVectors = value;
281         else if (strcmp(token, "MaxVertexOutputVectors") == 0)
282             resources->maxVertexOutputVectors = value;
283         else if (strcmp(token, "MaxFragmentInputVectors") == 0)
284             resources->maxFragmentInputVectors = value;
285         else if (strcmp(token, "MinProgramTexelOffset") == 0)
286             resources->minProgramTexelOffset = value;
287         else if (strcmp(token, "MaxProgramTexelOffset") == 0)
288             resources->maxProgramTexelOffset = value;
289         else if (strcmp(token, "MaxClipDistances") == 0)
290             resources->maxClipDistances = value;
291         else if (strcmp(token, "MaxComputeWorkGroupCountX") == 0)
292             resources->maxComputeWorkGroupCountX = value;
293         else if (strcmp(token, "MaxComputeWorkGroupCountY") == 0)
294             resources->maxComputeWorkGroupCountY = value;
295         else if (strcmp(token, "MaxComputeWorkGroupCountZ") == 0)
296             resources->maxComputeWorkGroupCountZ = value;
297         else if (strcmp(token, "MaxComputeWorkGroupSizeX") == 0)
298             resources->maxComputeWorkGroupSizeX = value;
299         else if (strcmp(token, "MaxComputeWorkGroupSizeY") == 0)
300             resources->maxComputeWorkGroupSizeY = value;
301         else if (strcmp(token, "MaxComputeWorkGroupSizeZ") == 0)
302             resources->maxComputeWorkGroupSizeZ = value;
303         else if (strcmp(token, "MaxComputeUniformComponents") == 0)
304             resources->maxComputeUniformComponents = value;
305         else if (strcmp(token, "MaxComputeTextureImageUnits") == 0)
306             resources->maxComputeTextureImageUnits = value;
307         else if (strcmp(token, "MaxComputeImageUniforms") == 0)
308             resources->maxComputeImageUniforms = value;
309         else if (strcmp(token, "MaxComputeAtomicCounters") == 0)
310             resources->maxComputeAtomicCounters = value;
311         else if (strcmp(token, "MaxComputeAtomicCounterBuffers") == 0)
312             resources->maxComputeAtomicCounterBuffers = value;
313         else if (strcmp(token, "MaxVaryingComponents") == 0)
314             resources->maxVaryingComponents = value;
315         else if (strcmp(token, "MaxVertexOutputComponents") == 0)
316             resources->maxVertexOutputComponents = value;
317         else if (strcmp(token, "MaxGeometryInputComponents") == 0)
318             resources->maxGeometryInputComponents = value;
319         else if (strcmp(token, "MaxGeometryOutputComponents") == 0)
320             resources->maxGeometryOutputComponents = value;
321         else if (strcmp(token, "MaxFragmentInputComponents") == 0)
322             resources->maxFragmentInputComponents = value;
323         else if (strcmp(token, "MaxImageUnits") == 0)
324             resources->maxImageUnits = value;
325         else if (strcmp(token, "MaxCombinedImageUnitsAndFragmentOutputs") == 0)
326             resources->maxCombinedImageUnitsAndFragmentOutputs = value;
327         else if (strcmp(token, "MaxCombinedShaderOutputResources") == 0)
328             resources->maxCombinedShaderOutputResources = value;
329         else if (strcmp(token, "MaxImageSamples") == 0)
330             resources->maxImageSamples = value;
331         else if (strcmp(token, "MaxVertexImageUniforms") == 0)
332             resources->maxVertexImageUniforms = value;
333         else if (strcmp(token, "MaxTessControlImageUniforms") == 0)
334             resources->maxTessControlImageUniforms = value;
335         else if (strcmp(token, "MaxTessEvaluationImageUniforms") == 0)
336             resources->maxTessEvaluationImageUniforms = value;
337         else if (strcmp(token, "MaxGeometryImageUniforms") == 0)
338             resources->maxGeometryImageUniforms = value;
339         else if (strcmp(token, "MaxFragmentImageUniforms") == 0)
340             resources->maxFragmentImageUniforms = value;
341         else if (strcmp(token, "MaxCombinedImageUniforms") == 0)
342             resources->maxCombinedImageUniforms = value;
343         else if (strcmp(token, "MaxGeometryTextureImageUnits") == 0)
344             resources->maxGeometryTextureImageUnits = value;
345         else if (strcmp(token, "MaxGeometryOutputVertices") == 0)
346             resources->maxGeometryOutputVertices = value;
347         else if (strcmp(token, "MaxGeometryTotalOutputComponents") == 0)
348             resources->maxGeometryTotalOutputComponents = value;
349         else if (strcmp(token, "MaxGeometryUniformComponents") == 0)
350             resources->maxGeometryUniformComponents = value;
351         else if (strcmp(token, "MaxGeometryVaryingComponents") == 0)
352             resources->maxGeometryVaryingComponents = value;
353         else if (strcmp(token, "MaxTessControlInputComponents") == 0)
354             resources->maxTessControlInputComponents = value;
355         else if (strcmp(token, "MaxTessControlOutputComponents") == 0)
356             resources->maxTessControlOutputComponents = value;
357         else if (strcmp(token, "MaxTessControlTextureImageUnits") == 0)
358             resources->maxTessControlTextureImageUnits = value;
359         else if (strcmp(token, "MaxTessControlUniformComponents") == 0)
360             resources->maxTessControlUniformComponents = value;
361         else if (strcmp(token, "MaxTessControlTotalOutputComponents") == 0)
362             resources->maxTessControlTotalOutputComponents = value;
363         else if (strcmp(token, "MaxTessEvaluationInputComponents") == 0)
364             resources->maxTessEvaluationInputComponents = value;
365         else if (strcmp(token, "MaxTessEvaluationOutputComponents") == 0)
366             resources->maxTessEvaluationOutputComponents = value;
367         else if (strcmp(token, "MaxTessEvaluationTextureImageUnits") == 0)
368             resources->maxTessEvaluationTextureImageUnits = value;
369         else if (strcmp(token, "MaxTessEvaluationUniformComponents") == 0)
370             resources->maxTessEvaluationUniformComponents = value;
371         else if (strcmp(token, "MaxTessPatchComponents") == 0)
372             resources->maxTessPatchComponents = value;
373         else if (strcmp(token, "MaxPatchVertices") == 0)
374             resources->maxPatchVertices = value;
375         else if (strcmp(token, "MaxTessGenLevel") == 0)
376             resources->maxTessGenLevel = value;
377         else if (strcmp(token, "MaxViewports") == 0)
378             resources->maxViewports = value;
379         else if (strcmp(token, "MaxVertexAtomicCounters") == 0)
380             resources->maxVertexAtomicCounters = value;
381         else if (strcmp(token, "MaxTessControlAtomicCounters") == 0)
382             resources->maxTessControlAtomicCounters = value;
383         else if (strcmp(token, "MaxTessEvaluationAtomicCounters") == 0)
384             resources->maxTessEvaluationAtomicCounters = value;
385         else if (strcmp(token, "MaxGeometryAtomicCounters") == 0)
386             resources->maxGeometryAtomicCounters = value;
387         else if (strcmp(token, "MaxFragmentAtomicCounters") == 0)
388             resources->maxFragmentAtomicCounters = value;
389         else if (strcmp(token, "MaxCombinedAtomicCounters") == 0)
390             resources->maxCombinedAtomicCounters = value;
391         else if (strcmp(token, "MaxAtomicCounterBindings") == 0)
392             resources->maxAtomicCounterBindings = value;
393         else if (strcmp(token, "MaxVertexAtomicCounterBuffers") == 0)
394             resources->maxVertexAtomicCounterBuffers = value;
395         else if (strcmp(token, "MaxTessControlAtomicCounterBuffers") == 0)
396             resources->maxTessControlAtomicCounterBuffers = value;
397         else if (strcmp(token, "MaxTessEvaluationAtomicCounterBuffers") == 0)
398             resources->maxTessEvaluationAtomicCounterBuffers = value;
399         else if (strcmp(token, "MaxGeometryAtomicCounterBuffers") == 0)
400             resources->maxGeometryAtomicCounterBuffers = value;
401         else if (strcmp(token, "MaxFragmentAtomicCounterBuffers") == 0)
402             resources->maxFragmentAtomicCounterBuffers = value;
403         else if (strcmp(token, "MaxCombinedAtomicCounterBuffers") == 0)
404             resources->maxCombinedAtomicCounterBuffers = value;
405         else if (strcmp(token, "MaxAtomicCounterBufferSize") == 0)
406             resources->maxAtomicCounterBufferSize = value;
407         else if (strcmp(token, "MaxTransformFeedbackBuffers") == 0)
408             resources->maxTransformFeedbackBuffers = value;
409         else if (strcmp(token, "MaxTransformFeedbackInterleavedComponents") == 0)
410             resources->maxTransformFeedbackInterleavedComponents = value;
411         else if (strcmp(token, "MaxCullDistances") == 0)
412             resources->maxCullDistances = value;
413         else if (strcmp(token, "MaxCombinedClipAndCullDistances") == 0)
414             resources->maxCombinedClipAndCullDistances = value;
415         else if (strcmp(token, "MaxSamples") == 0)
416             resources->maxSamples = value;
417
418         else if (strcmp(token, "nonInductiveForLoops") == 0)
419             resources->limits.nonInductiveForLoops = (value != 0);
420         else if (strcmp(token, "whileLoops") == 0)
421             resources->limits.whileLoops = (value != 0);
422         else if (strcmp(token, "doWhileLoops") == 0)
423             resources->limits.doWhileLoops = (value != 0);
424         else if (strcmp(token, "generalUniformIndexing") == 0)
425             resources->limits.generalUniformIndexing = (value != 0);
426         else if (strcmp(token, "generalAttributeMatrixVectorIndexing") == 0)
427             resources->limits.generalAttributeMatrixVectorIndexing = (value != 0);
428         else if (strcmp(token, "generalVaryingIndexing") == 0)
429             resources->limits.generalVaryingIndexing = (value != 0);
430         else if (strcmp(token, "generalSamplerIndexing") == 0)
431             resources->limits.generalSamplerIndexing = (value != 0);
432         else if (strcmp(token, "generalVariableIndexing") == 0)
433             resources->limits.generalVariableIndexing = (value != 0);
434         else if (strcmp(token, "generalConstantMatrixVectorIndexing") == 0)
435             resources->limits.generalConstantMatrixVectorIndexing = (value != 0);
436         else
437             printf("Warning: unrecognized limit (%s) in configuration file.\n", token);
438
439         token = strtok(0, delims);
440     }
441 }
442
443 }  // end namespace glslang