blob: 7b83596a134ea143b81fca45835acd79fe2936e8 [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"
Chia-I Wua6bc0ce2014-12-29 14:38:28 +080024#include "xglrenderframework.h"
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -060025#include "GL/freeglut_std.h"
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -060026//#include "ShaderLang.h"
27#include "GlslangToBil.h"
Tony Barbour4ab45422014-12-10 17:00:20 -070028#include <limits.h>
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -060029#include <math.h>
Chia-I Wuec664fa2014-12-02 11:54:24 +080030#include <wand/MagickWand.h>
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -060031
32// Command-line options
33enum TOptions {
34 EOptionNone = 0x000,
35 EOptionIntermediate = 0x001,
36 EOptionSuppressInfolog = 0x002,
37 EOptionMemoryLeakMode = 0x004,
38 EOptionRelaxedErrors = 0x008,
39 EOptionGiveWarnings = 0x010,
40 EOptionLinkProgram = 0x020,
41 EOptionMultiThreaded = 0x040,
42 EOptionDumpConfig = 0x080,
43 EOptionDumpReflection = 0x100,
44 EOptionSuppressWarnings = 0x200,
45 EOptionDumpVersions = 0x400,
46 EOptionBil = 0x800,
47 EOptionDefaultDesktop = 0x1000,
48};
49
50#ifndef _WIN32
51
52#include <errno.h>
53
54int fopen_s(
55 FILE** pFile,
56 const char* filename,
57 const char* mode
58)
59{
60 if (!pFile || !filename || !mode) {
61 return EINVAL;
62 }
63
64 FILE* f = fopen(filename, mode);
65 if (! f) {
66 if (errno != 0) {
67 return errno;
68 } else {
69 return ENOENT;
70 }
71 }
72 *pFile = f;
73
74 return 0;
75}
76
77#endif
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -060078
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -060079// Set up environment for GLSL compiler
80// Must be done once per process
81void TestEnvironment::SetUp()
82{
83 // Initialize GLSL to BIL compiler utility
84 glslang::InitializeProcess();
Chia-I Wub76e0fa2014-12-28 14:27:28 +080085
86 xgl_testing::set_error_callback(test_error_callback);
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -060087}
88
89void TestEnvironment::TearDown()
90{
91 glslang::FinalizeProcess();
92}
93
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -060094XglTestFramework::XglTestFramework() :
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -060095 m_compile_options( 0 ),
96 m_num_shader_strings( 0 )
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -060097{
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -060098
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -060099}
100
101XglTestFramework::~XglTestFramework()
102{
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600103
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600104}
105
106// Define all the static elements
107bool XglTestFramework::m_show_images = false;
108bool XglTestFramework::m_save_images = false;
Tony Barbour247bf372014-10-30 14:29:04 -0600109bool XglTestFramework::m_compare_images = false;
Courtney Goeltzenleuchterc44e3ee2014-10-31 14:13:33 -0600110bool XglTestFramework::m_use_bil = true;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600111int XglTestFramework::m_width = 0;
112int XglTestFramework::m_height = 0;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600113std::list<XglTestImageRecord> XglTestFramework::m_images;
114std::list<XglTestImageRecord>::iterator XglTestFramework::m_display_image;
115int m_display_image_idx = 0;
116
117void XglTestFramework::InitArgs(int *argc, char *argv[])
118{
119 int i, n;
120
121 for (i=0, n=0; i< *argc; i++) {
122 if (strncmp("--show-images", argv[i], 13) == 0) {
123 m_show_images = true;
124 continue;
125 }
126 if (strncmp("--save-images", argv[i], 13) == 0) {
127 m_save_images = true;
128 continue;
129 }
130
Courtney Goeltzenleuchterb666dc62014-10-09 09:13:56 -0600131 if (strncmp("--use-BIL", argv[i], 13) == 0) {
132 m_use_bil = true;
133 continue;
134 }
135
Courtney Goeltzenleuchterc44e3ee2014-10-31 14:13:33 -0600136 if (strncmp("--no-BIL", argv[i], 13) == 0) {
137 m_use_bil = false;
138 continue;
139 }
140
Tony Barbour247bf372014-10-30 14:29:04 -0600141 if (strncmp("--compare-images", argv[i], 16) == 0) {
142 m_compare_images = true;
143 continue;
144 }
145
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600146 /*
147 * Since the above "consume" inputs, update argv
148 * so that it contains the trimmed list of args for glutInit
149 */
Tony Barboura98d3932014-12-11 09:52:49 -0700150 if (strncmp("--help", argv[i], 6) == 0 || strncmp("-h", argv[i], 2) == 0) {
Courtney Goeltzenleuchter31144b72014-12-02 13:13:10 -0700151 printf("\nOther options:\n");
152 printf("\t--show-images\n"
153 "\t\tDisplay test images in viewer after tests complete.\n");
154 printf("\t--save-images\n"
155 "\t\tSave tests images as ppm files in current working directory.\n"
156 "\t\tUsed to generate golden images for compare-images.\n");
157 printf("\t--compare-images\n"
158 "\t\tCompare test images to 'golden' image in golden folder.\n"
Tony Barboura98d3932014-12-11 09:52:49 -0700159 "\t\tAlso saves the generated test image in current working\n"
160 "\t\t\tdirectory but only if the image is different from the golden\n"
161 "\t\tSetting RENDERTEST_GOLDEN_DIR environment variable can specify\n"
162 "\t\t\tdifferent directory for golden images\n"
Courtney Goeltzenleuchter31144b72014-12-02 13:13:10 -0700163 "\t\tSignal test failure if different.\n");
164 printf("\t--use-BIL\n"
165 "\t\tUse BIL code path (default).\n");
166 printf("\t--no-BIL\n"
167 "\t\tUse built-in GLSL compiler rather than BIL code path.\n");
Tony Barbour4ab45422014-12-10 17:00:20 -0700168 exit(0);
Courtney Goeltzenleuchter31144b72014-12-02 13:13:10 -0700169 }
170
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600171 argv[n] = argv[i];
172 n++;
173 }
174
175 if (m_show_images) {
176 glutInit(argc, argv);
177 }
178}
179
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600180void XglTestFramework::WritePPM( const char *basename, XglImage *image )
181{
182 string filename;
183 XGL_RESULT err;
Courtney Goeltzenleuchter02d33c12014-10-08 14:26:40 -0600184 int x, y;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600185
186 filename.append(basename);
187 filename.append(".ppm");
188
189 const XGL_IMAGE_SUBRESOURCE sr = {
190 XGL_IMAGE_ASPECT_COLOR, 0, 0
191 };
192 XGL_SUBRESOURCE_LAYOUT sr_layout;
Chia-I Wu99ff89d2014-12-27 14:14:50 +0800193 size_t data_size = sizeof(sr_layout);
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600194
195 err = xglGetImageSubresourceInfo( image->image(), &sr,
196 XGL_INFO_TYPE_SUBRESOURCE_LAYOUT,
197 &data_size, &sr_layout);
198 ASSERT_XGL_SUCCESS( err );
199 ASSERT_EQ(data_size, sizeof(sr_layout));
200
201 const char *ptr;
202
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600203 err = xglMapMemory( image->memory(), 0, (void **) &ptr );
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600204 ASSERT_XGL_SUCCESS( err );
205
206 ptr += sr_layout.offset;
207
208 ofstream file (filename.c_str());
209 ASSERT_TRUE(file.is_open()) << "Unable to open file: " << filename;
210
211 file << "P6\n";
212 file << image->width() << "\n";
213 file << image->height() << "\n";
214 file << 255 << "\n";
215
216 for (y = 0; y < image->height(); y++) {
Tony Barboura53a6942015-02-25 11:25:11 -0700217 const int *row = (const int *) ptr;
218 int swapped;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600219
Tony Barboura53a6942015-02-25 11:25:11 -0700220 if (image->format() == XGL_FMT_B8G8R8A8_UNORM)
221 {
222 for (x = 0; x < image->width(); x++) {
223 swapped = (*row & 0xff00ff00) | (*row & 0x000000ff) << 16 | (*row & 0x00ff0000) >> 16;
224 file.write((char *) &swapped, 3);
225 row++;
226 }
227 }
228 else if (image->format() == XGL_FMT_R8G8B8A8_UNORM)
229 {
230 for (x = 0; x < image->width(); x++) {
231 file.write((char *) row, 3);
232 row++;
233 }
234 }
235 else {
236 printf("Unrecognized image format - will not write image files");
237 break;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600238 }
239
240 ptr += sr_layout.rowPitch;
241 }
242
243 file.close();
244
245 err = xglUnmapMemory( image->memory() );
246 ASSERT_XGL_SUCCESS( err );
247}
248
Tony Barbour247bf372014-10-30 14:29:04 -0600249void XglTestFramework::Compare(const char *basename, XglImage *image )
250{
251
252 MagickWand *magick_wand_1;
253 MagickWand *magick_wand_2;
254 MagickWand *compare_wand;
255 MagickBooleanType status;
Tony Barbour4ab45422014-12-10 17:00:20 -0700256 char testimage[256],golden[PATH_MAX+256],golddir[PATH_MAX] = "./golden";
Tony Barbour247bf372014-10-30 14:29:04 -0600257 double differenz;
258
Tony Barbour4ab45422014-12-10 17:00:20 -0700259 if (getenv("RENDERTEST_GOLDEN_DIR"))
260 {
261 strcpy(golddir,getenv("RENDERTEST_GOLDEN_DIR"));
262 }
263
Tony Barbour247bf372014-10-30 14:29:04 -0600264 MagickWandGenesis();
265 magick_wand_1=NewMagickWand();
266 sprintf(testimage,"%s.ppm",basename);
267 status=MagickReadImage(magick_wand_1,testimage);
268 ASSERT_TRUE(status) << "Unable to open file: " << testimage;
269
270
271 MagickWandGenesis();
272 magick_wand_2=NewMagickWand();
Tony Barbour4ab45422014-12-10 17:00:20 -0700273 sprintf(golden,"%s/%s.ppm",golddir,basename);
Tony Barbour247bf372014-10-30 14:29:04 -0600274 status=MagickReadImage(magick_wand_2,golden);
275 ASSERT_TRUE(status) << "Unable to open file: " << golden;
276
Tony Barbour247bf372014-10-30 14:29:04 -0600277 compare_wand=MagickCompareImages(magick_wand_1,magick_wand_2, MeanAbsoluteErrorMetric, &differenz);
278 if (differenz != 0.0)
279 {
280 char difference[256];
281
282 sprintf(difference,"%s-diff.ppm",basename);
283 status = MagickWriteImage(compare_wand, difference);
284 ASSERT_TRUE(differenz == 0.0) << "Image comparison failed - diff file written";
285 }
286 DestroyMagickWand(compare_wand);
287
288 DestroyMagickWand(magick_wand_1);
289 DestroyMagickWand(magick_wand_2);
290 MagickWandTerminus();
Courtney Goeltzenleuchterfcda72d2014-12-05 15:41:02 -0700291
292 if (differenz == 0.0)
293 {
294 /*
295 * If test image and golden image match, we do not need to
296 * keep around the test image.
297 */
298 remove(testimage);
299 }
Tony Barbour247bf372014-10-30 14:29:04 -0600300}
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600301
302void XglTestFramework::Show(const char *comment, XglImage *image)
303{
304 XGL_RESULT err;
305
306 const XGL_IMAGE_SUBRESOURCE sr = {
307 XGL_IMAGE_ASPECT_COLOR, 0, 0
308 };
309 XGL_SUBRESOURCE_LAYOUT sr_layout;
Chia-I Wu99ff89d2014-12-27 14:14:50 +0800310 size_t data_size = sizeof(sr_layout);
Tony Barbour96db8822015-02-25 12:28:39 -0700311 XglTestImageRecord record;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600312
313 if (!m_show_images) return;
314
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600315 err = xglGetImageSubresourceInfo( image->image(), &sr, XGL_INFO_TYPE_SUBRESOURCE_LAYOUT,
316 &data_size, &sr_layout);
317 ASSERT_XGL_SUCCESS( err );
318 ASSERT_EQ(data_size, sizeof(sr_layout));
319
Tony Barbour96db8822015-02-25 12:28:39 -0700320 char *ptr;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600321
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600322 err = image->MapMemory( (void **) &ptr );
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600323 ASSERT_XGL_SUCCESS( err );
324
325 ptr += sr_layout.offset;
326
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600327 record.m_title.append(comment);
328 record.m_width = image->width();
329 record.m_height = image->height();
330 // TODO: Need to make this more robust to handle different image formats
331 record.m_data_size = image->width()*image->height()*4;
332 record.m_data = malloc(record.m_data_size);
333 memcpy(record.m_data, ptr, record.m_data_size);
334 m_images.push_back(record);
335 m_display_image = --m_images.end();
336
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600337 err = image->UnmapMemory();
338 ASSERT_XGL_SUCCESS( err );
Tony Barbour96db8822015-02-25 12:28:39 -0700339
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600340}
341
Tony Barbour247bf372014-10-30 14:29:04 -0600342void XglTestFramework::RecordImage(XglImage *image, char *tag)
343{
344 const ::testing::TestInfo* const test_info =
345 ::testing::UnitTest::GetInstance()->current_test_info();
346 ostringstream filestream;
347 string filename;
348
349 filestream << test_info->name() << "-" << tag;
350 filename = filestream.str();
351 // ToDo - scrub string for bad characters
352
353 if (m_save_images || m_compare_images) {
354 WritePPM(filename.c_str(), image);
355 if (m_compare_images) {
356 Compare(filename.c_str(), image);
357 }
358 }
359
360 if (m_show_images) {
361 Show(test_info->name(), image);
362 }
363}
364
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600365void XglTestFramework::RecordImage(XglImage *image)
366{
367 const ::testing::TestInfo* const test_info =
368 ::testing::UnitTest::GetInstance()->current_test_info();
Tony Barbour247bf372014-10-30 14:29:04 -0600369 ostringstream filestream;
370 string filename;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600371
Tony Barbour247bf372014-10-30 14:29:04 -0600372 m_width = 40;
373
374 if (strcmp(test_info->name(), m_testName.c_str())) {
375 filestream << test_info->name();
376 m_testName.assign(test_info->name());
Tony Barboura0e2ee82014-11-18 17:02:36 -0700377 m_frameNum = 2;
378 filename = filestream.str();
Tony Barbour247bf372014-10-30 14:29:04 -0600379 }
380 else {
381 filestream << test_info->name() << "-" << m_frameNum;
382 m_frameNum++;
Tony Barboura0e2ee82014-11-18 17:02:36 -0700383 filename = filestream.str();
Tony Barbour247bf372014-10-30 14:29:04 -0600384 }
385
386
387 // ToDo - scrub string for bad characters
388
389 if (m_save_images || m_compare_images) {
390 WritePPM(filename.c_str(), image);
391 if (m_compare_images) {
392 Compare(filename.c_str(), image);
393 }
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600394 }
395
396 if (m_show_images) {
Courtney Goeltzenleuchter02d33c12014-10-08 14:26:40 -0600397 Show(test_info->name(), image);
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600398 }
399}
400
Tony Barbour96db8822015-02-25 12:28:39 -0700401static xgl_testing::Environment *environment;
402
403TestFrameworkXglPresent::TestFrameworkXglPresent() :
404m_device(environment->default_device()),
405m_queue(*m_device.graphics_queues()[0]),
406m_cmdbuf(m_device, xgl_testing::CmdBuffer::create_info(XGL_QUEUE_TYPE_GRAPHICS))
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600407{
Tony Barbour96db8822015-02-25 12:28:39 -0700408 m_quit = false;
409 m_pause = false;
410 m_width = 0;
411 m_height = 0;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600412}
413
Tony Barbour96db8822015-02-25 12:28:39 -0700414void TestFrameworkXglPresent::Display()
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600415{
Tony Barbour96db8822015-02-25 12:28:39 -0700416 XGL_RESULT err;
417
418 XGL_WSI_X11_PRESENT_INFO present = {
419 .destWindow = m_window,
420 .srcImage = m_display_image->m_presentableImage,
421 };
422
423 xcb_change_property (environment->m_connection,
424 XCB_PROP_MODE_REPLACE,
425 m_window,
426 XCB_ATOM_WM_NAME,
427 XCB_ATOM_STRING,
428 8,
429 m_display_image->m_title.size(),
430 m_display_image->m_title.c_str());
431
432 err = xglWsiX11QueuePresent(m_queue.obj(), &present, NULL);
433 assert(!err);
434
435 m_queue.wait();
436
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600437}
438
Tony Barbour96db8822015-02-25 12:28:39 -0700439void TestFrameworkXglPresent::HandleEvent(xcb_generic_event_t *event)
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600440{
Tony Barbour96db8822015-02-25 12:28:39 -0700441 u_int8_t event_code = event->response_type & 0x7f;
442 switch (event_code) {
443 case XCB_EXPOSE:
444 Display(); // TODO: handle resize
445 break;
446 case XCB_CLIENT_MESSAGE:
447 if((*(xcb_client_message_event_t*)event).data.data32[0] ==
448 (m_atom_wm_delete_window)->atom) {
449 m_quit = true;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600450 }
451 break;
Tony Barbour96db8822015-02-25 12:28:39 -0700452 case XCB_KEY_RELEASE:
453 {
454 const xcb_key_release_event_t *key =
455 (const xcb_key_release_event_t *) event;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600456
Tony Barbour96db8822015-02-25 12:28:39 -0700457 switch (key->detail) {
458 case 0x9: // Escape
459 m_quit = true;
460 break;
461 case 0x71: // left arrow key
462 if (m_display_image == m_images.begin()) {
463 m_display_image = --m_images.end();
464 } else {
465 --m_display_image;
466 }
467 break;
468 case 0x72: // right arrow key
469 ++m_display_image;
470 if (m_display_image == m_images.end()) {
471 m_display_image = m_images.begin();
472 }
473 break;
474 case 0x41:
475 m_pause = !m_pause;
476 break;
477 }
478 Display();
479 }
480 break;
481 default:
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600482 break;
483 }
Tony Barbour96db8822015-02-25 12:28:39 -0700484}
485
486void TestFrameworkXglPresent::Run()
487{
488 xcb_flush(environment->m_connection);
489
490 while (! m_quit) {
491 xcb_generic_event_t *event;
492
493 if (m_pause) {
494 event = xcb_wait_for_event(environment->m_connection);
495 } else {
496 event = xcb_poll_for_event(environment->m_connection);
497 }
498 if (event) {
499 HandleEvent(event);
500 free(event);
501 }
502 }
503}
504
505void TestFrameworkXglPresent::CreatePresentableImages()
506{
507 XGL_RESULT err;
508
509 m_display_image = m_images.begin();
510
511 for (int x=0; x < m_images.size(); x++)
512 {
513 const XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO presentable_image_info = {
514 .format = XGL_FMT_B8G8R8A8_UNORM,
515 .usage = XGL_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
516 .extent = {
517 .width = m_display_image->m_width,
518 .height = m_display_image->m_height,
519 },
520 .flags = 0,
521 };
522
523 void *dest_ptr;
524
525 err = xglWsiX11CreatePresentableImage(m_device.obj(), &presentable_image_info,
526 &m_display_image->m_presentableImage, &m_display_image->m_presentableMemory);
527 assert(!err);
528
529 xgl_testing::Buffer buf;
530 buf.init(m_device, (XGL_GPU_SIZE) m_display_image->m_data_size);
531 dest_ptr = buf.map();
532 memcpy(dest_ptr,m_display_image->m_data, m_display_image->m_data_size);
533 buf.unmap();
534
535 m_cmdbuf.begin();
536
537 XGL_BUFFER_IMAGE_COPY region = {};
538 region.imageExtent.height = m_display_image->m_height;
539 region.imageExtent.width = m_display_image->m_width;
540 region.imageExtent.depth = 1;
541
542 xglCmdCopyBufferToImage(m_cmdbuf.obj(), buf.obj(), m_display_image->m_presentableImage, 1, &region);
543 m_cmdbuf.end();
544
545 uint32_t numMemRefs=2;
546 XGL_MEMORY_REF memRefs[2];
547 memRefs[0].flags = 0;
548 memRefs[0].mem = m_display_image->m_presentableMemory;
549 memRefs[1].flags = 0;
550 memRefs[1].mem = buf.memories()[0];
551
552 XGL_CMD_BUFFER cmdBufs[1];
553 cmdBufs[0] = m_cmdbuf.obj();
554
555 xglQueueSubmit(m_queue.obj(), 1, cmdBufs, numMemRefs, memRefs, NULL);
556 m_queue.wait();
557
558
559 if (m_display_image->m_width > m_width)
560 m_width = m_display_image->m_width;
561
562 if (m_display_image->m_height > m_height)
563 m_height = m_display_image->m_height;
564
565
566 ++m_display_image;
567
568 }
569
570 m_display_image = m_images.begin();
571}
572
573void TestFrameworkXglPresent::InitPresentFramework(std::list<XglTestImageRecord> &imagesIn)
574{
575 m_images = imagesIn;
576}
577
578void TestFrameworkXglPresent::CreateWindow()
579{
580 uint32_t value_mask, value_list[32];
581
582 m_window = xcb_generate_id(environment->m_connection);
583
584 value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
585 value_list[0] = environment->m_screen->black_pixel;
586 value_list[1] = XCB_EVENT_MASK_KEY_RELEASE |
587 XCB_EVENT_MASK_EXPOSURE |
588 XCB_EVENT_MASK_STRUCTURE_NOTIFY;
589
590 xcb_create_window(environment->m_connection,
591 XCB_COPY_FROM_PARENT,
592 m_window, environment->m_screen->root,
593 0, 0, m_width, m_height, 0,
594 XCB_WINDOW_CLASS_INPUT_OUTPUT,
595 environment->m_screen->root_visual,
596 value_mask, value_list);
597
598 /* Magic code that will send notification when window is destroyed */
599 xcb_intern_atom_cookie_t cookie = xcb_intern_atom(environment->m_connection, 1, 12,
600 "WM_PROTOCOLS");
601 xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(environment->m_connection, cookie, 0);
602
603 xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(environment->m_connection, 0, 16, "WM_DELETE_WINDOW");
604 m_atom_wm_delete_window = xcb_intern_atom_reply(environment->m_connection, cookie2, 0);
605
606 xcb_change_property(environment->m_connection, XCB_PROP_MODE_REPLACE,
607 m_window, (*reply).atom, 4, 32, 1,
608 &(*m_atom_wm_delete_window).atom);
609 free(reply);
610
611 xcb_map_window(environment->m_connection, m_window);
612}
613
614void TestFrameworkXglPresent::TearDown()
615{
616 xcb_destroy_window(environment->m_connection, m_window);
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600617}
618
619void XglTestFramework::Finish()
620{
621 if (m_images.size() == 0) return;
622
Tony Barbour96db8822015-02-25 12:28:39 -0700623 environment = new xgl_testing::Environment();
624 ::testing::AddGlobalTestEnvironment(environment);
625 environment->X11SetUp();
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600626
Tony Barbour96db8822015-02-25 12:28:39 -0700627 {
628 TestFrameworkXglPresent xglPresent;
629
630 xglPresent.InitPresentFramework(m_images);
631 xglPresent.CreatePresentableImages();
632 xglPresent.CreateWindow();
633 xglPresent.Run();
634 xglPresent.TearDown();
635 }
636 environment->TearDown();
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600637}
638
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600639//
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600640// These are the default resources for TBuiltInResources, used for both
641// - parsing this string for the case where the user didn't supply one
642// - dumping out a template for user construction of a config file
643//
644static const char* DefaultConfig =
645 "MaxLights 32\n"
646 "MaxClipPlanes 6\n"
647 "MaxTextureUnits 32\n"
648 "MaxTextureCoords 32\n"
649 "MaxVertexAttribs 64\n"
650 "MaxVertexUniformComponents 4096\n"
651 "MaxVaryingFloats 64\n"
652 "MaxVertexTextureImageUnits 32\n"
653 "MaxCombinedTextureImageUnits 80\n"
654 "MaxTextureImageUnits 32\n"
655 "MaxFragmentUniformComponents 4096\n"
656 "MaxDrawBuffers 32\n"
657 "MaxVertexUniformVectors 128\n"
658 "MaxVaryingVectors 8\n"
659 "MaxFragmentUniformVectors 16\n"
660 "MaxVertexOutputVectors 16\n"
661 "MaxFragmentInputVectors 15\n"
662 "MinProgramTexelOffset -8\n"
663 "MaxProgramTexelOffset 7\n"
664 "MaxClipDistances 8\n"
665 "MaxComputeWorkGroupCountX 65535\n"
666 "MaxComputeWorkGroupCountY 65535\n"
667 "MaxComputeWorkGroupCountZ 65535\n"
668 "MaxComputeWorkGroupSizeX 1024\n"
669 "MaxComputeWorkGroupSizeY 1024\n"
670 "MaxComputeWorkGroupSizeZ 64\n"
671 "MaxComputeUniformComponents 1024\n"
672 "MaxComputeTextureImageUnits 16\n"
673 "MaxComputeImageUniforms 8\n"
674 "MaxComputeAtomicCounters 8\n"
675 "MaxComputeAtomicCounterBuffers 1\n"
676 "MaxVaryingComponents 60\n"
677 "MaxVertexOutputComponents 64\n"
678 "MaxGeometryInputComponents 64\n"
679 "MaxGeometryOutputComponents 128\n"
680 "MaxFragmentInputComponents 128\n"
681 "MaxImageUnits 8\n"
682 "MaxCombinedImageUnitsAndFragmentOutputs 8\n"
683 "MaxCombinedShaderOutputResources 8\n"
684 "MaxImageSamples 0\n"
685 "MaxVertexImageUniforms 0\n"
686 "MaxTessControlImageUniforms 0\n"
687 "MaxTessEvaluationImageUniforms 0\n"
688 "MaxGeometryImageUniforms 0\n"
689 "MaxFragmentImageUniforms 8\n"
690 "MaxCombinedImageUniforms 8\n"
691 "MaxGeometryTextureImageUnits 16\n"
692 "MaxGeometryOutputVertices 256\n"
693 "MaxGeometryTotalOutputComponents 1024\n"
694 "MaxGeometryUniformComponents 1024\n"
695 "MaxGeometryVaryingComponents 64\n"
696 "MaxTessControlInputComponents 128\n"
697 "MaxTessControlOutputComponents 128\n"
698 "MaxTessControlTextureImageUnits 16\n"
699 "MaxTessControlUniformComponents 1024\n"
700 "MaxTessControlTotalOutputComponents 4096\n"
701 "MaxTessEvaluationInputComponents 128\n"
702 "MaxTessEvaluationOutputComponents 128\n"
703 "MaxTessEvaluationTextureImageUnits 16\n"
704 "MaxTessEvaluationUniformComponents 1024\n"
705 "MaxTessPatchComponents 120\n"
706 "MaxPatchVertices 32\n"
707 "MaxTessGenLevel 64\n"
708 "MaxViewports 16\n"
709 "MaxVertexAtomicCounters 0\n"
710 "MaxTessControlAtomicCounters 0\n"
711 "MaxTessEvaluationAtomicCounters 0\n"
712 "MaxGeometryAtomicCounters 0\n"
713 "MaxFragmentAtomicCounters 8\n"
714 "MaxCombinedAtomicCounters 8\n"
715 "MaxAtomicCounterBindings 1\n"
716 "MaxVertexAtomicCounterBuffers 0\n"
717 "MaxTessControlAtomicCounterBuffers 0\n"
718 "MaxTessEvaluationAtomicCounterBuffers 0\n"
719 "MaxGeometryAtomicCounterBuffers 0\n"
720 "MaxFragmentAtomicCounterBuffers 1\n"
721 "MaxCombinedAtomicCounterBuffers 1\n"
722 "MaxAtomicCounterBufferSize 16384\n"
723 "MaxTransformFeedbackBuffers 4\n"
724 "MaxTransformFeedbackInterleavedComponents 64\n"
725 "MaxCullDistances 8\n"
726 "MaxCombinedClipAndCullDistances 8\n"
727 "MaxSamples 4\n"
728
729 "nonInductiveForLoops 1\n"
730 "whileLoops 1\n"
731 "doWhileLoops 1\n"
732 "generalUniformIndexing 1\n"
733 "generalAttributeMatrixVectorIndexing 1\n"
734 "generalVaryingIndexing 1\n"
735 "generalSamplerIndexing 1\n"
736 "generalVariableIndexing 1\n"
737 "generalConstantMatrixVectorIndexing 1\n"
738 ;
739
740//
741// *.conf => this is a config file that can set limits/resources
742//
743bool XglTestFramework::SetConfigFile(const std::string& name)
744{
745 if (name.size() < 5)
746 return false;
747
748 if (name.compare(name.size() - 5, 5, ".conf") == 0) {
749 ConfigFile = name;
750 return true;
751 }
752
753 return false;
754}
755
756//
757// Parse either a .conf file provided by the user or the default string above.
758//
759void XglTestFramework::ProcessConfigFile()
760{
761 char** configStrings = 0;
762 char* config = 0;
763 if (ConfigFile.size() > 0) {
764 configStrings = ReadFileData(ConfigFile.c_str());
765 if (configStrings)
766 config = *configStrings;
767 else {
768 printf("Error opening configuration file; will instead use the default configuration\n");
769 }
770 }
771
772 if (config == 0) {
773 config = new char[strlen(DefaultConfig) + 1];
774 strcpy(config, DefaultConfig);
775 }
776
777 const char* delims = " \t\n\r";
778 const char* token = strtok(config, delims);
779 while (token) {
780 const char* valueStr = strtok(0, delims);
781 if (valueStr == 0 || ! (valueStr[0] == '-' || (valueStr[0] >= '0' && valueStr[0] <= '9'))) {
782 printf("Error: '%s' bad .conf file. Each name must be followed by one number.\n", valueStr ? valueStr : "");
783 return;
784 }
785 int value = atoi(valueStr);
786
787 if (strcmp(token, "MaxLights") == 0)
788 Resources.maxLights = value;
789 else if (strcmp(token, "MaxClipPlanes") == 0)
790 Resources.maxClipPlanes = value;
791 else if (strcmp(token, "MaxTextureUnits") == 0)
792 Resources.maxTextureUnits = value;
793 else if (strcmp(token, "MaxTextureCoords") == 0)
794 Resources.maxTextureCoords = value;
795 else if (strcmp(token, "MaxVertexAttribs") == 0)
796 Resources.maxVertexAttribs = value;
797 else if (strcmp(token, "MaxVertexUniformComponents") == 0)
798 Resources.maxVertexUniformComponents = value;
799 else if (strcmp(token, "MaxVaryingFloats") == 0)
800 Resources.maxVaryingFloats = value;
801 else if (strcmp(token, "MaxVertexTextureImageUnits") == 0)
802 Resources.maxVertexTextureImageUnits = value;
803 else if (strcmp(token, "MaxCombinedTextureImageUnits") == 0)
804 Resources.maxCombinedTextureImageUnits = value;
805 else if (strcmp(token, "MaxTextureImageUnits") == 0)
806 Resources.maxTextureImageUnits = value;
807 else if (strcmp(token, "MaxFragmentUniformComponents") == 0)
808 Resources.maxFragmentUniformComponents = value;
809 else if (strcmp(token, "MaxDrawBuffers") == 0)
810 Resources.maxDrawBuffers = value;
811 else if (strcmp(token, "MaxVertexUniformVectors") == 0)
812 Resources.maxVertexUniformVectors = value;
813 else if (strcmp(token, "MaxVaryingVectors") == 0)
814 Resources.maxVaryingVectors = value;
815 else if (strcmp(token, "MaxFragmentUniformVectors") == 0)
816 Resources.maxFragmentUniformVectors = value;
817 else if (strcmp(token, "MaxVertexOutputVectors") == 0)
818 Resources.maxVertexOutputVectors = value;
819 else if (strcmp(token, "MaxFragmentInputVectors") == 0)
820 Resources.maxFragmentInputVectors = value;
821 else if (strcmp(token, "MinProgramTexelOffset") == 0)
822 Resources.minProgramTexelOffset = value;
823 else if (strcmp(token, "MaxProgramTexelOffset") == 0)
824 Resources.maxProgramTexelOffset = value;
825 else if (strcmp(token, "MaxClipDistances") == 0)
826 Resources.maxClipDistances = value;
827 else if (strcmp(token, "MaxComputeWorkGroupCountX") == 0)
828 Resources.maxComputeWorkGroupCountX = value;
829 else if (strcmp(token, "MaxComputeWorkGroupCountY") == 0)
830 Resources.maxComputeWorkGroupCountY = value;
831 else if (strcmp(token, "MaxComputeWorkGroupCountZ") == 0)
832 Resources.maxComputeWorkGroupCountZ = value;
833 else if (strcmp(token, "MaxComputeWorkGroupSizeX") == 0)
834 Resources.maxComputeWorkGroupSizeX = value;
835 else if (strcmp(token, "MaxComputeWorkGroupSizeY") == 0)
836 Resources.maxComputeWorkGroupSizeY = value;
837 else if (strcmp(token, "MaxComputeWorkGroupSizeZ") == 0)
838 Resources.maxComputeWorkGroupSizeZ = value;
839 else if (strcmp(token, "MaxComputeUniformComponents") == 0)
840 Resources.maxComputeUniformComponents = value;
841 else if (strcmp(token, "MaxComputeTextureImageUnits") == 0)
842 Resources.maxComputeTextureImageUnits = value;
843 else if (strcmp(token, "MaxComputeImageUniforms") == 0)
844 Resources.maxComputeImageUniforms = value;
845 else if (strcmp(token, "MaxComputeAtomicCounters") == 0)
846 Resources.maxComputeAtomicCounters = value;
847 else if (strcmp(token, "MaxComputeAtomicCounterBuffers") == 0)
848 Resources.maxComputeAtomicCounterBuffers = value;
849 else if (strcmp(token, "MaxVaryingComponents") == 0)
850 Resources.maxVaryingComponents = value;
851 else if (strcmp(token, "MaxVertexOutputComponents") == 0)
852 Resources.maxVertexOutputComponents = value;
853 else if (strcmp(token, "MaxGeometryInputComponents") == 0)
854 Resources.maxGeometryInputComponents = value;
855 else if (strcmp(token, "MaxGeometryOutputComponents") == 0)
856 Resources.maxGeometryOutputComponents = value;
857 else if (strcmp(token, "MaxFragmentInputComponents") == 0)
858 Resources.maxFragmentInputComponents = value;
859 else if (strcmp(token, "MaxImageUnits") == 0)
860 Resources.maxImageUnits = value;
861 else if (strcmp(token, "MaxCombinedImageUnitsAndFragmentOutputs") == 0)
862 Resources.maxCombinedImageUnitsAndFragmentOutputs = value;
863 else if (strcmp(token, "MaxCombinedShaderOutputResources") == 0)
864 Resources.maxCombinedShaderOutputResources = value;
865 else if (strcmp(token, "MaxImageSamples") == 0)
866 Resources.maxImageSamples = value;
867 else if (strcmp(token, "MaxVertexImageUniforms") == 0)
868 Resources.maxVertexImageUniforms = value;
869 else if (strcmp(token, "MaxTessControlImageUniforms") == 0)
870 Resources.maxTessControlImageUniforms = value;
871 else if (strcmp(token, "MaxTessEvaluationImageUniforms") == 0)
872 Resources.maxTessEvaluationImageUniforms = value;
873 else if (strcmp(token, "MaxGeometryImageUniforms") == 0)
874 Resources.maxGeometryImageUniforms = value;
875 else if (strcmp(token, "MaxFragmentImageUniforms") == 0)
876 Resources.maxFragmentImageUniforms = value;
877 else if (strcmp(token, "MaxCombinedImageUniforms") == 0)
878 Resources.maxCombinedImageUniforms = value;
879 else if (strcmp(token, "MaxGeometryTextureImageUnits") == 0)
880 Resources.maxGeometryTextureImageUnits = value;
881 else if (strcmp(token, "MaxGeometryOutputVertices") == 0)
882 Resources.maxGeometryOutputVertices = value;
883 else if (strcmp(token, "MaxGeometryTotalOutputComponents") == 0)
884 Resources.maxGeometryTotalOutputComponents = value;
885 else if (strcmp(token, "MaxGeometryUniformComponents") == 0)
886 Resources.maxGeometryUniformComponents = value;
887 else if (strcmp(token, "MaxGeometryVaryingComponents") == 0)
888 Resources.maxGeometryVaryingComponents = value;
889 else if (strcmp(token, "MaxTessControlInputComponents") == 0)
890 Resources.maxTessControlInputComponents = value;
891 else if (strcmp(token, "MaxTessControlOutputComponents") == 0)
892 Resources.maxTessControlOutputComponents = value;
893 else if (strcmp(token, "MaxTessControlTextureImageUnits") == 0)
894 Resources.maxTessControlTextureImageUnits = value;
895 else if (strcmp(token, "MaxTessControlUniformComponents") == 0)
896 Resources.maxTessControlUniformComponents = value;
897 else if (strcmp(token, "MaxTessControlTotalOutputComponents") == 0)
898 Resources.maxTessControlTotalOutputComponents = value;
899 else if (strcmp(token, "MaxTessEvaluationInputComponents") == 0)
900 Resources.maxTessEvaluationInputComponents = value;
901 else if (strcmp(token, "MaxTessEvaluationOutputComponents") == 0)
902 Resources.maxTessEvaluationOutputComponents = value;
903 else if (strcmp(token, "MaxTessEvaluationTextureImageUnits") == 0)
904 Resources.maxTessEvaluationTextureImageUnits = value;
905 else if (strcmp(token, "MaxTessEvaluationUniformComponents") == 0)
906 Resources.maxTessEvaluationUniformComponents = value;
907 else if (strcmp(token, "MaxTessPatchComponents") == 0)
908 Resources.maxTessPatchComponents = value;
909 else if (strcmp(token, "MaxPatchVertices") == 0)
910 Resources.maxPatchVertices = value;
911 else if (strcmp(token, "MaxTessGenLevel") == 0)
912 Resources.maxTessGenLevel = value;
913 else if (strcmp(token, "MaxViewports") == 0)
914 Resources.maxViewports = value;
915 else if (strcmp(token, "MaxVertexAtomicCounters") == 0)
916 Resources.maxVertexAtomicCounters = value;
917 else if (strcmp(token, "MaxTessControlAtomicCounters") == 0)
918 Resources.maxTessControlAtomicCounters = value;
919 else if (strcmp(token, "MaxTessEvaluationAtomicCounters") == 0)
920 Resources.maxTessEvaluationAtomicCounters = value;
921 else if (strcmp(token, "MaxGeometryAtomicCounters") == 0)
922 Resources.maxGeometryAtomicCounters = value;
923 else if (strcmp(token, "MaxFragmentAtomicCounters") == 0)
924 Resources.maxFragmentAtomicCounters = value;
925 else if (strcmp(token, "MaxCombinedAtomicCounters") == 0)
926 Resources.maxCombinedAtomicCounters = value;
927 else if (strcmp(token, "MaxAtomicCounterBindings") == 0)
928 Resources.maxAtomicCounterBindings = value;
929 else if (strcmp(token, "MaxVertexAtomicCounterBuffers") == 0)
930 Resources.maxVertexAtomicCounterBuffers = value;
931 else if (strcmp(token, "MaxTessControlAtomicCounterBuffers") == 0)
932 Resources.maxTessControlAtomicCounterBuffers = value;
933 else if (strcmp(token, "MaxTessEvaluationAtomicCounterBuffers") == 0)
934 Resources.maxTessEvaluationAtomicCounterBuffers = value;
935 else if (strcmp(token, "MaxGeometryAtomicCounterBuffers") == 0)
936 Resources.maxGeometryAtomicCounterBuffers = value;
937 else if (strcmp(token, "MaxFragmentAtomicCounterBuffers") == 0)
938 Resources.maxFragmentAtomicCounterBuffers = value;
939 else if (strcmp(token, "MaxCombinedAtomicCounterBuffers") == 0)
940 Resources.maxCombinedAtomicCounterBuffers = value;
941 else if (strcmp(token, "MaxAtomicCounterBufferSize") == 0)
942 Resources.maxAtomicCounterBufferSize = value;
943 else if (strcmp(token, "MaxTransformFeedbackBuffers") == 0)
944 Resources.maxTransformFeedbackBuffers = value;
945 else if (strcmp(token, "MaxTransformFeedbackInterleavedComponents") == 0)
946 Resources.maxTransformFeedbackInterleavedComponents = value;
947 else if (strcmp(token, "MaxCullDistances") == 0)
948 Resources.maxCullDistances = value;
949 else if (strcmp(token, "MaxCombinedClipAndCullDistances") == 0)
950 Resources.maxCombinedClipAndCullDistances = value;
951 else if (strcmp(token, "MaxSamples") == 0)
952 Resources.maxSamples = value;
953
954 else if (strcmp(token, "nonInductiveForLoops") == 0)
955 Resources.limits.nonInductiveForLoops = (value != 0);
956 else if (strcmp(token, "whileLoops") == 0)
957 Resources.limits.whileLoops = (value != 0);
958 else if (strcmp(token, "doWhileLoops") == 0)
959 Resources.limits.doWhileLoops = (value != 0);
960 else if (strcmp(token, "generalUniformIndexing") == 0)
961 Resources.limits.generalUniformIndexing = (value != 0);
962 else if (strcmp(token, "generalAttributeMatrixVectorIndexing") == 0)
963 Resources.limits.generalAttributeMatrixVectorIndexing = (value != 0);
964 else if (strcmp(token, "generalVaryingIndexing") == 0)
965 Resources.limits.generalVaryingIndexing = (value != 0);
966 else if (strcmp(token, "generalSamplerIndexing") == 0)
967 Resources.limits.generalSamplerIndexing = (value != 0);
968 else if (strcmp(token, "generalVariableIndexing") == 0)
969 Resources.limits.generalVariableIndexing = (value != 0);
970 else if (strcmp(token, "generalConstantMatrixVectorIndexing") == 0)
971 Resources.limits.generalConstantMatrixVectorIndexing = (value != 0);
972 else
973 printf("Warning: unrecognized limit (%s) in configuration file.\n", token);
974
975 token = strtok(0, delims);
976 }
977 if (configStrings)
978 FreeFileData(configStrings);
979}
980
981void XglTestFramework::SetMessageOptions(EShMessages& messages)
982{
983 if (m_compile_options & EOptionRelaxedErrors)
984 messages = (EShMessages)(messages | EShMsgRelaxedErrors);
985 if (m_compile_options & EOptionIntermediate)
986 messages = (EShMessages)(messages | EShMsgAST);
987 if (m_compile_options & EOptionSuppressWarnings)
988 messages = (EShMessages)(messages | EShMsgSuppressWarnings);
989}
990
991//
992// Malloc a string of sufficient size and read a string into it.
993//
994char** XglTestFramework::ReadFileData(const char* fileName)
995{
996 FILE *in;
997 #if defined(_WIN32) && defined(__GNUC__)
998 in = fopen(fileName, "r");
999 int errorCode = in ? 0 : 1;
1000 #else
1001 int errorCode = fopen_s(&in, fileName, "r");
1002 #endif
1003
1004 char *fdata;
1005 int count = 0;
1006 const int maxSourceStrings = 5;
1007 char** return_data = (char**)malloc(sizeof(char *) * (maxSourceStrings+1));
1008
1009 if (errorCode) {
1010 printf("Error: unable to open input file: %s\n", fileName);
1011 return 0;
1012 }
1013
1014 while (fgetc(in) != EOF)
1015 count++;
1016
1017 fseek(in, 0, SEEK_SET);
1018
1019 if (!(fdata = (char*)malloc(count+2))) {
1020 printf("Error allocating memory\n");
1021 return 0;
1022 }
1023 if (fread(fdata,1,count, in)!=count) {
1024 printf("Error reading input file: %s\n", fileName);
1025 return 0;
1026 }
1027 fdata[count] = '\0';
1028 fclose(in);
1029 if (count == 0) {
1030 return_data[0]=(char*)malloc(count+2);
1031 return_data[0][0]='\0';
1032 m_num_shader_strings = 0;
1033 return return_data;
1034 } else
1035 m_num_shader_strings = 1;
1036
1037 int len = (int)(ceil)((float)count/(float)m_num_shader_strings);
1038 int ptr_len=0,i=0;
1039 while(count>0){
1040 return_data[i]=(char*)malloc(len+2);
1041 memcpy(return_data[i],fdata+ptr_len,len);
1042 return_data[i][len]='\0';
1043 count-=(len);
1044 ptr_len+=(len);
1045 if(count<len){
1046 if(count==0){
1047 m_num_shader_strings=(i+1);
1048 break;
1049 }
1050 len = count;
1051 }
1052 ++i;
1053 }
1054 return return_data;
1055}
1056
1057void XglTestFramework::FreeFileData(char** data)
1058{
1059 for(int i=0;i<m_num_shader_strings;i++)
1060 free(data[i]);
1061}
1062
1063//
1064// Deduce the language from the filename. Files must end in one of the
1065// following extensions:
1066//
1067// .vert = vertex
1068// .tesc = tessellation control
1069// .tese = tessellation evaluation
1070// .geom = geometry
1071// .frag = fragment
1072// .comp = compute
1073//
1074EShLanguage XglTestFramework::FindLanguage(const std::string& name)
1075{
1076 size_t ext = name.rfind('.');
1077 if (ext == std::string::npos) {
1078 return EShLangVertex;
1079 }
1080
1081 std::string suffix = name.substr(ext + 1, std::string::npos);
1082 if (suffix == "vert")
1083 return EShLangVertex;
1084 else if (suffix == "tesc")
1085 return EShLangTessControl;
1086 else if (suffix == "tese")
1087 return EShLangTessEvaluation;
1088 else if (suffix == "geom")
1089 return EShLangGeometry;
1090 else if (suffix == "frag")
1091 return EShLangFragment;
1092 else if (suffix == "comp")
1093 return EShLangCompute;
1094
1095 return EShLangVertex;
1096}
1097
1098//
1099// Convert XGL shader type to compiler's
1100//
1101EShLanguage XglTestFramework::FindLanguage(const XGL_PIPELINE_SHADER_STAGE shader_type)
1102{
1103 switch (shader_type) {
1104 case XGL_SHADER_STAGE_VERTEX:
1105 return EShLangVertex;
1106
1107 case XGL_SHADER_STAGE_TESS_CONTROL:
1108 return EShLangTessControl;
1109
1110 case XGL_SHADER_STAGE_TESS_EVALUATION:
1111 return EShLangTessEvaluation;
1112
1113 case XGL_SHADER_STAGE_GEOMETRY:
1114 return EShLangGeometry;
1115
1116 case XGL_SHADER_STAGE_FRAGMENT:
1117 return EShLangFragment;
1118
1119 case XGL_SHADER_STAGE_COMPUTE:
1120 return EShLangCompute;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001121
Chia-I Wub4c2aa42014-12-15 23:50:11 +08001122 default:
1123 return EShLangVertex;
1124 }
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001125}
1126
1127
1128//
1129// Compile a given string containing GLSL into BIL for use by XGL
1130// Return value of false means an error was encountered.
1131//
1132bool XglTestFramework::GLSLtoBIL(const XGL_PIPELINE_SHADER_STAGE shader_type,
1133 const char *pshader,
1134 std::vector<unsigned int> &bil)
1135{
1136 glslang::TProgram& program = *new glslang::TProgram;
1137 const char *shaderStrings[1];
1138
1139 // TODO: Do we want to load a special config file depending on the
1140 // shader source? Optional name maybe?
1141 // SetConfigFile(fileName);
1142
1143 ProcessConfigFile();
1144
1145 EShMessages messages = EShMsgDefault;
1146 SetMessageOptions(messages);
1147
1148 EShLanguage stage = FindLanguage(shader_type);
1149 glslang::TShader* shader = new glslang::TShader(stage);
1150
1151 shaderStrings[0] = pshader;
1152 shader->setStrings(shaderStrings, 1);
1153
1154 if (! shader->parse(&Resources, (m_compile_options & EOptionDefaultDesktop) ? 110 : 100, false, messages)) {
1155
Cody Northrop195d6622014-11-03 12:54:37 -07001156 if (! (m_compile_options & EOptionSuppressInfolog)) {
1157 puts(shader->getInfoLog());
1158 puts(shader->getInfoDebugLog());
1159 }
1160
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001161 return false; // something didn't work
1162 }
1163
1164 program.addShader(shader);
1165
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001166
1167 //
1168 // Program-level processing...
1169 //
1170
Cody Northrop195d6622014-11-03 12:54:37 -07001171 if (! program.link(messages)) {
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001172
Cody Northrop195d6622014-11-03 12:54:37 -07001173 if (! (m_compile_options & EOptionSuppressInfolog)) {
1174 puts(shader->getInfoLog());
1175 puts(shader->getInfoDebugLog());
1176 }
1177
1178 return false;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001179 }
1180
1181 if (m_compile_options & EOptionDumpReflection) {
1182 program.buildReflection();
1183 program.dumpReflection();
1184 }
1185
1186 glslang::GlslangToBil(*program.getIntermediate(stage), bil);
1187
1188 return true;
1189}
1190
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001191
1192
1193XglTestImageRecord::XglTestImageRecord() : // Constructor
1194 m_width( 0 ),
1195 m_height( 0 ),
Chia-I Wu837f9952014-12-15 23:29:34 +08001196 m_data( NULL ),
Tony Barbour96db8822015-02-25 12:28:39 -07001197 m_presentableImage( NULL ),
1198 m_presentableMemory( NULL),
Chia-I Wu837f9952014-12-15 23:29:34 +08001199 m_data_size( 0 )
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001200{
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001201}
1202
1203XglTestImageRecord::~XglTestImageRecord()
1204{
1205
1206}
1207
1208XglTestImageRecord::XglTestImageRecord(const XglTestImageRecord &copyin) // Copy constructor to handle pass by value.
1209{
1210 m_title = copyin.m_title;
1211 m_width = copyin.m_width;
1212 m_height = copyin.m_height;
1213 m_data_size = copyin.m_data_size;
1214 m_data = copyin.m_data; // TODO: Do we need to copy the data or is pointer okay?
Tony Barbour96db8822015-02-25 12:28:39 -07001215 m_presentableImage = copyin.m_presentableImage;
1216 m_presentableMemory = copyin.m_presentableMemory;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001217}
1218
1219ostream &operator<<(ostream &output, const XglTestImageRecord &XglTestImageRecord)
1220{
1221 output << XglTestImageRecord.m_title << " (" << XglTestImageRecord.m_width <<
1222 "," << XglTestImageRecord.m_height << ")" << endl;
1223 return output;
1224}
1225
1226XglTestImageRecord& XglTestImageRecord::operator=(const XglTestImageRecord &rhs)
1227{
1228 m_title = rhs.m_title;
1229 m_width = rhs.m_width;
1230 m_height = rhs.m_height;
1231 m_data_size = rhs.m_data_size;
1232 m_data = rhs.m_data;
Tony Barbour96db8822015-02-25 12:28:39 -07001233 m_presentableImage = rhs.m_presentableImage;
1234 m_presentableMemory = rhs.m_presentableMemory;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001235 return *this;
1236}
1237
1238int XglTestImageRecord::operator==(const XglTestImageRecord &rhs) const
1239{
1240 if( this->m_data != rhs.m_data) return 0;
1241 return 1;
1242}
1243
1244// This function is required for built-in STL list functions like sort
1245int XglTestImageRecord::operator<(const XglTestImageRecord &rhs) const
1246{
1247 if( this->m_data_size < rhs.m_data_size ) return 1;
1248 return 0;
1249}
1250