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