blob: 9200d6be6288c1361b6ab8d15715ebec333f53dc [file] [log] [blame]
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -06001// XGL tests
2//
3// Copyright (C) 2014 LunarG, Inc.
4//
5// Permission is hereby granted, free of charge, to any person obtaining a
6// copy of this software and associated documentation files (the "Software"),
7// to deal in the Software without restriction, including without limitation
8// the rights to use, copy, modify, merge, publish, distribute, sublicense,
9// and/or sell copies of the Software, and to permit persons to whom the
10// Software is furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included
13// in all copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21// DEALINGS IN THE SOFTWARE.
22
23#include "xgltestframework.h"
24#include "GL/freeglut_std.h"
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -060025//#include "ShaderLang.h"
26#include "GlslangToBil.h"
27#include <math.h>
28
29// Command-line options
30enum TOptions {
31 EOptionNone = 0x000,
32 EOptionIntermediate = 0x001,
33 EOptionSuppressInfolog = 0x002,
34 EOptionMemoryLeakMode = 0x004,
35 EOptionRelaxedErrors = 0x008,
36 EOptionGiveWarnings = 0x010,
37 EOptionLinkProgram = 0x020,
38 EOptionMultiThreaded = 0x040,
39 EOptionDumpConfig = 0x080,
40 EOptionDumpReflection = 0x100,
41 EOptionSuppressWarnings = 0x200,
42 EOptionDumpVersions = 0x400,
43 EOptionBil = 0x800,
44 EOptionDefaultDesktop = 0x1000,
45};
46
47#ifndef _WIN32
48
49#include <errno.h>
50
51int fopen_s(
52 FILE** pFile,
53 const char* filename,
54 const char* mode
55)
56{
57 if (!pFile || !filename || !mode) {
58 return EINVAL;
59 }
60
61 FILE* f = fopen(filename, mode);
62 if (! f) {
63 if (errno != 0) {
64 return errno;
65 } else {
66 return ENOENT;
67 }
68 }
69 *pFile = f;
70
71 return 0;
72}
73
74#endif
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -060075
Courtney Goeltzenleuchterf12c7762014-10-08 08:46:51 -060076// Set up environment for GLSL compiler
77// Must be done once per process
78void TestEnvironment::SetUp()
79{
80 // Initialize GLSL to BIL compiler utility
81 glslang::InitializeProcess();
82}
83
84void TestEnvironment::TearDown()
85{
86 glslang::FinalizeProcess();
87}
88
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -060089XglTestFramework::XglTestFramework() :
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -060090 m_glut_initialized( false ),
91 m_compile_options( 0 ),
92 m_num_shader_strings( 0 )
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -060093{
Courtney Goeltzenleuchterf12c7762014-10-08 08:46:51 -060094
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -060095}
96
97XglTestFramework::~XglTestFramework()
98{
Courtney Goeltzenleuchterf12c7762014-10-08 08:46:51 -060099
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600100}
101
102// Define all the static elements
103bool XglTestFramework::m_show_images = false;
104bool XglTestFramework::m_save_images = false;
105int XglTestFramework::m_width = 0;
106int XglTestFramework::m_height = 0;
107int XglTestFramework::m_window = 0;
108std::list<XglTestImageRecord> XglTestFramework::m_images;
109std::list<XglTestImageRecord>::iterator XglTestFramework::m_display_image;
110int m_display_image_idx = 0;
111
112void XglTestFramework::InitArgs(int *argc, char *argv[])
113{
114 int i, n;
115
116 for (i=0, n=0; i< *argc; i++) {
117 if (strncmp("--show-images", argv[i], 13) == 0) {
118 m_show_images = true;
119 continue;
120 }
121 if (strncmp("--save-images", argv[i], 13) == 0) {
122 m_save_images = true;
123 continue;
124 }
125
126 /*
127 * Since the above "consume" inputs, update argv
128 * so that it contains the trimmed list of args for glutInit
129 */
130 argv[n] = argv[i];
131 n++;
132 }
133
134 if (m_show_images) {
135 glutInit(argc, argv);
136 }
137}
138
139void XglTestFramework::Reshape( int w, int h )
140{
141 if (!m_show_images) return; // Do nothing except save info if not enabled
142
143 // Resize window to be large enough to handle biggest image we've seen
144 // TODO: Probably need some sort of limits for the Window system.
145 if (w > m_width) {
146 m_width = w;
147 }
148 if (h > m_height) {
149 m_height = h;
150 }
151
152 glutReshapeWindow(m_width, m_height);
153
154 glViewport( 0, 0, m_width, m_height );
155 glMatrixMode( GL_PROJECTION );
156 glLoadIdentity();
157 glOrtho( 0.0, m_width, 0.0, m_height, 0.0, 2.0 );
158 glMatrixMode( GL_MODELVIEW );
159 glLoadIdentity();
160
161// glScissor(width/4, height/4, width/2, height/2);
162}
163
164void XglTestFramework::WritePPM( const char *basename, XglImage *image )
165{
166 string filename;
167 XGL_RESULT err;
168 int x, y;
169
170 filename.append(basename);
171 filename.append(".ppm");
172
173 const XGL_IMAGE_SUBRESOURCE sr = {
174 XGL_IMAGE_ASPECT_COLOR, 0, 0
175 };
176 XGL_SUBRESOURCE_LAYOUT sr_layout;
Jon Ashburnb8e43892014-09-25 14:36:58 -0600177 XGL_UINT data_size = sizeof(sr_layout);
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600178
179 err = xglGetImageSubresourceInfo( image->image(), &sr,
180 XGL_INFO_TYPE_SUBRESOURCE_LAYOUT,
181 &data_size, &sr_layout);
182 ASSERT_XGL_SUCCESS( err );
183 ASSERT_EQ(data_size, sizeof(sr_layout));
184
185 const char *ptr;
186
187 err = xglMapMemory( image->memory(), 0, (XGL_VOID **) &ptr );
188 ASSERT_XGL_SUCCESS( err );
189
190 ptr += sr_layout.offset;
191
192 ofstream file (filename.c_str());
193 ASSERT_TRUE(file.is_open()) << "Unable to open file: " << filename;
194
195 file << "P6\n";
196 file << image->width() << "\n";
197 file << image->height() << "\n";
198 file << 255 << "\n";
199
200 for (y = 0; y < image->height(); y++) {
201 const char *row = ptr;
202
203 for (x = 0; x < image->width(); x++) {
204 file.write(row, 3);
205 row += 4;
206 }
207
208 ptr += sr_layout.rowPitch;
209 }
210
211 file.close();
212
213 err = xglUnmapMemory( image->memory() );
214 ASSERT_XGL_SUCCESS( err );
215}
216
217void XglTestFramework::InitGLUT(int w, int h)
218{
219
220 if (!m_show_images) return;
221
222 if (!m_glut_initialized) {
223 glutInitWindowSize(w, h);
224
225 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
226 m_window = glutCreateWindow(NULL);
227 m_glut_initialized = true;
228 }
229
230 Reshape(w, h);
231}
232
233void XglTestFramework::Show(const char *comment, XglImage *image)
234{
235 XGL_RESULT err;
236
237 const XGL_IMAGE_SUBRESOURCE sr = {
238 XGL_IMAGE_ASPECT_COLOR, 0, 0
239 };
240 XGL_SUBRESOURCE_LAYOUT sr_layout;
Jon Ashburnb8e43892014-09-25 14:36:58 -0600241 XGL_UINT data_size = sizeof(sr_layout);
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600242
243 if (!m_show_images) return;
244
245 InitGLUT(image->width(), image->height());
246
247 err = xglGetImageSubresourceInfo( image->image(), &sr, XGL_INFO_TYPE_SUBRESOURCE_LAYOUT,
248 &data_size, &sr_layout);
249 ASSERT_XGL_SUCCESS( err );
250 ASSERT_EQ(data_size, sizeof(sr_layout));
251
252 const char *ptr;
253
254 err = image->MapMemory( (XGL_VOID **) &ptr );
255 ASSERT_XGL_SUCCESS( err );
256
257 ptr += sr_layout.offset;
258
259 XglTestImageRecord record;
260 record.m_title.append(comment);
261 record.m_width = image->width();
262 record.m_height = image->height();
263 // TODO: Need to make this more robust to handle different image formats
264 record.m_data_size = image->width()*image->height()*4;
265 record.m_data = malloc(record.m_data_size);
266 memcpy(record.m_data, ptr, record.m_data_size);
267 m_images.push_back(record);
268 m_display_image = --m_images.end();
269
270 Display();
271
272 err = image->UnmapMemory();
273 ASSERT_XGL_SUCCESS( err );
274}
275
276void XglTestFramework::RecordImage(XglImage *image)
277{
278 const ::testing::TestInfo* const test_info =
279 ::testing::UnitTest::GetInstance()->current_test_info();
280
281 if (m_save_images) {
282 WritePPM(test_info->test_case_name(), image);
283 }
284
285 if (m_show_images) {
286 Show(test_info->test_case_name(), image);
287 }
288}
289
290void XglTestFramework::Display()
291{
292 glutSetWindowTitle(m_display_image->m_title.c_str());
293
294 glClearColor(0, 0, 0, 0);
295 glClear(GL_COLOR_BUFFER_BIT);
296 glRasterPos3f(0, 0, 0);
297 glBitmap(0, 0, 0, 0, 0, 0, NULL);
298 glDrawPixels(m_display_image->m_width, m_display_image->m_height,
299 GL_RGBA, GL_UNSIGNED_BYTE, m_display_image->m_data);
300
301 glutSwapBuffers();
302}
303
304void XglTestFramework::Key( unsigned char key, int x, int y )
305{
306 (void) x;
307 (void) y;
308 switch (key) {
309 case 27:
310 glutDestroyWindow(m_window);
311 exit(0);
312 break;
313 }
314 glutPostRedisplay();
315}
316
317void XglTestFramework::SpecialKey( int key, int x, int y )
318{
319 (void) x;
320 (void) y;
321 switch (key) {
322 case GLUT_KEY_UP:
323 case GLUT_KEY_RIGHT:
324 ++m_display_image;
325 if (m_display_image == m_images.end()) {
326 m_display_image = m_images.begin();
327 }
328 break;
329 case GLUT_KEY_DOWN:
330 case GLUT_KEY_LEFT:
331 if (m_display_image == m_images.begin()) {
332 m_display_image = --m_images.end();
333 } else {
334 --m_display_image;
335 }
336
337 break;
338 }
339 glutPostRedisplay();
340}
341
342void XglTestFramework::Finish()
343{
344 if (m_images.size() == 0) return;
345
346 glutReshapeFunc( Reshape );
347 glutKeyboardFunc( Key );
348 glutSpecialFunc( SpecialKey );
349 glutDisplayFunc( Display );
350
351 glutMainLoop();
352}
353
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -0600354//
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -0600355// These are the default resources for TBuiltInResources, used for both
356// - parsing this string for the case where the user didn't supply one
357// - dumping out a template for user construction of a config file
358//
359static const char* DefaultConfig =
360 "MaxLights 32\n"
361 "MaxClipPlanes 6\n"
362 "MaxTextureUnits 32\n"
363 "MaxTextureCoords 32\n"
364 "MaxVertexAttribs 64\n"
365 "MaxVertexUniformComponents 4096\n"
366 "MaxVaryingFloats 64\n"
367 "MaxVertexTextureImageUnits 32\n"
368 "MaxCombinedTextureImageUnits 80\n"
369 "MaxTextureImageUnits 32\n"
370 "MaxFragmentUniformComponents 4096\n"
371 "MaxDrawBuffers 32\n"
372 "MaxVertexUniformVectors 128\n"
373 "MaxVaryingVectors 8\n"
374 "MaxFragmentUniformVectors 16\n"
375 "MaxVertexOutputVectors 16\n"
376 "MaxFragmentInputVectors 15\n"
377 "MinProgramTexelOffset -8\n"
378 "MaxProgramTexelOffset 7\n"
379 "MaxClipDistances 8\n"
380 "MaxComputeWorkGroupCountX 65535\n"
381 "MaxComputeWorkGroupCountY 65535\n"
382 "MaxComputeWorkGroupCountZ 65535\n"
383 "MaxComputeWorkGroupSizeX 1024\n"
384 "MaxComputeWorkGroupSizeY 1024\n"
385 "MaxComputeWorkGroupSizeZ 64\n"
386 "MaxComputeUniformComponents 1024\n"
387 "MaxComputeTextureImageUnits 16\n"
388 "MaxComputeImageUniforms 8\n"
389 "MaxComputeAtomicCounters 8\n"
390 "MaxComputeAtomicCounterBuffers 1\n"
391 "MaxVaryingComponents 60\n"
392 "MaxVertexOutputComponents 64\n"
393 "MaxGeometryInputComponents 64\n"
394 "MaxGeometryOutputComponents 128\n"
395 "MaxFragmentInputComponents 128\n"
396 "MaxImageUnits 8\n"
397 "MaxCombinedImageUnitsAndFragmentOutputs 8\n"
398 "MaxCombinedShaderOutputResources 8\n"
399 "MaxImageSamples 0\n"
400 "MaxVertexImageUniforms 0\n"
401 "MaxTessControlImageUniforms 0\n"
402 "MaxTessEvaluationImageUniforms 0\n"
403 "MaxGeometryImageUniforms 0\n"
404 "MaxFragmentImageUniforms 8\n"
405 "MaxCombinedImageUniforms 8\n"
406 "MaxGeometryTextureImageUnits 16\n"
407 "MaxGeometryOutputVertices 256\n"
408 "MaxGeometryTotalOutputComponents 1024\n"
409 "MaxGeometryUniformComponents 1024\n"
410 "MaxGeometryVaryingComponents 64\n"
411 "MaxTessControlInputComponents 128\n"
412 "MaxTessControlOutputComponents 128\n"
413 "MaxTessControlTextureImageUnits 16\n"
414 "MaxTessControlUniformComponents 1024\n"
415 "MaxTessControlTotalOutputComponents 4096\n"
416 "MaxTessEvaluationInputComponents 128\n"
417 "MaxTessEvaluationOutputComponents 128\n"
418 "MaxTessEvaluationTextureImageUnits 16\n"
419 "MaxTessEvaluationUniformComponents 1024\n"
420 "MaxTessPatchComponents 120\n"
421 "MaxPatchVertices 32\n"
422 "MaxTessGenLevel 64\n"
423 "MaxViewports 16\n"
424 "MaxVertexAtomicCounters 0\n"
425 "MaxTessControlAtomicCounters 0\n"
426 "MaxTessEvaluationAtomicCounters 0\n"
427 "MaxGeometryAtomicCounters 0\n"
428 "MaxFragmentAtomicCounters 8\n"
429 "MaxCombinedAtomicCounters 8\n"
430 "MaxAtomicCounterBindings 1\n"
431 "MaxVertexAtomicCounterBuffers 0\n"
432 "MaxTessControlAtomicCounterBuffers 0\n"
433 "MaxTessEvaluationAtomicCounterBuffers 0\n"
434 "MaxGeometryAtomicCounterBuffers 0\n"
435 "MaxFragmentAtomicCounterBuffers 1\n"
436 "MaxCombinedAtomicCounterBuffers 1\n"
437 "MaxAtomicCounterBufferSize 16384\n"
438 "MaxTransformFeedbackBuffers 4\n"
439 "MaxTransformFeedbackInterleavedComponents 64\n"
440 "MaxCullDistances 8\n"
441 "MaxCombinedClipAndCullDistances 8\n"
442 "MaxSamples 4\n"
443
444 "nonInductiveForLoops 1\n"
445 "whileLoops 1\n"
446 "doWhileLoops 1\n"
447 "generalUniformIndexing 1\n"
448 "generalAttributeMatrixVectorIndexing 1\n"
449 "generalVaryingIndexing 1\n"
450 "generalSamplerIndexing 1\n"
451 "generalVariableIndexing 1\n"
452 "generalConstantMatrixVectorIndexing 1\n"
453 ;
454
455//
456// *.conf => this is a config file that can set limits/resources
457//
458bool XglTestFramework::SetConfigFile(const std::string& name)
459{
460 if (name.size() < 5)
461 return false;
462
463 if (name.compare(name.size() - 5, 5, ".conf") == 0) {
464 ConfigFile = name;
465 return true;
466 }
467
468 return false;
469}
470
471//
472// Parse either a .conf file provided by the user or the default string above.
473//
474void XglTestFramework::ProcessConfigFile()
475{
476 char** configStrings = 0;
477 char* config = 0;
478 if (ConfigFile.size() > 0) {
479 configStrings = ReadFileData(ConfigFile.c_str());
480 if (configStrings)
481 config = *configStrings;
482 else {
483 printf("Error opening configuration file; will instead use the default configuration\n");
484 }
485 }
486
487 if (config == 0) {
488 config = new char[strlen(DefaultConfig) + 1];
489 strcpy(config, DefaultConfig);
490 }
491
492 const char* delims = " \t\n\r";
493 const char* token = strtok(config, delims);
494 while (token) {
495 const char* valueStr = strtok(0, delims);
496 if (valueStr == 0 || ! (valueStr[0] == '-' || (valueStr[0] >= '0' && valueStr[0] <= '9'))) {
497 printf("Error: '%s' bad .conf file. Each name must be followed by one number.\n", valueStr ? valueStr : "");
498 return;
499 }
500 int value = atoi(valueStr);
501
502 if (strcmp(token, "MaxLights") == 0)
503 Resources.maxLights = value;
504 else if (strcmp(token, "MaxClipPlanes") == 0)
505 Resources.maxClipPlanes = value;
506 else if (strcmp(token, "MaxTextureUnits") == 0)
507 Resources.maxTextureUnits = value;
508 else if (strcmp(token, "MaxTextureCoords") == 0)
509 Resources.maxTextureCoords = value;
510 else if (strcmp(token, "MaxVertexAttribs") == 0)
511 Resources.maxVertexAttribs = value;
512 else if (strcmp(token, "MaxVertexUniformComponents") == 0)
513 Resources.maxVertexUniformComponents = value;
514 else if (strcmp(token, "MaxVaryingFloats") == 0)
515 Resources.maxVaryingFloats = value;
516 else if (strcmp(token, "MaxVertexTextureImageUnits") == 0)
517 Resources.maxVertexTextureImageUnits = value;
518 else if (strcmp(token, "MaxCombinedTextureImageUnits") == 0)
519 Resources.maxCombinedTextureImageUnits = value;
520 else if (strcmp(token, "MaxTextureImageUnits") == 0)
521 Resources.maxTextureImageUnits = value;
522 else if (strcmp(token, "MaxFragmentUniformComponents") == 0)
523 Resources.maxFragmentUniformComponents = value;
524 else if (strcmp(token, "MaxDrawBuffers") == 0)
525 Resources.maxDrawBuffers = value;
526 else if (strcmp(token, "MaxVertexUniformVectors") == 0)
527 Resources.maxVertexUniformVectors = value;
528 else if (strcmp(token, "MaxVaryingVectors") == 0)
529 Resources.maxVaryingVectors = value;
530 else if (strcmp(token, "MaxFragmentUniformVectors") == 0)
531 Resources.maxFragmentUniformVectors = value;
532 else if (strcmp(token, "MaxVertexOutputVectors") == 0)
533 Resources.maxVertexOutputVectors = value;
534 else if (strcmp(token, "MaxFragmentInputVectors") == 0)
535 Resources.maxFragmentInputVectors = value;
536 else if (strcmp(token, "MinProgramTexelOffset") == 0)
537 Resources.minProgramTexelOffset = value;
538 else if (strcmp(token, "MaxProgramTexelOffset") == 0)
539 Resources.maxProgramTexelOffset = value;
540 else if (strcmp(token, "MaxClipDistances") == 0)
541 Resources.maxClipDistances = value;
542 else if (strcmp(token, "MaxComputeWorkGroupCountX") == 0)
543 Resources.maxComputeWorkGroupCountX = value;
544 else if (strcmp(token, "MaxComputeWorkGroupCountY") == 0)
545 Resources.maxComputeWorkGroupCountY = value;
546 else if (strcmp(token, "MaxComputeWorkGroupCountZ") == 0)
547 Resources.maxComputeWorkGroupCountZ = value;
548 else if (strcmp(token, "MaxComputeWorkGroupSizeX") == 0)
549 Resources.maxComputeWorkGroupSizeX = value;
550 else if (strcmp(token, "MaxComputeWorkGroupSizeY") == 0)
551 Resources.maxComputeWorkGroupSizeY = value;
552 else if (strcmp(token, "MaxComputeWorkGroupSizeZ") == 0)
553 Resources.maxComputeWorkGroupSizeZ = value;
554 else if (strcmp(token, "MaxComputeUniformComponents") == 0)
555 Resources.maxComputeUniformComponents = value;
556 else if (strcmp(token, "MaxComputeTextureImageUnits") == 0)
557 Resources.maxComputeTextureImageUnits = value;
558 else if (strcmp(token, "MaxComputeImageUniforms") == 0)
559 Resources.maxComputeImageUniforms = value;
560 else if (strcmp(token, "MaxComputeAtomicCounters") == 0)
561 Resources.maxComputeAtomicCounters = value;
562 else if (strcmp(token, "MaxComputeAtomicCounterBuffers") == 0)
563 Resources.maxComputeAtomicCounterBuffers = value;
564 else if (strcmp(token, "MaxVaryingComponents") == 0)
565 Resources.maxVaryingComponents = value;
566 else if (strcmp(token, "MaxVertexOutputComponents") == 0)
567 Resources.maxVertexOutputComponents = value;
568 else if (strcmp(token, "MaxGeometryInputComponents") == 0)
569 Resources.maxGeometryInputComponents = value;
570 else if (strcmp(token, "MaxGeometryOutputComponents") == 0)
571 Resources.maxGeometryOutputComponents = value;
572 else if (strcmp(token, "MaxFragmentInputComponents") == 0)
573 Resources.maxFragmentInputComponents = value;
574 else if (strcmp(token, "MaxImageUnits") == 0)
575 Resources.maxImageUnits = value;
576 else if (strcmp(token, "MaxCombinedImageUnitsAndFragmentOutputs") == 0)
577 Resources.maxCombinedImageUnitsAndFragmentOutputs = value;
578 else if (strcmp(token, "MaxCombinedShaderOutputResources") == 0)
579 Resources.maxCombinedShaderOutputResources = value;
580 else if (strcmp(token, "MaxImageSamples") == 0)
581 Resources.maxImageSamples = value;
582 else if (strcmp(token, "MaxVertexImageUniforms") == 0)
583 Resources.maxVertexImageUniforms = value;
584 else if (strcmp(token, "MaxTessControlImageUniforms") == 0)
585 Resources.maxTessControlImageUniforms = value;
586 else if (strcmp(token, "MaxTessEvaluationImageUniforms") == 0)
587 Resources.maxTessEvaluationImageUniforms = value;
588 else if (strcmp(token, "MaxGeometryImageUniforms") == 0)
589 Resources.maxGeometryImageUniforms = value;
590 else if (strcmp(token, "MaxFragmentImageUniforms") == 0)
591 Resources.maxFragmentImageUniforms = value;
592 else if (strcmp(token, "MaxCombinedImageUniforms") == 0)
593 Resources.maxCombinedImageUniforms = value;
594 else if (strcmp(token, "MaxGeometryTextureImageUnits") == 0)
595 Resources.maxGeometryTextureImageUnits = value;
596 else if (strcmp(token, "MaxGeometryOutputVertices") == 0)
597 Resources.maxGeometryOutputVertices = value;
598 else if (strcmp(token, "MaxGeometryTotalOutputComponents") == 0)
599 Resources.maxGeometryTotalOutputComponents = value;
600 else if (strcmp(token, "MaxGeometryUniformComponents") == 0)
601 Resources.maxGeometryUniformComponents = value;
602 else if (strcmp(token, "MaxGeometryVaryingComponents") == 0)
603 Resources.maxGeometryVaryingComponents = value;
604 else if (strcmp(token, "MaxTessControlInputComponents") == 0)
605 Resources.maxTessControlInputComponents = value;
606 else if (strcmp(token, "MaxTessControlOutputComponents") == 0)
607 Resources.maxTessControlOutputComponents = value;
608 else if (strcmp(token, "MaxTessControlTextureImageUnits") == 0)
609 Resources.maxTessControlTextureImageUnits = value;
610 else if (strcmp(token, "MaxTessControlUniformComponents") == 0)
611 Resources.maxTessControlUniformComponents = value;
612 else if (strcmp(token, "MaxTessControlTotalOutputComponents") == 0)
613 Resources.maxTessControlTotalOutputComponents = value;
614 else if (strcmp(token, "MaxTessEvaluationInputComponents") == 0)
615 Resources.maxTessEvaluationInputComponents = value;
616 else if (strcmp(token, "MaxTessEvaluationOutputComponents") == 0)
617 Resources.maxTessEvaluationOutputComponents = value;
618 else if (strcmp(token, "MaxTessEvaluationTextureImageUnits") == 0)
619 Resources.maxTessEvaluationTextureImageUnits = value;
620 else if (strcmp(token, "MaxTessEvaluationUniformComponents") == 0)
621 Resources.maxTessEvaluationUniformComponents = value;
622 else if (strcmp(token, "MaxTessPatchComponents") == 0)
623 Resources.maxTessPatchComponents = value;
624 else if (strcmp(token, "MaxPatchVertices") == 0)
625 Resources.maxPatchVertices = value;
626 else if (strcmp(token, "MaxTessGenLevel") == 0)
627 Resources.maxTessGenLevel = value;
628 else if (strcmp(token, "MaxViewports") == 0)
629 Resources.maxViewports = value;
630 else if (strcmp(token, "MaxVertexAtomicCounters") == 0)
631 Resources.maxVertexAtomicCounters = value;
632 else if (strcmp(token, "MaxTessControlAtomicCounters") == 0)
633 Resources.maxTessControlAtomicCounters = value;
634 else if (strcmp(token, "MaxTessEvaluationAtomicCounters") == 0)
635 Resources.maxTessEvaluationAtomicCounters = value;
636 else if (strcmp(token, "MaxGeometryAtomicCounters") == 0)
637 Resources.maxGeometryAtomicCounters = value;
638 else if (strcmp(token, "MaxFragmentAtomicCounters") == 0)
639 Resources.maxFragmentAtomicCounters = value;
640 else if (strcmp(token, "MaxCombinedAtomicCounters") == 0)
641 Resources.maxCombinedAtomicCounters = value;
642 else if (strcmp(token, "MaxAtomicCounterBindings") == 0)
643 Resources.maxAtomicCounterBindings = value;
644 else if (strcmp(token, "MaxVertexAtomicCounterBuffers") == 0)
645 Resources.maxVertexAtomicCounterBuffers = value;
646 else if (strcmp(token, "MaxTessControlAtomicCounterBuffers") == 0)
647 Resources.maxTessControlAtomicCounterBuffers = value;
648 else if (strcmp(token, "MaxTessEvaluationAtomicCounterBuffers") == 0)
649 Resources.maxTessEvaluationAtomicCounterBuffers = value;
650 else if (strcmp(token, "MaxGeometryAtomicCounterBuffers") == 0)
651 Resources.maxGeometryAtomicCounterBuffers = value;
652 else if (strcmp(token, "MaxFragmentAtomicCounterBuffers") == 0)
653 Resources.maxFragmentAtomicCounterBuffers = value;
654 else if (strcmp(token, "MaxCombinedAtomicCounterBuffers") == 0)
655 Resources.maxCombinedAtomicCounterBuffers = value;
656 else if (strcmp(token, "MaxAtomicCounterBufferSize") == 0)
657 Resources.maxAtomicCounterBufferSize = value;
658 else if (strcmp(token, "MaxTransformFeedbackBuffers") == 0)
659 Resources.maxTransformFeedbackBuffers = value;
660 else if (strcmp(token, "MaxTransformFeedbackInterleavedComponents") == 0)
661 Resources.maxTransformFeedbackInterleavedComponents = value;
662 else if (strcmp(token, "MaxCullDistances") == 0)
663 Resources.maxCullDistances = value;
664 else if (strcmp(token, "MaxCombinedClipAndCullDistances") == 0)
665 Resources.maxCombinedClipAndCullDistances = value;
666 else if (strcmp(token, "MaxSamples") == 0)
667 Resources.maxSamples = value;
668
669 else if (strcmp(token, "nonInductiveForLoops") == 0)
670 Resources.limits.nonInductiveForLoops = (value != 0);
671 else if (strcmp(token, "whileLoops") == 0)
672 Resources.limits.whileLoops = (value != 0);
673 else if (strcmp(token, "doWhileLoops") == 0)
674 Resources.limits.doWhileLoops = (value != 0);
675 else if (strcmp(token, "generalUniformIndexing") == 0)
676 Resources.limits.generalUniformIndexing = (value != 0);
677 else if (strcmp(token, "generalAttributeMatrixVectorIndexing") == 0)
678 Resources.limits.generalAttributeMatrixVectorIndexing = (value != 0);
679 else if (strcmp(token, "generalVaryingIndexing") == 0)
680 Resources.limits.generalVaryingIndexing = (value != 0);
681 else if (strcmp(token, "generalSamplerIndexing") == 0)
682 Resources.limits.generalSamplerIndexing = (value != 0);
683 else if (strcmp(token, "generalVariableIndexing") == 0)
684 Resources.limits.generalVariableIndexing = (value != 0);
685 else if (strcmp(token, "generalConstantMatrixVectorIndexing") == 0)
686 Resources.limits.generalConstantMatrixVectorIndexing = (value != 0);
687 else
688 printf("Warning: unrecognized limit (%s) in configuration file.\n", token);
689
690 token = strtok(0, delims);
691 }
692 if (configStrings)
693 FreeFileData(configStrings);
694}
695
696void XglTestFramework::SetMessageOptions(EShMessages& messages)
697{
698 if (m_compile_options & EOptionRelaxedErrors)
699 messages = (EShMessages)(messages | EShMsgRelaxedErrors);
700 if (m_compile_options & EOptionIntermediate)
701 messages = (EShMessages)(messages | EShMsgAST);
702 if (m_compile_options & EOptionSuppressWarnings)
703 messages = (EShMessages)(messages | EShMsgSuppressWarnings);
704}
705
706//
707// Malloc a string of sufficient size and read a string into it.
708//
709char** XglTestFramework::ReadFileData(const char* fileName)
710{
711 FILE *in;
712 #if defined(_WIN32) && defined(__GNUC__)
713 in = fopen(fileName, "r");
714 int errorCode = in ? 0 : 1;
715 #else
716 int errorCode = fopen_s(&in, fileName, "r");
717 #endif
718
719 char *fdata;
720 int count = 0;
721 const int maxSourceStrings = 5;
722 char** return_data = (char**)malloc(sizeof(char *) * (maxSourceStrings+1));
723
724 if (errorCode) {
725 printf("Error: unable to open input file: %s\n", fileName);
726 return 0;
727 }
728
729 while (fgetc(in) != EOF)
730 count++;
731
732 fseek(in, 0, SEEK_SET);
733
734 if (!(fdata = (char*)malloc(count+2))) {
735 printf("Error allocating memory\n");
736 return 0;
737 }
738 if (fread(fdata,1,count, in)!=count) {
739 printf("Error reading input file: %s\n", fileName);
740 return 0;
741 }
742 fdata[count] = '\0';
743 fclose(in);
744 if (count == 0) {
745 return_data[0]=(char*)malloc(count+2);
746 return_data[0][0]='\0';
747 m_num_shader_strings = 0;
748 return return_data;
749 } else
750 m_num_shader_strings = 1;
751
752 int len = (int)(ceil)((float)count/(float)m_num_shader_strings);
753 int ptr_len=0,i=0;
754 while(count>0){
755 return_data[i]=(char*)malloc(len+2);
756 memcpy(return_data[i],fdata+ptr_len,len);
757 return_data[i][len]='\0';
758 count-=(len);
759 ptr_len+=(len);
760 if(count<len){
761 if(count==0){
762 m_num_shader_strings=(i+1);
763 break;
764 }
765 len = count;
766 }
767 ++i;
768 }
769 return return_data;
770}
771
772void XglTestFramework::FreeFileData(char** data)
773{
774 for(int i=0;i<m_num_shader_strings;i++)
775 free(data[i]);
776}
777
778//
779// Deduce the language from the filename. Files must end in one of the
780// following extensions:
781//
782// .vert = vertex
783// .tesc = tessellation control
784// .tese = tessellation evaluation
785// .geom = geometry
786// .frag = fragment
787// .comp = compute
788//
789EShLanguage XglTestFramework::FindLanguage(const std::string& name)
790{
791 size_t ext = name.rfind('.');
792 if (ext == std::string::npos) {
793 return EShLangVertex;
794 }
795
796 std::string suffix = name.substr(ext + 1, std::string::npos);
797 if (suffix == "vert")
798 return EShLangVertex;
799 else if (suffix == "tesc")
800 return EShLangTessControl;
801 else if (suffix == "tese")
802 return EShLangTessEvaluation;
803 else if (suffix == "geom")
804 return EShLangGeometry;
805 else if (suffix == "frag")
806 return EShLangFragment;
807 else if (suffix == "comp")
808 return EShLangCompute;
809
810 return EShLangVertex;
811}
812
813//
814// Convert XGL shader type to compiler's
815//
816EShLanguage XglTestFramework::FindLanguage(const XGL_PIPELINE_SHADER_STAGE shader_type)
817{
818 switch (shader_type) {
819 case XGL_SHADER_STAGE_VERTEX:
820 return EShLangVertex;
821
822 case XGL_SHADER_STAGE_TESS_CONTROL:
823 return EShLangTessControl;
824
825 case XGL_SHADER_STAGE_TESS_EVALUATION:
826 return EShLangTessEvaluation;
827
828 case XGL_SHADER_STAGE_GEOMETRY:
829 return EShLangGeometry;
830
831 case XGL_SHADER_STAGE_FRAGMENT:
832 return EShLangFragment;
833
834 case XGL_SHADER_STAGE_COMPUTE:
835 return EShLangCompute;
836 }
837
838 return EShLangVertex;
839}
840
841
842//
843// Compile a given string containing GLSL into BIL for use by XGL
844// Return value of false means an error was encountered.
845//
846bool XglTestFramework::GLSLtoBIL(const XGL_PIPELINE_SHADER_STAGE shader_type,
847 const char *pshader,
848 std::vector<unsigned int> &bil)
849{
850 glslang::TProgram& program = *new glslang::TProgram;
851 const char *shaderStrings[1];
852
853 // TODO: Do we want to load a special config file depending on the
854 // shader source? Optional name maybe?
855 // SetConfigFile(fileName);
856
857 ProcessConfigFile();
858
859 EShMessages messages = EShMsgDefault;
860 SetMessageOptions(messages);
861
862 EShLanguage stage = FindLanguage(shader_type);
863 glslang::TShader* shader = new glslang::TShader(stage);
864
865 shaderStrings[0] = pshader;
866 shader->setStrings(shaderStrings, 1);
867
868 if (! shader->parse(&Resources, (m_compile_options & EOptionDefaultDesktop) ? 110 : 100, false, messages)) {
869
870 return false; // something didn't work
871 }
872
873 program.addShader(shader);
874
875 if (! (m_compile_options & EOptionSuppressInfolog)) {
876 puts(shader->getInfoLog());
877 puts(shader->getInfoDebugLog());
878 }
879
880 //
881 // Program-level processing...
882 //
883
884 if (! program.link(messages))
885 return false;
886
887 if (! (m_compile_options & EOptionSuppressInfolog)) {
888 puts(program.getInfoLog());
889 puts(program.getInfoDebugLog());
890 }
891
892 if (m_compile_options & EOptionDumpReflection) {
893 program.buildReflection();
894 program.dumpReflection();
895 }
896
897 glslang::GlslangToBil(*program.getIntermediate(stage), bil);
898
899 return true;
900}
901
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600902
903
904XglTestImageRecord::XglTestImageRecord() : // Constructor
905 m_width( 0 ),
906 m_height( 0 ),
907 m_data( NULL )
908{
909 m_data_size = 0;
910}
911
912XglTestImageRecord::~XglTestImageRecord()
913{
914
915}
916
917XglTestImageRecord::XglTestImageRecord(const XglTestImageRecord &copyin) // Copy constructor to handle pass by value.
918{
919 m_title = copyin.m_title;
920 m_width = copyin.m_width;
921 m_height = copyin.m_height;
922 m_data_size = copyin.m_data_size;
923 m_data = copyin.m_data; // TODO: Do we need to copy the data or is pointer okay?
924}
925
926ostream &operator<<(ostream &output, const XglTestImageRecord &XglTestImageRecord)
927{
928 output << XglTestImageRecord.m_title << " (" << XglTestImageRecord.m_width <<
929 "," << XglTestImageRecord.m_height << ")" << endl;
930 return output;
931}
932
933XglTestImageRecord& XglTestImageRecord::operator=(const XglTestImageRecord &rhs)
934{
935 m_title = rhs.m_title;
936 m_width = rhs.m_width;
937 m_height = rhs.m_height;
938 m_data_size = rhs.m_data_size;
939 m_data = rhs.m_data;
940 return *this;
941}
942
943int XglTestImageRecord::operator==(const XglTestImageRecord &rhs) const
944{
945 if( this->m_data != rhs.m_data) return 0;
946 return 1;
947}
948
949// This function is required for built-in STL list functions like sort
950int XglTestImageRecord::operator<(const XglTestImageRecord &rhs) const
951{
952 if( this->m_data_size < rhs.m_data_size ) return 1;
953 return 0;
954}
955