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