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