blob: fa648a3d91fe3533abe153d0549058b08607532f [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++) {
217 const char *row = ptr;
218
219 for (x = 0; x < image->width(); x++) {
220 file.write(row, 3);
221 row += 4;
222 }
223
224 ptr += sr_layout.rowPitch;
225 }
226
227 file.close();
228
229 err = xglUnmapMemory( image->memory() );
230 ASSERT_XGL_SUCCESS( err );
231}
232
Tony Barbour247bf372014-10-30 14:29:04 -0600233void XglTestFramework::Compare(const char *basename, XglImage *image )
234{
235
236 MagickWand *magick_wand_1;
237 MagickWand *magick_wand_2;
238 MagickWand *compare_wand;
239 MagickBooleanType status;
Tony Barbour4ab45422014-12-10 17:00:20 -0700240 char testimage[256],golden[PATH_MAX+256],golddir[PATH_MAX] = "./golden";
Tony Barbour247bf372014-10-30 14:29:04 -0600241 double differenz;
242
Tony Barbour4ab45422014-12-10 17:00:20 -0700243 if (getenv("RENDERTEST_GOLDEN_DIR"))
244 {
245 strcpy(golddir,getenv("RENDERTEST_GOLDEN_DIR"));
246 }
247
Tony Barbour247bf372014-10-30 14:29:04 -0600248 MagickWandGenesis();
249 magick_wand_1=NewMagickWand();
250 sprintf(testimage,"%s.ppm",basename);
251 status=MagickReadImage(magick_wand_1,testimage);
252 ASSERT_TRUE(status) << "Unable to open file: " << testimage;
253
254
255 MagickWandGenesis();
256 magick_wand_2=NewMagickWand();
Tony Barbour4ab45422014-12-10 17:00:20 -0700257 sprintf(golden,"%s/%s.ppm",golddir,basename);
Tony Barbour247bf372014-10-30 14:29:04 -0600258 status=MagickReadImage(magick_wand_2,golden);
259 ASSERT_TRUE(status) << "Unable to open file: " << golden;
260
Tony Barbour247bf372014-10-30 14:29:04 -0600261 compare_wand=MagickCompareImages(magick_wand_1,magick_wand_2, MeanAbsoluteErrorMetric, &differenz);
262 if (differenz != 0.0)
263 {
264 char difference[256];
265
266 sprintf(difference,"%s-diff.ppm",basename);
267 status = MagickWriteImage(compare_wand, difference);
268 ASSERT_TRUE(differenz == 0.0) << "Image comparison failed - diff file written";
269 }
270 DestroyMagickWand(compare_wand);
271
272 DestroyMagickWand(magick_wand_1);
273 DestroyMagickWand(magick_wand_2);
274 MagickWandTerminus();
Courtney Goeltzenleuchterfcda72d2014-12-05 15:41:02 -0700275
276 if (differenz == 0.0)
277 {
278 /*
279 * If test image and golden image match, we do not need to
280 * keep around the test image.
281 */
282 remove(testimage);
283 }
Tony Barbour247bf372014-10-30 14:29:04 -0600284}
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600285
286void XglTestFramework::Show(const char *comment, XglImage *image)
287{
288 XGL_RESULT err;
289
290 const XGL_IMAGE_SUBRESOURCE sr = {
291 XGL_IMAGE_ASPECT_COLOR, 0, 0
292 };
293 XGL_SUBRESOURCE_LAYOUT sr_layout;
Chia-I Wu99ff89d2014-12-27 14:14:50 +0800294 size_t data_size = sizeof(sr_layout);
Tony Barbour96db8822015-02-25 12:28:39 -0700295 XglTestImageRecord record;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600296
297 if (!m_show_images) return;
298
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600299 err = xglGetImageSubresourceInfo( image->image(), &sr, XGL_INFO_TYPE_SUBRESOURCE_LAYOUT,
300 &data_size, &sr_layout);
301 ASSERT_XGL_SUCCESS( err );
302 ASSERT_EQ(data_size, sizeof(sr_layout));
303
Tony Barbour96db8822015-02-25 12:28:39 -0700304 char *ptr;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600305
Mark Lobodzinski17caf572015-01-29 08:55:56 -0600306 err = image->MapMemory( (void **) &ptr );
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600307 ASSERT_XGL_SUCCESS( err );
308
309 ptr += sr_layout.offset;
310
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600311 record.m_title.append(comment);
312 record.m_width = image->width();
313 record.m_height = image->height();
314 // TODO: Need to make this more robust to handle different image formats
315 record.m_data_size = image->width()*image->height()*4;
316 record.m_data = malloc(record.m_data_size);
317 memcpy(record.m_data, ptr, record.m_data_size);
318 m_images.push_back(record);
319 m_display_image = --m_images.end();
320
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600321 err = image->UnmapMemory();
322 ASSERT_XGL_SUCCESS( err );
Tony Barbour96db8822015-02-25 12:28:39 -0700323
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600324}
325
Tony Barbour247bf372014-10-30 14:29:04 -0600326void XglTestFramework::RecordImage(XglImage *image, char *tag)
327{
328 const ::testing::TestInfo* const test_info =
329 ::testing::UnitTest::GetInstance()->current_test_info();
330 ostringstream filestream;
331 string filename;
332
333 filestream << test_info->name() << "-" << tag;
334 filename = filestream.str();
335 // ToDo - scrub string for bad characters
336
337 if (m_save_images || m_compare_images) {
338 WritePPM(filename.c_str(), image);
339 if (m_compare_images) {
340 Compare(filename.c_str(), image);
341 }
342 }
343
344 if (m_show_images) {
345 Show(test_info->name(), image);
346 }
347}
348
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600349void XglTestFramework::RecordImage(XglImage *image)
350{
351 const ::testing::TestInfo* const test_info =
352 ::testing::UnitTest::GetInstance()->current_test_info();
Tony Barbour247bf372014-10-30 14:29:04 -0600353 ostringstream filestream;
354 string filename;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600355
Tony Barbour247bf372014-10-30 14:29:04 -0600356 m_width = 40;
357
358 if (strcmp(test_info->name(), m_testName.c_str())) {
359 filestream << test_info->name();
360 m_testName.assign(test_info->name());
Tony Barboura0e2ee82014-11-18 17:02:36 -0700361 m_frameNum = 2;
362 filename = filestream.str();
Tony Barbour247bf372014-10-30 14:29:04 -0600363 }
364 else {
365 filestream << test_info->name() << "-" << m_frameNum;
366 m_frameNum++;
Tony Barboura0e2ee82014-11-18 17:02:36 -0700367 filename = filestream.str();
Tony Barbour247bf372014-10-30 14:29:04 -0600368 }
369
370
371 // ToDo - scrub string for bad characters
372
373 if (m_save_images || m_compare_images) {
374 WritePPM(filename.c_str(), image);
375 if (m_compare_images) {
376 Compare(filename.c_str(), image);
377 }
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600378 }
379
380 if (m_show_images) {
Courtney Goeltzenleuchter02d33c12014-10-08 14:26:40 -0600381 Show(test_info->name(), image);
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600382 }
383}
384
Tony Barbour96db8822015-02-25 12:28:39 -0700385static xgl_testing::Environment *environment;
386
387TestFrameworkXglPresent::TestFrameworkXglPresent() :
388m_device(environment->default_device()),
389m_queue(*m_device.graphics_queues()[0]),
390m_cmdbuf(m_device, xgl_testing::CmdBuffer::create_info(XGL_QUEUE_TYPE_GRAPHICS))
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600391{
Tony Barbour96db8822015-02-25 12:28:39 -0700392 m_quit = false;
393 m_pause = false;
394 m_width = 0;
395 m_height = 0;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600396}
397
Tony Barbour96db8822015-02-25 12:28:39 -0700398void TestFrameworkXglPresent::Display()
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600399{
Tony Barbour96db8822015-02-25 12:28:39 -0700400 XGL_RESULT err;
401
402 XGL_WSI_X11_PRESENT_INFO present = {
403 .destWindow = m_window,
404 .srcImage = m_display_image->m_presentableImage,
405 };
406
407 xcb_change_property (environment->m_connection,
408 XCB_PROP_MODE_REPLACE,
409 m_window,
410 XCB_ATOM_WM_NAME,
411 XCB_ATOM_STRING,
412 8,
413 m_display_image->m_title.size(),
414 m_display_image->m_title.c_str());
415
416 err = xglWsiX11QueuePresent(m_queue.obj(), &present, NULL);
417 assert(!err);
418
419 m_queue.wait();
420
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600421}
422
Tony Barbour96db8822015-02-25 12:28:39 -0700423void TestFrameworkXglPresent::HandleEvent(xcb_generic_event_t *event)
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600424{
Tony Barbour96db8822015-02-25 12:28:39 -0700425 u_int8_t event_code = event->response_type & 0x7f;
426 switch (event_code) {
427 case XCB_EXPOSE:
428 Display(); // TODO: handle resize
429 break;
430 case XCB_CLIENT_MESSAGE:
431 if((*(xcb_client_message_event_t*)event).data.data32[0] ==
432 (m_atom_wm_delete_window)->atom) {
433 m_quit = true;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600434 }
435 break;
Tony Barbour96db8822015-02-25 12:28:39 -0700436 case XCB_KEY_RELEASE:
437 {
438 const xcb_key_release_event_t *key =
439 (const xcb_key_release_event_t *) event;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600440
Tony Barbour96db8822015-02-25 12:28:39 -0700441 switch (key->detail) {
442 case 0x9: // Escape
443 m_quit = true;
444 break;
445 case 0x71: // left arrow key
446 if (m_display_image == m_images.begin()) {
447 m_display_image = --m_images.end();
448 } else {
449 --m_display_image;
450 }
451 break;
452 case 0x72: // right arrow key
453 ++m_display_image;
454 if (m_display_image == m_images.end()) {
455 m_display_image = m_images.begin();
456 }
457 break;
458 case 0x41:
459 m_pause = !m_pause;
460 break;
461 }
462 Display();
463 }
464 break;
465 default:
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600466 break;
467 }
Tony Barbour96db8822015-02-25 12:28:39 -0700468}
469
470void TestFrameworkXglPresent::Run()
471{
472 xcb_flush(environment->m_connection);
473
474 while (! m_quit) {
475 xcb_generic_event_t *event;
476
477 if (m_pause) {
478 event = xcb_wait_for_event(environment->m_connection);
479 } else {
480 event = xcb_poll_for_event(environment->m_connection);
481 }
482 if (event) {
483 HandleEvent(event);
484 free(event);
485 }
486 }
487}
488
489void TestFrameworkXglPresent::CreatePresentableImages()
490{
491 XGL_RESULT err;
492
493 m_display_image = m_images.begin();
494
495 for (int x=0; x < m_images.size(); x++)
496 {
497 const XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO presentable_image_info = {
498 .format = XGL_FMT_B8G8R8A8_UNORM,
499 .usage = XGL_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
500 .extent = {
501 .width = m_display_image->m_width,
502 .height = m_display_image->m_height,
503 },
504 .flags = 0,
505 };
506
507 void *dest_ptr;
508
509 err = xglWsiX11CreatePresentableImage(m_device.obj(), &presentable_image_info,
510 &m_display_image->m_presentableImage, &m_display_image->m_presentableMemory);
511 assert(!err);
512
513 xgl_testing::Buffer buf;
514 buf.init(m_device, (XGL_GPU_SIZE) m_display_image->m_data_size);
515 dest_ptr = buf.map();
516 memcpy(dest_ptr,m_display_image->m_data, m_display_image->m_data_size);
517 buf.unmap();
518
519 m_cmdbuf.begin();
520
521 XGL_BUFFER_IMAGE_COPY region = {};
522 region.imageExtent.height = m_display_image->m_height;
523 region.imageExtent.width = m_display_image->m_width;
524 region.imageExtent.depth = 1;
525
526 xglCmdCopyBufferToImage(m_cmdbuf.obj(), buf.obj(), m_display_image->m_presentableImage, 1, &region);
527 m_cmdbuf.end();
528
529 uint32_t numMemRefs=2;
530 XGL_MEMORY_REF memRefs[2];
531 memRefs[0].flags = 0;
532 memRefs[0].mem = m_display_image->m_presentableMemory;
533 memRefs[1].flags = 0;
534 memRefs[1].mem = buf.memories()[0];
535
536 XGL_CMD_BUFFER cmdBufs[1];
537 cmdBufs[0] = m_cmdbuf.obj();
538
539 xglQueueSubmit(m_queue.obj(), 1, cmdBufs, numMemRefs, memRefs, NULL);
540 m_queue.wait();
541
542
543 if (m_display_image->m_width > m_width)
544 m_width = m_display_image->m_width;
545
546 if (m_display_image->m_height > m_height)
547 m_height = m_display_image->m_height;
548
549
550 ++m_display_image;
551
552 }
553
554 m_display_image = m_images.begin();
555}
556
557void TestFrameworkXglPresent::InitPresentFramework(std::list<XglTestImageRecord> &imagesIn)
558{
559 m_images = imagesIn;
560}
561
562void TestFrameworkXglPresent::CreateWindow()
563{
564 uint32_t value_mask, value_list[32];
565
566 m_window = xcb_generate_id(environment->m_connection);
567
568 value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
569 value_list[0] = environment->m_screen->black_pixel;
570 value_list[1] = XCB_EVENT_MASK_KEY_RELEASE |
571 XCB_EVENT_MASK_EXPOSURE |
572 XCB_EVENT_MASK_STRUCTURE_NOTIFY;
573
574 xcb_create_window(environment->m_connection,
575 XCB_COPY_FROM_PARENT,
576 m_window, environment->m_screen->root,
577 0, 0, m_width, m_height, 0,
578 XCB_WINDOW_CLASS_INPUT_OUTPUT,
579 environment->m_screen->root_visual,
580 value_mask, value_list);
581
582 /* Magic code that will send notification when window is destroyed */
583 xcb_intern_atom_cookie_t cookie = xcb_intern_atom(environment->m_connection, 1, 12,
584 "WM_PROTOCOLS");
585 xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(environment->m_connection, cookie, 0);
586
587 xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(environment->m_connection, 0, 16, "WM_DELETE_WINDOW");
588 m_atom_wm_delete_window = xcb_intern_atom_reply(environment->m_connection, cookie2, 0);
589
590 xcb_change_property(environment->m_connection, XCB_PROP_MODE_REPLACE,
591 m_window, (*reply).atom, 4, 32, 1,
592 &(*m_atom_wm_delete_window).atom);
593 free(reply);
594
595 xcb_map_window(environment->m_connection, m_window);
596}
597
598void TestFrameworkXglPresent::TearDown()
599{
600 xcb_destroy_window(environment->m_connection, m_window);
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600601}
602
603void XglTestFramework::Finish()
604{
605 if (m_images.size() == 0) return;
606
Tony Barbour96db8822015-02-25 12:28:39 -0700607 environment = new xgl_testing::Environment();
608 ::testing::AddGlobalTestEnvironment(environment);
609 environment->X11SetUp();
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600610
Tony Barbour96db8822015-02-25 12:28:39 -0700611 {
612 TestFrameworkXglPresent xglPresent;
613
614 xglPresent.InitPresentFramework(m_images);
615 xglPresent.CreatePresentableImages();
616 xglPresent.CreateWindow();
617 xglPresent.Run();
618 xglPresent.TearDown();
619 }
620 environment->TearDown();
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600621}
622
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600623//
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600624// These are the default resources for TBuiltInResources, used for both
625// - parsing this string for the case where the user didn't supply one
626// - dumping out a template for user construction of a config file
627//
628static const char* DefaultConfig =
629 "MaxLights 32\n"
630 "MaxClipPlanes 6\n"
631 "MaxTextureUnits 32\n"
632 "MaxTextureCoords 32\n"
633 "MaxVertexAttribs 64\n"
634 "MaxVertexUniformComponents 4096\n"
635 "MaxVaryingFloats 64\n"
636 "MaxVertexTextureImageUnits 32\n"
637 "MaxCombinedTextureImageUnits 80\n"
638 "MaxTextureImageUnits 32\n"
639 "MaxFragmentUniformComponents 4096\n"
640 "MaxDrawBuffers 32\n"
641 "MaxVertexUniformVectors 128\n"
642 "MaxVaryingVectors 8\n"
643 "MaxFragmentUniformVectors 16\n"
644 "MaxVertexOutputVectors 16\n"
645 "MaxFragmentInputVectors 15\n"
646 "MinProgramTexelOffset -8\n"
647 "MaxProgramTexelOffset 7\n"
648 "MaxClipDistances 8\n"
649 "MaxComputeWorkGroupCountX 65535\n"
650 "MaxComputeWorkGroupCountY 65535\n"
651 "MaxComputeWorkGroupCountZ 65535\n"
652 "MaxComputeWorkGroupSizeX 1024\n"
653 "MaxComputeWorkGroupSizeY 1024\n"
654 "MaxComputeWorkGroupSizeZ 64\n"
655 "MaxComputeUniformComponents 1024\n"
656 "MaxComputeTextureImageUnits 16\n"
657 "MaxComputeImageUniforms 8\n"
658 "MaxComputeAtomicCounters 8\n"
659 "MaxComputeAtomicCounterBuffers 1\n"
660 "MaxVaryingComponents 60\n"
661 "MaxVertexOutputComponents 64\n"
662 "MaxGeometryInputComponents 64\n"
663 "MaxGeometryOutputComponents 128\n"
664 "MaxFragmentInputComponents 128\n"
665 "MaxImageUnits 8\n"
666 "MaxCombinedImageUnitsAndFragmentOutputs 8\n"
667 "MaxCombinedShaderOutputResources 8\n"
668 "MaxImageSamples 0\n"
669 "MaxVertexImageUniforms 0\n"
670 "MaxTessControlImageUniforms 0\n"
671 "MaxTessEvaluationImageUniforms 0\n"
672 "MaxGeometryImageUniforms 0\n"
673 "MaxFragmentImageUniforms 8\n"
674 "MaxCombinedImageUniforms 8\n"
675 "MaxGeometryTextureImageUnits 16\n"
676 "MaxGeometryOutputVertices 256\n"
677 "MaxGeometryTotalOutputComponents 1024\n"
678 "MaxGeometryUniformComponents 1024\n"
679 "MaxGeometryVaryingComponents 64\n"
680 "MaxTessControlInputComponents 128\n"
681 "MaxTessControlOutputComponents 128\n"
682 "MaxTessControlTextureImageUnits 16\n"
683 "MaxTessControlUniformComponents 1024\n"
684 "MaxTessControlTotalOutputComponents 4096\n"
685 "MaxTessEvaluationInputComponents 128\n"
686 "MaxTessEvaluationOutputComponents 128\n"
687 "MaxTessEvaluationTextureImageUnits 16\n"
688 "MaxTessEvaluationUniformComponents 1024\n"
689 "MaxTessPatchComponents 120\n"
690 "MaxPatchVertices 32\n"
691 "MaxTessGenLevel 64\n"
692 "MaxViewports 16\n"
693 "MaxVertexAtomicCounters 0\n"
694 "MaxTessControlAtomicCounters 0\n"
695 "MaxTessEvaluationAtomicCounters 0\n"
696 "MaxGeometryAtomicCounters 0\n"
697 "MaxFragmentAtomicCounters 8\n"
698 "MaxCombinedAtomicCounters 8\n"
699 "MaxAtomicCounterBindings 1\n"
700 "MaxVertexAtomicCounterBuffers 0\n"
701 "MaxTessControlAtomicCounterBuffers 0\n"
702 "MaxTessEvaluationAtomicCounterBuffers 0\n"
703 "MaxGeometryAtomicCounterBuffers 0\n"
704 "MaxFragmentAtomicCounterBuffers 1\n"
705 "MaxCombinedAtomicCounterBuffers 1\n"
706 "MaxAtomicCounterBufferSize 16384\n"
707 "MaxTransformFeedbackBuffers 4\n"
708 "MaxTransformFeedbackInterleavedComponents 64\n"
709 "MaxCullDistances 8\n"
710 "MaxCombinedClipAndCullDistances 8\n"
711 "MaxSamples 4\n"
712
713 "nonInductiveForLoops 1\n"
714 "whileLoops 1\n"
715 "doWhileLoops 1\n"
716 "generalUniformIndexing 1\n"
717 "generalAttributeMatrixVectorIndexing 1\n"
718 "generalVaryingIndexing 1\n"
719 "generalSamplerIndexing 1\n"
720 "generalVariableIndexing 1\n"
721 "generalConstantMatrixVectorIndexing 1\n"
722 ;
723
724//
725// *.conf => this is a config file that can set limits/resources
726//
727bool XglTestFramework::SetConfigFile(const std::string& name)
728{
729 if (name.size() < 5)
730 return false;
731
732 if (name.compare(name.size() - 5, 5, ".conf") == 0) {
733 ConfigFile = name;
734 return true;
735 }
736
737 return false;
738}
739
740//
741// Parse either a .conf file provided by the user or the default string above.
742//
743void XglTestFramework::ProcessConfigFile()
744{
745 char** configStrings = 0;
746 char* config = 0;
747 if (ConfigFile.size() > 0) {
748 configStrings = ReadFileData(ConfigFile.c_str());
749 if (configStrings)
750 config = *configStrings;
751 else {
752 printf("Error opening configuration file; will instead use the default configuration\n");
753 }
754 }
755
756 if (config == 0) {
757 config = new char[strlen(DefaultConfig) + 1];
758 strcpy(config, DefaultConfig);
759 }
760
761 const char* delims = " \t\n\r";
762 const char* token = strtok(config, delims);
763 while (token) {
764 const char* valueStr = strtok(0, delims);
765 if (valueStr == 0 || ! (valueStr[0] == '-' || (valueStr[0] >= '0' && valueStr[0] <= '9'))) {
766 printf("Error: '%s' bad .conf file. Each name must be followed by one number.\n", valueStr ? valueStr : "");
767 return;
768 }
769 int value = atoi(valueStr);
770
771 if (strcmp(token, "MaxLights") == 0)
772 Resources.maxLights = value;
773 else if (strcmp(token, "MaxClipPlanes") == 0)
774 Resources.maxClipPlanes = value;
775 else if (strcmp(token, "MaxTextureUnits") == 0)
776 Resources.maxTextureUnits = value;
777 else if (strcmp(token, "MaxTextureCoords") == 0)
778 Resources.maxTextureCoords = value;
779 else if (strcmp(token, "MaxVertexAttribs") == 0)
780 Resources.maxVertexAttribs = value;
781 else if (strcmp(token, "MaxVertexUniformComponents") == 0)
782 Resources.maxVertexUniformComponents = value;
783 else if (strcmp(token, "MaxVaryingFloats") == 0)
784 Resources.maxVaryingFloats = value;
785 else if (strcmp(token, "MaxVertexTextureImageUnits") == 0)
786 Resources.maxVertexTextureImageUnits = value;
787 else if (strcmp(token, "MaxCombinedTextureImageUnits") == 0)
788 Resources.maxCombinedTextureImageUnits = value;
789 else if (strcmp(token, "MaxTextureImageUnits") == 0)
790 Resources.maxTextureImageUnits = value;
791 else if (strcmp(token, "MaxFragmentUniformComponents") == 0)
792 Resources.maxFragmentUniformComponents = value;
793 else if (strcmp(token, "MaxDrawBuffers") == 0)
794 Resources.maxDrawBuffers = value;
795 else if (strcmp(token, "MaxVertexUniformVectors") == 0)
796 Resources.maxVertexUniformVectors = value;
797 else if (strcmp(token, "MaxVaryingVectors") == 0)
798 Resources.maxVaryingVectors = value;
799 else if (strcmp(token, "MaxFragmentUniformVectors") == 0)
800 Resources.maxFragmentUniformVectors = value;
801 else if (strcmp(token, "MaxVertexOutputVectors") == 0)
802 Resources.maxVertexOutputVectors = value;
803 else if (strcmp(token, "MaxFragmentInputVectors") == 0)
804 Resources.maxFragmentInputVectors = value;
805 else if (strcmp(token, "MinProgramTexelOffset") == 0)
806 Resources.minProgramTexelOffset = value;
807 else if (strcmp(token, "MaxProgramTexelOffset") == 0)
808 Resources.maxProgramTexelOffset = value;
809 else if (strcmp(token, "MaxClipDistances") == 0)
810 Resources.maxClipDistances = value;
811 else if (strcmp(token, "MaxComputeWorkGroupCountX") == 0)
812 Resources.maxComputeWorkGroupCountX = value;
813 else if (strcmp(token, "MaxComputeWorkGroupCountY") == 0)
814 Resources.maxComputeWorkGroupCountY = value;
815 else if (strcmp(token, "MaxComputeWorkGroupCountZ") == 0)
816 Resources.maxComputeWorkGroupCountZ = value;
817 else if (strcmp(token, "MaxComputeWorkGroupSizeX") == 0)
818 Resources.maxComputeWorkGroupSizeX = value;
819 else if (strcmp(token, "MaxComputeWorkGroupSizeY") == 0)
820 Resources.maxComputeWorkGroupSizeY = value;
821 else if (strcmp(token, "MaxComputeWorkGroupSizeZ") == 0)
822 Resources.maxComputeWorkGroupSizeZ = value;
823 else if (strcmp(token, "MaxComputeUniformComponents") == 0)
824 Resources.maxComputeUniformComponents = value;
825 else if (strcmp(token, "MaxComputeTextureImageUnits") == 0)
826 Resources.maxComputeTextureImageUnits = value;
827 else if (strcmp(token, "MaxComputeImageUniforms") == 0)
828 Resources.maxComputeImageUniforms = value;
829 else if (strcmp(token, "MaxComputeAtomicCounters") == 0)
830 Resources.maxComputeAtomicCounters = value;
831 else if (strcmp(token, "MaxComputeAtomicCounterBuffers") == 0)
832 Resources.maxComputeAtomicCounterBuffers = value;
833 else if (strcmp(token, "MaxVaryingComponents") == 0)
834 Resources.maxVaryingComponents = value;
835 else if (strcmp(token, "MaxVertexOutputComponents") == 0)
836 Resources.maxVertexOutputComponents = value;
837 else if (strcmp(token, "MaxGeometryInputComponents") == 0)
838 Resources.maxGeometryInputComponents = value;
839 else if (strcmp(token, "MaxGeometryOutputComponents") == 0)
840 Resources.maxGeometryOutputComponents = value;
841 else if (strcmp(token, "MaxFragmentInputComponents") == 0)
842 Resources.maxFragmentInputComponents = value;
843 else if (strcmp(token, "MaxImageUnits") == 0)
844 Resources.maxImageUnits = value;
845 else if (strcmp(token, "MaxCombinedImageUnitsAndFragmentOutputs") == 0)
846 Resources.maxCombinedImageUnitsAndFragmentOutputs = value;
847 else if (strcmp(token, "MaxCombinedShaderOutputResources") == 0)
848 Resources.maxCombinedShaderOutputResources = value;
849 else if (strcmp(token, "MaxImageSamples") == 0)
850 Resources.maxImageSamples = value;
851 else if (strcmp(token, "MaxVertexImageUniforms") == 0)
852 Resources.maxVertexImageUniforms = value;
853 else if (strcmp(token, "MaxTessControlImageUniforms") == 0)
854 Resources.maxTessControlImageUniforms = value;
855 else if (strcmp(token, "MaxTessEvaluationImageUniforms") == 0)
856 Resources.maxTessEvaluationImageUniforms = value;
857 else if (strcmp(token, "MaxGeometryImageUniforms") == 0)
858 Resources.maxGeometryImageUniforms = value;
859 else if (strcmp(token, "MaxFragmentImageUniforms") == 0)
860 Resources.maxFragmentImageUniforms = value;
861 else if (strcmp(token, "MaxCombinedImageUniforms") == 0)
862 Resources.maxCombinedImageUniforms = value;
863 else if (strcmp(token, "MaxGeometryTextureImageUnits") == 0)
864 Resources.maxGeometryTextureImageUnits = value;
865 else if (strcmp(token, "MaxGeometryOutputVertices") == 0)
866 Resources.maxGeometryOutputVertices = value;
867 else if (strcmp(token, "MaxGeometryTotalOutputComponents") == 0)
868 Resources.maxGeometryTotalOutputComponents = value;
869 else if (strcmp(token, "MaxGeometryUniformComponents") == 0)
870 Resources.maxGeometryUniformComponents = value;
871 else if (strcmp(token, "MaxGeometryVaryingComponents") == 0)
872 Resources.maxGeometryVaryingComponents = value;
873 else if (strcmp(token, "MaxTessControlInputComponents") == 0)
874 Resources.maxTessControlInputComponents = value;
875 else if (strcmp(token, "MaxTessControlOutputComponents") == 0)
876 Resources.maxTessControlOutputComponents = value;
877 else if (strcmp(token, "MaxTessControlTextureImageUnits") == 0)
878 Resources.maxTessControlTextureImageUnits = value;
879 else if (strcmp(token, "MaxTessControlUniformComponents") == 0)
880 Resources.maxTessControlUniformComponents = value;
881 else if (strcmp(token, "MaxTessControlTotalOutputComponents") == 0)
882 Resources.maxTessControlTotalOutputComponents = value;
883 else if (strcmp(token, "MaxTessEvaluationInputComponents") == 0)
884 Resources.maxTessEvaluationInputComponents = value;
885 else if (strcmp(token, "MaxTessEvaluationOutputComponents") == 0)
886 Resources.maxTessEvaluationOutputComponents = value;
887 else if (strcmp(token, "MaxTessEvaluationTextureImageUnits") == 0)
888 Resources.maxTessEvaluationTextureImageUnits = value;
889 else if (strcmp(token, "MaxTessEvaluationUniformComponents") == 0)
890 Resources.maxTessEvaluationUniformComponents = value;
891 else if (strcmp(token, "MaxTessPatchComponents") == 0)
892 Resources.maxTessPatchComponents = value;
893 else if (strcmp(token, "MaxPatchVertices") == 0)
894 Resources.maxPatchVertices = value;
895 else if (strcmp(token, "MaxTessGenLevel") == 0)
896 Resources.maxTessGenLevel = value;
897 else if (strcmp(token, "MaxViewports") == 0)
898 Resources.maxViewports = value;
899 else if (strcmp(token, "MaxVertexAtomicCounters") == 0)
900 Resources.maxVertexAtomicCounters = value;
901 else if (strcmp(token, "MaxTessControlAtomicCounters") == 0)
902 Resources.maxTessControlAtomicCounters = value;
903 else if (strcmp(token, "MaxTessEvaluationAtomicCounters") == 0)
904 Resources.maxTessEvaluationAtomicCounters = value;
905 else if (strcmp(token, "MaxGeometryAtomicCounters") == 0)
906 Resources.maxGeometryAtomicCounters = value;
907 else if (strcmp(token, "MaxFragmentAtomicCounters") == 0)
908 Resources.maxFragmentAtomicCounters = value;
909 else if (strcmp(token, "MaxCombinedAtomicCounters") == 0)
910 Resources.maxCombinedAtomicCounters = value;
911 else if (strcmp(token, "MaxAtomicCounterBindings") == 0)
912 Resources.maxAtomicCounterBindings = value;
913 else if (strcmp(token, "MaxVertexAtomicCounterBuffers") == 0)
914 Resources.maxVertexAtomicCounterBuffers = value;
915 else if (strcmp(token, "MaxTessControlAtomicCounterBuffers") == 0)
916 Resources.maxTessControlAtomicCounterBuffers = value;
917 else if (strcmp(token, "MaxTessEvaluationAtomicCounterBuffers") == 0)
918 Resources.maxTessEvaluationAtomicCounterBuffers = value;
919 else if (strcmp(token, "MaxGeometryAtomicCounterBuffers") == 0)
920 Resources.maxGeometryAtomicCounterBuffers = value;
921 else if (strcmp(token, "MaxFragmentAtomicCounterBuffers") == 0)
922 Resources.maxFragmentAtomicCounterBuffers = value;
923 else if (strcmp(token, "MaxCombinedAtomicCounterBuffers") == 0)
924 Resources.maxCombinedAtomicCounterBuffers = value;
925 else if (strcmp(token, "MaxAtomicCounterBufferSize") == 0)
926 Resources.maxAtomicCounterBufferSize = value;
927 else if (strcmp(token, "MaxTransformFeedbackBuffers") == 0)
928 Resources.maxTransformFeedbackBuffers = value;
929 else if (strcmp(token, "MaxTransformFeedbackInterleavedComponents") == 0)
930 Resources.maxTransformFeedbackInterleavedComponents = value;
931 else if (strcmp(token, "MaxCullDistances") == 0)
932 Resources.maxCullDistances = value;
933 else if (strcmp(token, "MaxCombinedClipAndCullDistances") == 0)
934 Resources.maxCombinedClipAndCullDistances = value;
935 else if (strcmp(token, "MaxSamples") == 0)
936 Resources.maxSamples = value;
937
938 else if (strcmp(token, "nonInductiveForLoops") == 0)
939 Resources.limits.nonInductiveForLoops = (value != 0);
940 else if (strcmp(token, "whileLoops") == 0)
941 Resources.limits.whileLoops = (value != 0);
942 else if (strcmp(token, "doWhileLoops") == 0)
943 Resources.limits.doWhileLoops = (value != 0);
944 else if (strcmp(token, "generalUniformIndexing") == 0)
945 Resources.limits.generalUniformIndexing = (value != 0);
946 else if (strcmp(token, "generalAttributeMatrixVectorIndexing") == 0)
947 Resources.limits.generalAttributeMatrixVectorIndexing = (value != 0);
948 else if (strcmp(token, "generalVaryingIndexing") == 0)
949 Resources.limits.generalVaryingIndexing = (value != 0);
950 else if (strcmp(token, "generalSamplerIndexing") == 0)
951 Resources.limits.generalSamplerIndexing = (value != 0);
952 else if (strcmp(token, "generalVariableIndexing") == 0)
953 Resources.limits.generalVariableIndexing = (value != 0);
954 else if (strcmp(token, "generalConstantMatrixVectorIndexing") == 0)
955 Resources.limits.generalConstantMatrixVectorIndexing = (value != 0);
956 else
957 printf("Warning: unrecognized limit (%s) in configuration file.\n", token);
958
959 token = strtok(0, delims);
960 }
961 if (configStrings)
962 FreeFileData(configStrings);
963}
964
965void XglTestFramework::SetMessageOptions(EShMessages& messages)
966{
967 if (m_compile_options & EOptionRelaxedErrors)
968 messages = (EShMessages)(messages | EShMsgRelaxedErrors);
969 if (m_compile_options & EOptionIntermediate)
970 messages = (EShMessages)(messages | EShMsgAST);
971 if (m_compile_options & EOptionSuppressWarnings)
972 messages = (EShMessages)(messages | EShMsgSuppressWarnings);
973}
974
975//
976// Malloc a string of sufficient size and read a string into it.
977//
978char** XglTestFramework::ReadFileData(const char* fileName)
979{
980 FILE *in;
981 #if defined(_WIN32) && defined(__GNUC__)
982 in = fopen(fileName, "r");
983 int errorCode = in ? 0 : 1;
984 #else
985 int errorCode = fopen_s(&in, fileName, "r");
986 #endif
987
988 char *fdata;
989 int count = 0;
990 const int maxSourceStrings = 5;
991 char** return_data = (char**)malloc(sizeof(char *) * (maxSourceStrings+1));
992
993 if (errorCode) {
994 printf("Error: unable to open input file: %s\n", fileName);
995 return 0;
996 }
997
998 while (fgetc(in) != EOF)
999 count++;
1000
1001 fseek(in, 0, SEEK_SET);
1002
1003 if (!(fdata = (char*)malloc(count+2))) {
1004 printf("Error allocating memory\n");
1005 return 0;
1006 }
1007 if (fread(fdata,1,count, in)!=count) {
1008 printf("Error reading input file: %s\n", fileName);
1009 return 0;
1010 }
1011 fdata[count] = '\0';
1012 fclose(in);
1013 if (count == 0) {
1014 return_data[0]=(char*)malloc(count+2);
1015 return_data[0][0]='\0';
1016 m_num_shader_strings = 0;
1017 return return_data;
1018 } else
1019 m_num_shader_strings = 1;
1020
1021 int len = (int)(ceil)((float)count/(float)m_num_shader_strings);
1022 int ptr_len=0,i=0;
1023 while(count>0){
1024 return_data[i]=(char*)malloc(len+2);
1025 memcpy(return_data[i],fdata+ptr_len,len);
1026 return_data[i][len]='\0';
1027 count-=(len);
1028 ptr_len+=(len);
1029 if(count<len){
1030 if(count==0){
1031 m_num_shader_strings=(i+1);
1032 break;
1033 }
1034 len = count;
1035 }
1036 ++i;
1037 }
1038 return return_data;
1039}
1040
1041void XglTestFramework::FreeFileData(char** data)
1042{
1043 for(int i=0;i<m_num_shader_strings;i++)
1044 free(data[i]);
1045}
1046
1047//
1048// Deduce the language from the filename. Files must end in one of the
1049// following extensions:
1050//
1051// .vert = vertex
1052// .tesc = tessellation control
1053// .tese = tessellation evaluation
1054// .geom = geometry
1055// .frag = fragment
1056// .comp = compute
1057//
1058EShLanguage XglTestFramework::FindLanguage(const std::string& name)
1059{
1060 size_t ext = name.rfind('.');
1061 if (ext == std::string::npos) {
1062 return EShLangVertex;
1063 }
1064
1065 std::string suffix = name.substr(ext + 1, std::string::npos);
1066 if (suffix == "vert")
1067 return EShLangVertex;
1068 else if (suffix == "tesc")
1069 return EShLangTessControl;
1070 else if (suffix == "tese")
1071 return EShLangTessEvaluation;
1072 else if (suffix == "geom")
1073 return EShLangGeometry;
1074 else if (suffix == "frag")
1075 return EShLangFragment;
1076 else if (suffix == "comp")
1077 return EShLangCompute;
1078
1079 return EShLangVertex;
1080}
1081
1082//
1083// Convert XGL shader type to compiler's
1084//
1085EShLanguage XglTestFramework::FindLanguage(const XGL_PIPELINE_SHADER_STAGE shader_type)
1086{
1087 switch (shader_type) {
1088 case XGL_SHADER_STAGE_VERTEX:
1089 return EShLangVertex;
1090
1091 case XGL_SHADER_STAGE_TESS_CONTROL:
1092 return EShLangTessControl;
1093
1094 case XGL_SHADER_STAGE_TESS_EVALUATION:
1095 return EShLangTessEvaluation;
1096
1097 case XGL_SHADER_STAGE_GEOMETRY:
1098 return EShLangGeometry;
1099
1100 case XGL_SHADER_STAGE_FRAGMENT:
1101 return EShLangFragment;
1102
1103 case XGL_SHADER_STAGE_COMPUTE:
1104 return EShLangCompute;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001105
Chia-I Wub4c2aa42014-12-15 23:50:11 +08001106 default:
1107 return EShLangVertex;
1108 }
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001109}
1110
1111
1112//
1113// Compile a given string containing GLSL into BIL for use by XGL
1114// Return value of false means an error was encountered.
1115//
1116bool XglTestFramework::GLSLtoBIL(const XGL_PIPELINE_SHADER_STAGE shader_type,
1117 const char *pshader,
1118 std::vector<unsigned int> &bil)
1119{
1120 glslang::TProgram& program = *new glslang::TProgram;
1121 const char *shaderStrings[1];
1122
1123 // TODO: Do we want to load a special config file depending on the
1124 // shader source? Optional name maybe?
1125 // SetConfigFile(fileName);
1126
1127 ProcessConfigFile();
1128
1129 EShMessages messages = EShMsgDefault;
1130 SetMessageOptions(messages);
1131
1132 EShLanguage stage = FindLanguage(shader_type);
1133 glslang::TShader* shader = new glslang::TShader(stage);
1134
1135 shaderStrings[0] = pshader;
1136 shader->setStrings(shaderStrings, 1);
1137
1138 if (! shader->parse(&Resources, (m_compile_options & EOptionDefaultDesktop) ? 110 : 100, false, messages)) {
1139
Cody Northrop195d6622014-11-03 12:54:37 -07001140 if (! (m_compile_options & EOptionSuppressInfolog)) {
1141 puts(shader->getInfoLog());
1142 puts(shader->getInfoDebugLog());
1143 }
1144
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001145 return false; // something didn't work
1146 }
1147
1148 program.addShader(shader);
1149
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001150
1151 //
1152 // Program-level processing...
1153 //
1154
Cody Northrop195d6622014-11-03 12:54:37 -07001155 if (! program.link(messages)) {
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001156
Cody Northrop195d6622014-11-03 12:54:37 -07001157 if (! (m_compile_options & EOptionSuppressInfolog)) {
1158 puts(shader->getInfoLog());
1159 puts(shader->getInfoDebugLog());
1160 }
1161
1162 return false;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001163 }
1164
1165 if (m_compile_options & EOptionDumpReflection) {
1166 program.buildReflection();
1167 program.dumpReflection();
1168 }
1169
1170 glslang::GlslangToBil(*program.getIntermediate(stage), bil);
1171
1172 return true;
1173}
1174
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001175
1176
1177XglTestImageRecord::XglTestImageRecord() : // Constructor
1178 m_width( 0 ),
1179 m_height( 0 ),
Chia-I Wu837f9952014-12-15 23:29:34 +08001180 m_data( NULL ),
Tony Barbour96db8822015-02-25 12:28:39 -07001181 m_presentableImage( NULL ),
1182 m_presentableMemory( NULL),
Chia-I Wu837f9952014-12-15 23:29:34 +08001183 m_data_size( 0 )
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001184{
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001185}
1186
1187XglTestImageRecord::~XglTestImageRecord()
1188{
1189
1190}
1191
1192XglTestImageRecord::XglTestImageRecord(const XglTestImageRecord &copyin) // Copy constructor to handle pass by value.
1193{
1194 m_title = copyin.m_title;
1195 m_width = copyin.m_width;
1196 m_height = copyin.m_height;
1197 m_data_size = copyin.m_data_size;
1198 m_data = copyin.m_data; // TODO: Do we need to copy the data or is pointer okay?
Tony Barbour96db8822015-02-25 12:28:39 -07001199 m_presentableImage = copyin.m_presentableImage;
1200 m_presentableMemory = copyin.m_presentableMemory;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001201}
1202
1203ostream &operator<<(ostream &output, const XglTestImageRecord &XglTestImageRecord)
1204{
1205 output << XglTestImageRecord.m_title << " (" << XglTestImageRecord.m_width <<
1206 "," << XglTestImageRecord.m_height << ")" << endl;
1207 return output;
1208}
1209
1210XglTestImageRecord& XglTestImageRecord::operator=(const XglTestImageRecord &rhs)
1211{
1212 m_title = rhs.m_title;
1213 m_width = rhs.m_width;
1214 m_height = rhs.m_height;
1215 m_data_size = rhs.m_data_size;
1216 m_data = rhs.m_data;
Tony Barbour96db8822015-02-25 12:28:39 -07001217 m_presentableImage = rhs.m_presentableImage;
1218 m_presentableMemory = rhs.m_presentableMemory;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001219 return *this;
1220}
1221
1222int XglTestImageRecord::operator==(const XglTestImageRecord &rhs) const
1223{
1224 if( this->m_data != rhs.m_data) return 0;
1225 return 1;
1226}
1227
1228// This function is required for built-in STL list functions like sort
1229int XglTestImageRecord::operator<(const XglTestImageRecord &rhs) const
1230{
1231 if( this->m_data_size < rhs.m_data_size ) return 1;
1232 return 0;
1233}
1234