blob: ab8b8813eec965e50f658aec1e000ba1d038ac80 [file] [log] [blame]
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001// VK tests
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06002//
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
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060023#include "vktestframework.h"
24#include "vkrenderframework.h"
Steve Kc1638cc2015-03-17 09:40:23 -060025#include "GlslangToSpv.h"
Tony Barbour4ab45422014-12-10 17:00:20 -070026#include <limits.h>
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -060027#include <math.h>
Chia-I Wuec664fa2014-12-02 11:54:24 +080028#include <wand/MagickWand.h>
Chia-I Wuf8693382015-04-16 22:02:10 +080029#include <xcb/xcb.h>
30#include <vk_wsi_lunarg.h>
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -060031
Tony Barbour3d69c9e2015-05-20 16:53:31 -060032#if defined(PATH_MAX) && !defined(MAX_PATH)
33#define MAX_PATH PATH_MAX
34#endif
35
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -060036// Command-line options
37enum TOptions {
38 EOptionNone = 0x000,
39 EOptionIntermediate = 0x001,
40 EOptionSuppressInfolog = 0x002,
41 EOptionMemoryLeakMode = 0x004,
42 EOptionRelaxedErrors = 0x008,
43 EOptionGiveWarnings = 0x010,
44 EOptionLinkProgram = 0x020,
45 EOptionMultiThreaded = 0x040,
46 EOptionDumpConfig = 0x080,
47 EOptionDumpReflection = 0x100,
48 EOptionSuppressWarnings = 0x200,
49 EOptionDumpVersions = 0x400,
Cody Northrop3bfd27c2015-03-17 15:55:58 -060050 EOptionSpv = 0x800,
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -060051 EOptionDefaultDesktop = 0x1000,
52};
53
Chia-I Wuf8693382015-04-16 22:02:10 +080054class TestFrameworkVkPresent
55{
56public:
57 TestFrameworkVkPresent(vk_testing::Device &device);
58
59 void Run();
60 void InitPresentFramework(std::list<VkTestImageRecord> &imagesIn);
61 void CreateMyWindow();
62 void CreateSwapChain();
63 void TearDown();
Tony Barbour3d69c9e2015-05-20 16:53:31 -060064#ifdef _WIN32
65 static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
66#endif
67
Chia-I Wuf8693382015-04-16 22:02:10 +080068
69protected:
70 vk_testing::Device &m_device;
71 vk_testing::Queue &m_queue;
72 vk_testing::CmdBuffer m_cmdbuf;
73
74private:
Tony Barbour3d69c9e2015-05-20 16:53:31 -060075#ifdef _WIN32
76 HINSTANCE m_connection; // hInstance - Windows Instance
77 HWND m_window; // hWnd - window handle
78
79#else
Chia-I Wuf8693382015-04-16 22:02:10 +080080 xcb_connection_t *m_connection;
81 xcb_screen_t *m_screen;
82 xcb_window_t m_window;
83 xcb_intern_atom_reply_t *m_atom_wm_delete_window;
Tony Barbour3d69c9e2015-05-20 16:53:31 -060084#endif
Courtney Goeltzenleuchterd6079ec2015-04-22 10:09:35 -060085 std::list<VkTestImageRecord> m_images;
Chia-I Wuf8693382015-04-16 22:02:10 +080086
87 VkSwapChainWSI m_swap_chain;
88
89 bool m_quit;
90 bool m_pause;
91
92 uint32_t m_width;
93 uint32_t m_height;
94
95 std::list<VkTestImageRecord>::iterator m_display_image;
96
97 void Display();
98 void HandleEvent(xcb_generic_event_t *event);
99};
100
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600101#ifndef _WIN32
102
103#include <errno.h>
104
105int fopen_s(
106 FILE** pFile,
107 const char* filename,
108 const char* mode
109)
110{
111 if (!pFile || !filename || !mode) {
112 return EINVAL;
113 }
114
115 FILE* f = fopen(filename, mode);
116 if (! f) {
117 if (errno != 0) {
118 return errno;
119 } else {
120 return ENOENT;
121 }
122 }
123 *pFile = f;
124
125 return 0;
126}
127
128#endif
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600129
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600130
131
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600132// Set up environment for GLSL compiler
133// Must be done once per process
134void TestEnvironment::SetUp()
135{
Cody Northrop3bfd27c2015-03-17 15:55:58 -0600136 // Initialize GLSL to SPV compiler utility
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600137 glslang::InitializeProcess();
Chia-I Wub76e0fa2014-12-28 14:27:28 +0800138
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600139 vk_testing::set_error_callback(test_error_callback);
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600140}
141
142void TestEnvironment::TearDown()
143{
144 glslang::FinalizeProcess();
145}
146
Tony Barbour6918cd52015-04-09 12:58:51 -0600147VkTestFramework::VkTestFramework() :
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600148 m_compile_options( 0 ),
149 m_num_shader_strings( 0 )
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600150{
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600151
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600152}
153
Tony Barbour6918cd52015-04-09 12:58:51 -0600154VkTestFramework::~VkTestFramework()
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600155{
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600156
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600157}
158
159// Define all the static elements
Tony Barbour6918cd52015-04-09 12:58:51 -0600160bool VkTestFramework::m_show_images = false;
161bool VkTestFramework::m_save_images = false;
162bool VkTestFramework::m_compare_images = false;
Tony Barbour0dd968a2015-04-02 15:48:24 -0600163#ifdef _WIN32
Tony Barbour6918cd52015-04-09 12:58:51 -0600164bool VkTestFramework::m_use_spv = false;
Tony Barbour0dd968a2015-04-02 15:48:24 -0600165#else
Tony Barbour6918cd52015-04-09 12:58:51 -0600166bool VkTestFramework::m_use_spv = true;
Tony Barbour0dd968a2015-04-02 15:48:24 -0600167#endif
Tony Barbour6918cd52015-04-09 12:58:51 -0600168int VkTestFramework::m_width = 0;
169int VkTestFramework::m_height = 0;
170std::list<VkTestImageRecord> VkTestFramework::m_images;
171std::list<VkTestImageRecord>::iterator VkTestFramework::m_display_image;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600172int m_display_image_idx = 0;
173
Tony Barbour6918cd52015-04-09 12:58:51 -0600174void VkTestFramework::InitArgs(int *argc, char *argv[])
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600175{
176 int i, n;
177
178 for (i=0, n=0; i< *argc; i++) {
179 if (strncmp("--show-images", argv[i], 13) == 0) {
180 m_show_images = true;
181 continue;
182 }
183 if (strncmp("--save-images", argv[i], 13) == 0) {
184 m_save_images = true;
185 continue;
186 }
187
Cody Northrop3bfd27c2015-03-17 15:55:58 -0600188 if (strncmp("--use-SPV", argv[i], 13) == 0) {
189 m_use_spv = true;
Courtney Goeltzenleuchterb666dc62014-10-09 09:13:56 -0600190 continue;
191 }
192
Cody Northrop3bfd27c2015-03-17 15:55:58 -0600193 if (strncmp("--no-SPV", argv[i], 13) == 0) {
194 m_use_spv = false;
Courtney Goeltzenleuchterc44e3ee2014-10-31 14:13:33 -0600195 continue;
196 }
197
Tony Barbour247bf372014-10-30 14:29:04 -0600198 if (strncmp("--compare-images", argv[i], 16) == 0) {
199 m_compare_images = true;
200 continue;
201 }
202
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600203 /*
204 * Since the above "consume" inputs, update argv
205 * so that it contains the trimmed list of args for glutInit
206 */
Tony Barboura98d3932014-12-11 09:52:49 -0700207 if (strncmp("--help", argv[i], 6) == 0 || strncmp("-h", argv[i], 2) == 0) {
Courtney Goeltzenleuchter31144b72014-12-02 13:13:10 -0700208 printf("\nOther options:\n");
209 printf("\t--show-images\n"
210 "\t\tDisplay test images in viewer after tests complete.\n");
211 printf("\t--save-images\n"
212 "\t\tSave tests images as ppm files in current working directory.\n"
213 "\t\tUsed to generate golden images for compare-images.\n");
214 printf("\t--compare-images\n"
215 "\t\tCompare test images to 'golden' image in golden folder.\n"
Tony Barboura98d3932014-12-11 09:52:49 -0700216 "\t\tAlso saves the generated test image in current working\n"
217 "\t\t\tdirectory but only if the image is different from the golden\n"
218 "\t\tSetting RENDERTEST_GOLDEN_DIR environment variable can specify\n"
219 "\t\t\tdifferent directory for golden images\n"
Courtney Goeltzenleuchter31144b72014-12-02 13:13:10 -0700220 "\t\tSignal test failure if different.\n");
Cody Northrop3bfd27c2015-03-17 15:55:58 -0600221 printf("\t--use-SPV\n"
222 "\t\tUse SPV code path (default).\n");
223 printf("\t--no-SPV\n"
224 "\t\tUse built-in GLSL compiler rather than SPV code path.\n");
Tony Barbour4ab45422014-12-10 17:00:20 -0700225 exit(0);
Courtney Goeltzenleuchter31144b72014-12-02 13:13:10 -0700226 }
227
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600228 argv[n] = argv[i];
229 n++;
230 }
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600231}
232
Tony Barbour6918cd52015-04-09 12:58:51 -0600233void VkTestFramework::WritePPM( const char *basename, VkImageObj *image )
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600234{
235 string filename;
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600236 VkResult err;
Tony Barbour84d448c2015-04-02 14:02:33 -0600237 int x, y;
Tony Barbour6918cd52015-04-09 12:58:51 -0600238 VkImageObj displayImage(image->device());
Tony Barbour4c97d7a2015-04-22 15:10:33 -0600239 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
Tony Barbour84d448c2015-04-02 14:02:33 -0600240
Tony Barbour4c97d7a2015-04-22 15:10:33 -0600241 displayImage.init(image->extent().width, image->extent().height, image->format(), 0, VK_IMAGE_TILING_LINEAR, reqs);
Tony Barbour84d448c2015-04-02 14:02:33 -0600242 displayImage.CopyImage(*image);
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600243
244 filename.append(basename);
245 filename.append(".ppm");
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600246
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600247 const VkImageSubresource sr = {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600248 VK_IMAGE_ASPECT_COLOR, 0, 0
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600249 };
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600250 VkSubresourceLayout sr_layout;
Chia-I Wu99ff89d2014-12-27 14:14:50 +0800251 size_t data_size = sizeof(sr_layout);
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600252
253 err = vkGetImageSubresourceInfo(image->device()->device(), displayImage.image(), &sr,
Tony Barbourd1c35722015-04-16 15:59:00 -0600254 VK_SUBRESOURCE_INFO_TYPE_LAYOUT,
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600255 &data_size, &sr_layout);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600256 ASSERT_VK_SUCCESS( err );
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600257 ASSERT_EQ(data_size, sizeof(sr_layout));
258
Tony Barbour84d448c2015-04-02 14:02:33 -0600259 char *ptr;
260 ptr = (char *) displayImage.map();
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600261 ptr += sr_layout.offset;
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600262 ofstream file (filename.c_str(), ios::binary);
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600263 ASSERT_TRUE(file.is_open()) << "Unable to open file: " << filename;
264
265 file << "P6\n";
Tony Barbour84d448c2015-04-02 14:02:33 -0600266 file << displayImage.width() << "\n";
267 file << displayImage.height() << "\n";
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600268 file << 255 << "\n";
269
Tony Barbour84d448c2015-04-02 14:02:33 -0600270 for (y = 0; y < displayImage.height(); y++) {
Tony Barboura53a6942015-02-25 11:25:11 -0700271 const int *row = (const int *) ptr;
272 int swapped;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600273
Tony Barbourd1c35722015-04-16 15:59:00 -0600274 if (displayImage.format() == VK_FORMAT_B8G8R8A8_UNORM)
Tony Barboura53a6942015-02-25 11:25:11 -0700275 {
Tony Barbour84d448c2015-04-02 14:02:33 -0600276 for (x = 0; x < displayImage.width(); x++) {
Tony Barboura53a6942015-02-25 11:25:11 -0700277 swapped = (*row & 0xff00ff00) | (*row & 0x000000ff) << 16 | (*row & 0x00ff0000) >> 16;
278 file.write((char *) &swapped, 3);
279 row++;
280 }
281 }
Tony Barbourd1c35722015-04-16 15:59:00 -0600282 else if (displayImage.format() == VK_FORMAT_R8G8B8A8_UNORM)
Tony Barboura53a6942015-02-25 11:25:11 -0700283 {
Tony Barbour84d448c2015-04-02 14:02:33 -0600284 for (x = 0; x < displayImage.width(); x++) {
Tony Barboura53a6942015-02-25 11:25:11 -0700285 file.write((char *) row, 3);
286 row++;
287 }
288 }
289 else {
290 printf("Unrecognized image format - will not write image files");
291 break;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600292 }
293
294 ptr += sr_layout.rowPitch;
295 }
296
297 file.close();
Tony Barbour84d448c2015-04-02 14:02:33 -0600298 displayImage.unmap();
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600299}
300
Tony Barbour6918cd52015-04-09 12:58:51 -0600301void VkTestFramework::Compare(const char *basename, VkImageObj *image )
Tony Barbour247bf372014-10-30 14:29:04 -0600302{
303
304 MagickWand *magick_wand_1;
305 MagickWand *magick_wand_2;
306 MagickWand *compare_wand;
307 MagickBooleanType status;
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600308 char testimage[256],golden[MAX_PATH+256],golddir[MAX_PATH] = "./golden";
Tony Barbour247bf372014-10-30 14:29:04 -0600309 double differenz;
310
Tony Barbour4ab45422014-12-10 17:00:20 -0700311 if (getenv("RENDERTEST_GOLDEN_DIR"))
312 {
313 strcpy(golddir,getenv("RENDERTEST_GOLDEN_DIR"));
314 }
315
Tony Barbour247bf372014-10-30 14:29:04 -0600316 MagickWandGenesis();
317 magick_wand_1=NewMagickWand();
318 sprintf(testimage,"%s.ppm",basename);
319 status=MagickReadImage(magick_wand_1,testimage);
320 ASSERT_TRUE(status) << "Unable to open file: " << testimage;
321
322
323 MagickWandGenesis();
324 magick_wand_2=NewMagickWand();
Tony Barbour4ab45422014-12-10 17:00:20 -0700325 sprintf(golden,"%s/%s.ppm",golddir,basename);
Tony Barbour247bf372014-10-30 14:29:04 -0600326 status=MagickReadImage(magick_wand_2,golden);
327 ASSERT_TRUE(status) << "Unable to open file: " << golden;
328
Tony Barbour247bf372014-10-30 14:29:04 -0600329 compare_wand=MagickCompareImages(magick_wand_1,magick_wand_2, MeanAbsoluteErrorMetric, &differenz);
330 if (differenz != 0.0)
331 {
332 char difference[256];
333
334 sprintf(difference,"%s-diff.ppm",basename);
335 status = MagickWriteImage(compare_wand, difference);
336 ASSERT_TRUE(differenz == 0.0) << "Image comparison failed - diff file written";
337 }
338 DestroyMagickWand(compare_wand);
339
340 DestroyMagickWand(magick_wand_1);
341 DestroyMagickWand(magick_wand_2);
342 MagickWandTerminus();
Courtney Goeltzenleuchterfcda72d2014-12-05 15:41:02 -0700343
344 if (differenz == 0.0)
345 {
346 /*
347 * If test image and golden image match, we do not need to
348 * keep around the test image.
349 */
350 remove(testimage);
351 }
Tony Barbour247bf372014-10-30 14:29:04 -0600352}
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600353
Tony Barbour6918cd52015-04-09 12:58:51 -0600354void VkTestFramework::Show(const char *comment, VkImageObj *image)
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600355{
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600356 VkResult err;
Courtney Goeltzenleuchterfcf43ab2015-04-29 10:53:31 -0600357 VkSubresourceLayout sr_layout;
358 char *ptr;
359 VkTestImageRecord record;
360 size_t data_size = sizeof(sr_layout);
361 VkImageObj displayImage(image->device());
362 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
363
364 if (!m_show_images) return;
365
366 displayImage.init(image->extent().width, image->extent().height, image->format(), 0, VK_IMAGE_TILING_LINEAR, reqs);
367 displayImage.CopyImage(*image);
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600368
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600369 const VkImageSubresource sr = {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600370 VK_IMAGE_ASPECT_COLOR, 0, 0
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600371 };
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600372
Courtney Goeltzenleuchterfcf43ab2015-04-29 10:53:31 -0600373 err = vkGetImageSubresourceInfo(displayImage.device()->device(), displayImage.image(), &sr,
374 VK_SUBRESOURCE_INFO_TYPE_LAYOUT,
375 &data_size, &sr_layout);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600376 ASSERT_VK_SUCCESS( err );
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600377 ASSERT_EQ(data_size, sizeof(sr_layout));
378
Courtney Goeltzenleuchterfcf43ab2015-04-29 10:53:31 -0600379 err = displayImage.MapMemory( (void **) &ptr );
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600380 ASSERT_VK_SUCCESS( err );
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600381
382 ptr += sr_layout.offset;
383
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600384 record.m_title.append(comment);
Courtney Goeltzenleuchterfcf43ab2015-04-29 10:53:31 -0600385 record.m_width = displayImage.width();
386 record.m_height = displayImage.height();
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600387 // TODO: Need to make this more robust to handle different image formats
Courtney Goeltzenleuchterfcf43ab2015-04-29 10:53:31 -0600388 record.m_data_size = displayImage.width()*displayImage.height()*4;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600389 record.m_data = malloc(record.m_data_size);
390 memcpy(record.m_data, ptr, record.m_data_size);
391 m_images.push_back(record);
392 m_display_image = --m_images.end();
393
Courtney Goeltzenleuchterfcf43ab2015-04-29 10:53:31 -0600394 err = displayImage.UnmapMemory();
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600395 ASSERT_VK_SUCCESS( err );
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600396}
397
Tony Barbour6918cd52015-04-09 12:58:51 -0600398void VkTestFramework::RecordImages(vector<VkImageObj *> images)
Tony Barbour247bf372014-10-30 14:29:04 -0600399{
Courtney Goeltzenleuchtere5f0e6c2015-04-02 14:17:44 -0600400 for (int32_t i = 0; i < images.size(); i++) {
401 RecordImage(images[i]);
Tony Barbour247bf372014-10-30 14:29:04 -0600402 }
403}
404
Tony Barbour6918cd52015-04-09 12:58:51 -0600405void VkTestFramework::RecordImage(VkImageObj * image)
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600406{
407 const ::testing::TestInfo* const test_info =
408 ::testing::UnitTest::GetInstance()->current_test_info();
Tony Barbour247bf372014-10-30 14:29:04 -0600409 ostringstream filestream;
410 string filename;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600411
Tony Barbour247bf372014-10-30 14:29:04 -0600412 m_width = 40;
413
414 if (strcmp(test_info->name(), m_testName.c_str())) {
415 filestream << test_info->name();
416 m_testName.assign(test_info->name());
Tony Barboura0e2ee82014-11-18 17:02:36 -0700417 m_frameNum = 2;
418 filename = filestream.str();
Tony Barbour247bf372014-10-30 14:29:04 -0600419 }
420 else {
421 filestream << test_info->name() << "-" << m_frameNum;
422 m_frameNum++;
Tony Barboura0e2ee82014-11-18 17:02:36 -0700423 filename = filestream.str();
Tony Barbour247bf372014-10-30 14:29:04 -0600424 }
425
Tony Barbour247bf372014-10-30 14:29:04 -0600426 // ToDo - scrub string for bad characters
427
428 if (m_save_images || m_compare_images) {
429 WritePPM(filename.c_str(), image);
430 if (m_compare_images) {
431 Compare(filename.c_str(), image);
432 }
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600433 }
434
435 if (m_show_images) {
Courtney Goeltzenleuchter02d33c12014-10-08 14:26:40 -0600436 Show(test_info->name(), image);
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600437 }
438}
439
Chia-I Wuf8693382015-04-16 22:02:10 +0800440TestFrameworkVkPresent::TestFrameworkVkPresent(vk_testing::Device &device) :
441 m_device(device),
Courtney Goeltzenleuchterb4337c12015-03-05 16:47:18 -0700442 m_queue(*m_device.graphics_queues()[0]),
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600443 m_cmdbuf(m_device, vk_testing::CmdBuffer::create_info(m_device.graphics_queue_node_index_))
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600444{
Tony Barbour96db8822015-02-25 12:28:39 -0700445 m_quit = false;
446 m_pause = false;
447 m_width = 0;
448 m_height = 0;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600449}
450
Tony Barbour6918cd52015-04-09 12:58:51 -0600451void TestFrameworkVkPresent::Display()
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600452{
Tony Barbourf20f87b2015-04-22 09:02:32 -0600453 VkResult U_ASSERT_ONLY err;
Tony Barbour96db8822015-02-25 12:28:39 -0700454
Chia-I Wuf8693382015-04-16 22:02:10 +0800455 VkPresentInfoWSI present = {};
456 present.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_WSI;
457 present.image = m_display_image->m_presentableImage;
458 present.flipInterval = 1;
Tony Barbour96db8822015-02-25 12:28:39 -0700459
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600460#ifndef _WIN32
Chia-I Wuf8693382015-04-16 22:02:10 +0800461 xcb_change_property (m_connection,
Tony Barbour96db8822015-02-25 12:28:39 -0700462 XCB_PROP_MODE_REPLACE,
463 m_window,
464 XCB_ATOM_WM_NAME,
465 XCB_ATOM_STRING,
466 8,
467 m_display_image->m_title.size(),
468 m_display_image->m_title.c_str());
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600469#endif
Chia-I Wuf8693382015-04-16 22:02:10 +0800470 err = vkQueuePresentWSI(m_queue.obj(), &present);
Tony Barbour96db8822015-02-25 12:28:39 -0700471 assert(!err);
472
473 m_queue.wait();
474
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600475}
476
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600477#ifdef _WIN32
478// MS-Windows event handling function:
479LRESULT CALLBACK TestFrameworkVkPresent::WndProc(HWND hWnd,
480 UINT uMsg,
481 WPARAM wParam,
482 LPARAM lParam)
483{
484
485 switch(uMsg)
486 {
487 case WM_CLOSE:
488 PostQuitMessage(0);
489 break;
490
491 case WM_PAINT:
492 {
493 TestFrameworkVkPresent* me = reinterpret_cast<TestFrameworkVkPresent*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
494 if (me) {
495 me->Display();
496 }
497 }
498 return 0;
499
500 default:
501 break;
502 }
503 return (DefWindowProc(hWnd, uMsg, wParam, lParam));
504}
505
506void TestFrameworkVkPresent::Run()
507{
508 MSG msg; // message
509 bool done;
510
511 done = false; //initialize loop condition variable
512 /* main message loop*/
513 while(!done) {
514 PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
515 if (msg.message == WM_QUIT) {
516 done = true; //if found, quit app
517 } else {
518 /* Translate and dispatch to event queue*/
519 TranslateMessage(&msg);
520 DispatchMessage(&msg);
521 }
522 }
523}
524
525#else
Tony Barbour6918cd52015-04-09 12:58:51 -0600526void TestFrameworkVkPresent::HandleEvent(xcb_generic_event_t *event)
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600527{
Tony Barbour0dd968a2015-04-02 15:48:24 -0600528 uint8_t event_code = event->response_type & 0x7f;
Tony Barbour96db8822015-02-25 12:28:39 -0700529 switch (event_code) {
530 case XCB_EXPOSE:
531 Display(); // TODO: handle resize
532 break;
533 case XCB_CLIENT_MESSAGE:
534 if((*(xcb_client_message_event_t*)event).data.data32[0] ==
535 (m_atom_wm_delete_window)->atom) {
536 m_quit = true;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600537 }
538 break;
Tony Barbour96db8822015-02-25 12:28:39 -0700539 case XCB_KEY_RELEASE:
540 {
541 const xcb_key_release_event_t *key =
542 (const xcb_key_release_event_t *) event;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600543
Tony Barbour96db8822015-02-25 12:28:39 -0700544 switch (key->detail) {
545 case 0x9: // Escape
546 m_quit = true;
547 break;
548 case 0x71: // left arrow key
549 if (m_display_image == m_images.begin()) {
550 m_display_image = --m_images.end();
551 } else {
552 --m_display_image;
553 }
554 break;
555 case 0x72: // right arrow key
556 ++m_display_image;
557 if (m_display_image == m_images.end()) {
558 m_display_image = m_images.begin();
559 }
560 break;
561 case 0x41:
562 m_pause = !m_pause;
563 break;
564 }
565 Display();
566 }
567 break;
568 default:
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600569 break;
570 }
Tony Barbour96db8822015-02-25 12:28:39 -0700571}
572
Tony Barbour6918cd52015-04-09 12:58:51 -0600573void TestFrameworkVkPresent::Run()
Tony Barbour96db8822015-02-25 12:28:39 -0700574{
Chia-I Wuf8693382015-04-16 22:02:10 +0800575 xcb_flush(m_connection);
Tony Barbour96db8822015-02-25 12:28:39 -0700576
577 while (! m_quit) {
578 xcb_generic_event_t *event;
579
580 if (m_pause) {
Chia-I Wuf8693382015-04-16 22:02:10 +0800581 event = xcb_wait_for_event(m_connection);
Tony Barbour96db8822015-02-25 12:28:39 -0700582 } else {
Chia-I Wuf8693382015-04-16 22:02:10 +0800583 event = xcb_poll_for_event(m_connection);
Tony Barbour96db8822015-02-25 12:28:39 -0700584 }
585 if (event) {
586 HandleEvent(event);
587 free(event);
588 }
589 }
590}
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600591#endif // _WIN32
Tony Barbour96db8822015-02-25 12:28:39 -0700592
Chia-I Wuf8693382015-04-16 22:02:10 +0800593void TestFrameworkVkPresent::CreateSwapChain()
Tony Barbour96db8822015-02-25 12:28:39 -0700594{
Tony Barbourf20f87b2015-04-22 09:02:32 -0600595 VkResult U_ASSERT_ONLY err;
Tony Barbour96db8822015-02-25 12:28:39 -0700596
Chia-I Wuf8693382015-04-16 22:02:10 +0800597 VkSwapChainCreateInfoWSI swap_chain = {};
598 swap_chain.sType = VK_STRUCTURE_TYPE_SWAP_CHAIN_CREATE_INFO_WSI;
599 swap_chain.pNativeWindowSystemHandle = (void *) m_connection;
600 swap_chain.pNativeWindowHandle = (void *) (intptr_t) m_window;
601 swap_chain.imageCount = m_images.size();
602 swap_chain.imageFormat = VK_FORMAT_B8G8R8A8_UNORM;
603 swap_chain.imageExtent.width = m_width;
604 swap_chain.imageExtent.height = m_height;
605 swap_chain.imageArraySize = 1;
606 swap_chain.imageUsageFlags = VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT;
607 swap_chain.swapModeFlags = VK_SWAP_MODE_FLIP_BIT_WSI |
608 VK_SWAP_MODE_BLIT_BIT_WSI;
609
610 err = vkCreateSwapChainWSI(m_device.obj(), &swap_chain, &m_swap_chain);
611 assert(!err);
612
613 size_t size = sizeof(VkSwapChainImageInfoWSI) * m_images.size();
614 std::vector<VkSwapChainImageInfoWSI> persistent_images;
615 persistent_images.resize(m_images.size());
616 err = vkGetSwapChainInfoWSI(m_swap_chain,
617 VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI,
618 &size, &persistent_images[0]);
619 assert(!err && size == sizeof(VkSwapChainImageInfoWSI) * m_images.size());
620
Tony Barbour96db8822015-02-25 12:28:39 -0700621 m_display_image = m_images.begin();
622
623 for (int x=0; x < m_images.size(); x++)
624 {
Tony Barbour96db8822015-02-25 12:28:39 -0700625 void *dest_ptr;
626
Chia-I Wuf8693382015-04-16 22:02:10 +0800627 m_display_image->m_presentableImage = persistent_images[x].image;
628 m_display_image->m_presentableMemory = persistent_images[x].memory;
Tony Barbour96db8822015-02-25 12:28:39 -0700629
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600630 vk_testing::Buffer buf;
Courtney Goeltzenleuchter6636d1a2015-04-29 10:54:08 -0600631 VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
632 buf.init(m_device, (VkDeviceSize) m_display_image->m_data_size, flags);
Tony Barbour96db8822015-02-25 12:28:39 -0700633 dest_ptr = buf.map();
634 memcpy(dest_ptr,m_display_image->m_data, m_display_image->m_data_size);
635 buf.unmap();
636
637 m_cmdbuf.begin();
638
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600639 VkBufferImageCopy region = {};
Tony Barbour96db8822015-02-25 12:28:39 -0700640 region.imageExtent.height = m_display_image->m_height;
641 region.imageExtent.width = m_display_image->m_width;
642 region.imageExtent.depth = 1;
643
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600644 vkCmdCopyBufferToImage(m_cmdbuf.obj(),
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -0600645 buf.obj(),
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600646 m_display_image->m_presentableImage, VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL,
Courtney Goeltzenleuchterb3efe9b2015-03-25 11:25:10 -0600647 1, &region);
Tony Barbour96db8822015-02-25 12:28:39 -0700648 m_cmdbuf.end();
649
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600650 VkCmdBuffer cmdBufs[1];
Tony Barbour96db8822015-02-25 12:28:39 -0700651 cmdBufs[0] = m_cmdbuf.obj();
652
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600653 vkQueueSubmit(m_queue.obj(), 1, cmdBufs, NULL);
Tony Barbour96db8822015-02-25 12:28:39 -0700654 m_queue.wait();
655
Tony Barbour96db8822015-02-25 12:28:39 -0700656 ++m_display_image;
Tony Barbour96db8822015-02-25 12:28:39 -0700657 }
658
659 m_display_image = m_images.begin();
660}
661
Tony Barbour6918cd52015-04-09 12:58:51 -0600662void TestFrameworkVkPresent::InitPresentFramework(std::list<VkTestImageRecord> &imagesIn)
Tony Barbour96db8822015-02-25 12:28:39 -0700663{
664 m_images = imagesIn;
665}
666
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600667#ifdef _WIN32
668void TestFrameworkVkPresent::CreateMyWindow()
669{
670 WNDCLASSEX win_class;
671 // const ::testing::TestInfo* const test_info =
672 // ::testing::UnitTest::GetInstance()->current_test_info();
673 m_connection = GetModuleHandle(NULL);
674
675 for (std::list<VkTestImageRecord>::const_iterator it = m_images.begin();
676 it != m_images.end(); it++) {
677 if (m_width < it->m_width)
678 m_width = it->m_width;
679 if (m_height < it->m_height)
680 m_height = it->m_height;
681 }
682 // Initialize the window class structure:
683 win_class.cbSize = sizeof(WNDCLASSEX);
684 win_class.style = CS_HREDRAW | CS_VREDRAW;
685 win_class.lpfnWndProc = (WNDPROC) &TestFrameworkVkPresent::WndProc;
686 win_class.cbClsExtra = 0;
687 win_class.cbWndExtra = 0;
688 win_class.hInstance = m_connection; // hInstance
689 win_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
690 win_class.hCursor = LoadCursor(NULL, IDC_ARROW);
691 win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
692 win_class.lpszMenuName = NULL;
693 win_class.lpszClassName = "Test";
694 win_class.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
695 // Register window class:
696 if (!RegisterClassEx(&win_class)) {
697 // It didn't work, so try to give a useful error:
698 printf("Unexpected error trying to start the application!\n");
699 fflush(stdout);
700 exit(1);
701 }
702 // Create window with the registered class:
703 m_window = CreateWindowEx(0,
704 "Test", // class name
705 "Test", // app name
706 WS_OVERLAPPEDWINDOW | // window style
707 WS_VISIBLE |
708 WS_SYSMENU,
709 100,100, // x/y coords
710 m_width, // width
711 m_height, // height
712 NULL, // handle to parent
713 NULL, // handle to menu
714 m_connection, // hInstance
715 NULL); // no extra parameters
716
717 if (!m_window) {
718 // It didn't work, so try to give a useful error:
719 DWORD error = GetLastError();
720 char message[120];
721 sprintf(message, "Cannot create a window in which to draw!\n GetLastError = %d", error);
722 MessageBox(NULL, message, "Error", MB_OK);
723 exit(1);
724 }
725}
726#else
Tony Barbour6918cd52015-04-09 12:58:51 -0600727void TestFrameworkVkPresent::CreateMyWindow()
Tony Barbour96db8822015-02-25 12:28:39 -0700728{
Chia-I Wuf8693382015-04-16 22:02:10 +0800729 const xcb_setup_t *setup;
730 xcb_screen_iterator_t iter;
731 int scr;
Tony Barbour96db8822015-02-25 12:28:39 -0700732 uint32_t value_mask, value_list[32];
733
Chia-I Wuf8693382015-04-16 22:02:10 +0800734 m_connection = xcb_connect(NULL, &scr);
735
736 setup = xcb_get_setup(m_connection);
737 iter = xcb_setup_roots_iterator(setup);
738 while (scr-- > 0)
739 xcb_screen_next(&iter);
740
741 m_screen = iter.data;
742
743 for (std::list<VkTestImageRecord>::const_iterator it = m_images.begin();
744 it != m_images.end(); it++) {
745 if (m_width < it->m_width)
746 m_width = it->m_width;
747 if (m_height < it->m_height)
748 m_height = it->m_height;
749 }
750
751 m_window = xcb_generate_id(m_connection);
Tony Barbour96db8822015-02-25 12:28:39 -0700752
753 value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
Chia-I Wuf8693382015-04-16 22:02:10 +0800754 value_list[0] = m_screen->black_pixel;
Tony Barbour96db8822015-02-25 12:28:39 -0700755 value_list[1] = XCB_EVENT_MASK_KEY_RELEASE |
756 XCB_EVENT_MASK_EXPOSURE |
757 XCB_EVENT_MASK_STRUCTURE_NOTIFY;
758
Chia-I Wuf8693382015-04-16 22:02:10 +0800759 xcb_create_window(m_connection,
Tony Barbour96db8822015-02-25 12:28:39 -0700760 XCB_COPY_FROM_PARENT,
Chia-I Wuf8693382015-04-16 22:02:10 +0800761 m_window, m_screen->root,
Tony Barbour96db8822015-02-25 12:28:39 -0700762 0, 0, m_width, m_height, 0,
763 XCB_WINDOW_CLASS_INPUT_OUTPUT,
Chia-I Wuf8693382015-04-16 22:02:10 +0800764 m_screen->root_visual,
Tony Barbour96db8822015-02-25 12:28:39 -0700765 value_mask, value_list);
766
767 /* Magic code that will send notification when window is destroyed */
Chia-I Wuf8693382015-04-16 22:02:10 +0800768 xcb_intern_atom_cookie_t cookie = xcb_intern_atom(m_connection, 1, 12,
Tony Barbour96db8822015-02-25 12:28:39 -0700769 "WM_PROTOCOLS");
Chia-I Wuf8693382015-04-16 22:02:10 +0800770 xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(m_connection, cookie, 0);
Tony Barbour96db8822015-02-25 12:28:39 -0700771
Chia-I Wuf8693382015-04-16 22:02:10 +0800772 xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(m_connection, 0, 16, "WM_DELETE_WINDOW");
773 m_atom_wm_delete_window = xcb_intern_atom_reply(m_connection, cookie2, 0);
Tony Barbour96db8822015-02-25 12:28:39 -0700774
Chia-I Wuf8693382015-04-16 22:02:10 +0800775 xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE,
Tony Barbour96db8822015-02-25 12:28:39 -0700776 m_window, (*reply).atom, 4, 32, 1,
777 &(*m_atom_wm_delete_window).atom);
778 free(reply);
779
Chia-I Wuf8693382015-04-16 22:02:10 +0800780 xcb_map_window(m_connection, m_window);
Tony Barbour96db8822015-02-25 12:28:39 -0700781}
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600782#endif
Tony Barbour96db8822015-02-25 12:28:39 -0700783
Tony Barbour6918cd52015-04-09 12:58:51 -0600784void TestFrameworkVkPresent::TearDown()
Tony Barbour96db8822015-02-25 12:28:39 -0700785{
Chia-I Wuf8693382015-04-16 22:02:10 +0800786 vkDestroySwapChainWSI(m_swap_chain);
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600787#ifndef _WIN32
Chia-I Wuf8693382015-04-16 22:02:10 +0800788 xcb_destroy_window(m_connection, m_window);
789 xcb_disconnect(m_connection);
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600790#endif
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600791}
792
Tony Barbour6918cd52015-04-09 12:58:51 -0600793void VkTestFramework::Finish()
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600794{
795 if (m_images.size() == 0) return;
796
Chia-I Wuf8693382015-04-16 22:02:10 +0800797 vk_testing::Environment env;
798 env.SetUp();
Tony Barbour96db8822015-02-25 12:28:39 -0700799 {
Chia-I Wuf8693382015-04-16 22:02:10 +0800800 TestFrameworkVkPresent vkPresent(env.default_device());
Tony Barbour96db8822015-02-25 12:28:39 -0700801
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600802 vkPresent.InitPresentFramework(m_images);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600803 vkPresent.CreateMyWindow();
Chia-I Wuf8693382015-04-16 22:02:10 +0800804 vkPresent.CreateSwapChain();
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600805 vkPresent.Run();
806 vkPresent.TearDown();
Tony Barbour96db8822015-02-25 12:28:39 -0700807 }
Chia-I Wuf8693382015-04-16 22:02:10 +0800808 env.TearDown();
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600809}
810
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600811//
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600812// These are the default resources for TBuiltInResources, used for both
813// - parsing this string for the case where the user didn't supply one
814// - dumping out a template for user construction of a config file
815//
816static const char* DefaultConfig =
817 "MaxLights 32\n"
818 "MaxClipPlanes 6\n"
819 "MaxTextureUnits 32\n"
820 "MaxTextureCoords 32\n"
821 "MaxVertexAttribs 64\n"
822 "MaxVertexUniformComponents 4096\n"
823 "MaxVaryingFloats 64\n"
824 "MaxVertexTextureImageUnits 32\n"
825 "MaxCombinedTextureImageUnits 80\n"
826 "MaxTextureImageUnits 32\n"
827 "MaxFragmentUniformComponents 4096\n"
828 "MaxDrawBuffers 32\n"
829 "MaxVertexUniformVectors 128\n"
830 "MaxVaryingVectors 8\n"
831 "MaxFragmentUniformVectors 16\n"
832 "MaxVertexOutputVectors 16\n"
833 "MaxFragmentInputVectors 15\n"
834 "MinProgramTexelOffset -8\n"
835 "MaxProgramTexelOffset 7\n"
836 "MaxClipDistances 8\n"
837 "MaxComputeWorkGroupCountX 65535\n"
838 "MaxComputeWorkGroupCountY 65535\n"
839 "MaxComputeWorkGroupCountZ 65535\n"
840 "MaxComputeWorkGroupSizeX 1024\n"
841 "MaxComputeWorkGroupSizeY 1024\n"
842 "MaxComputeWorkGroupSizeZ 64\n"
843 "MaxComputeUniformComponents 1024\n"
844 "MaxComputeTextureImageUnits 16\n"
845 "MaxComputeImageUniforms 8\n"
846 "MaxComputeAtomicCounters 8\n"
847 "MaxComputeAtomicCounterBuffers 1\n"
848 "MaxVaryingComponents 60\n"
849 "MaxVertexOutputComponents 64\n"
850 "MaxGeometryInputComponents 64\n"
851 "MaxGeometryOutputComponents 128\n"
852 "MaxFragmentInputComponents 128\n"
853 "MaxImageUnits 8\n"
854 "MaxCombinedImageUnitsAndFragmentOutputs 8\n"
855 "MaxCombinedShaderOutputResources 8\n"
856 "MaxImageSamples 0\n"
857 "MaxVertexImageUniforms 0\n"
858 "MaxTessControlImageUniforms 0\n"
859 "MaxTessEvaluationImageUniforms 0\n"
860 "MaxGeometryImageUniforms 0\n"
861 "MaxFragmentImageUniforms 8\n"
862 "MaxCombinedImageUniforms 8\n"
863 "MaxGeometryTextureImageUnits 16\n"
864 "MaxGeometryOutputVertices 256\n"
865 "MaxGeometryTotalOutputComponents 1024\n"
866 "MaxGeometryUniformComponents 1024\n"
867 "MaxGeometryVaryingComponents 64\n"
868 "MaxTessControlInputComponents 128\n"
869 "MaxTessControlOutputComponents 128\n"
870 "MaxTessControlTextureImageUnits 16\n"
871 "MaxTessControlUniformComponents 1024\n"
872 "MaxTessControlTotalOutputComponents 4096\n"
873 "MaxTessEvaluationInputComponents 128\n"
874 "MaxTessEvaluationOutputComponents 128\n"
875 "MaxTessEvaluationTextureImageUnits 16\n"
876 "MaxTessEvaluationUniformComponents 1024\n"
877 "MaxTessPatchComponents 120\n"
878 "MaxPatchVertices 32\n"
879 "MaxTessGenLevel 64\n"
880 "MaxViewports 16\n"
881 "MaxVertexAtomicCounters 0\n"
882 "MaxTessControlAtomicCounters 0\n"
883 "MaxTessEvaluationAtomicCounters 0\n"
884 "MaxGeometryAtomicCounters 0\n"
885 "MaxFragmentAtomicCounters 8\n"
886 "MaxCombinedAtomicCounters 8\n"
887 "MaxAtomicCounterBindings 1\n"
888 "MaxVertexAtomicCounterBuffers 0\n"
889 "MaxTessControlAtomicCounterBuffers 0\n"
890 "MaxTessEvaluationAtomicCounterBuffers 0\n"
891 "MaxGeometryAtomicCounterBuffers 0\n"
892 "MaxFragmentAtomicCounterBuffers 1\n"
893 "MaxCombinedAtomicCounterBuffers 1\n"
894 "MaxAtomicCounterBufferSize 16384\n"
895 "MaxTransformFeedbackBuffers 4\n"
896 "MaxTransformFeedbackInterleavedComponents 64\n"
897 "MaxCullDistances 8\n"
898 "MaxCombinedClipAndCullDistances 8\n"
899 "MaxSamples 4\n"
900
901 "nonInductiveForLoops 1\n"
902 "whileLoops 1\n"
903 "doWhileLoops 1\n"
904 "generalUniformIndexing 1\n"
905 "generalAttributeMatrixVectorIndexing 1\n"
906 "generalVaryingIndexing 1\n"
907 "generalSamplerIndexing 1\n"
908 "generalVariableIndexing 1\n"
909 "generalConstantMatrixVectorIndexing 1\n"
910 ;
911
912//
913// *.conf => this is a config file that can set limits/resources
914//
Tony Barbour6918cd52015-04-09 12:58:51 -0600915bool VkTestFramework::SetConfigFile(const std::string& name)
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600916{
917 if (name.size() < 5)
918 return false;
919
920 if (name.compare(name.size() - 5, 5, ".conf") == 0) {
921 ConfigFile = name;
922 return true;
923 }
924
925 return false;
926}
927
928//
929// Parse either a .conf file provided by the user or the default string above.
930//
Tony Barbour6918cd52015-04-09 12:58:51 -0600931void VkTestFramework::ProcessConfigFile()
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600932{
933 char** configStrings = 0;
934 char* config = 0;
935 if (ConfigFile.size() > 0) {
936 configStrings = ReadFileData(ConfigFile.c_str());
937 if (configStrings)
938 config = *configStrings;
939 else {
940 printf("Error opening configuration file; will instead use the default configuration\n");
941 }
942 }
943
944 if (config == 0) {
945 config = new char[strlen(DefaultConfig) + 1];
946 strcpy(config, DefaultConfig);
947 }
948
949 const char* delims = " \t\n\r";
950 const char* token = strtok(config, delims);
951 while (token) {
952 const char* valueStr = strtok(0, delims);
953 if (valueStr == 0 || ! (valueStr[0] == '-' || (valueStr[0] >= '0' && valueStr[0] <= '9'))) {
954 printf("Error: '%s' bad .conf file. Each name must be followed by one number.\n", valueStr ? valueStr : "");
955 return;
956 }
957 int value = atoi(valueStr);
958
959 if (strcmp(token, "MaxLights") == 0)
960 Resources.maxLights = value;
961 else if (strcmp(token, "MaxClipPlanes") == 0)
962 Resources.maxClipPlanes = value;
963 else if (strcmp(token, "MaxTextureUnits") == 0)
964 Resources.maxTextureUnits = value;
965 else if (strcmp(token, "MaxTextureCoords") == 0)
966 Resources.maxTextureCoords = value;
967 else if (strcmp(token, "MaxVertexAttribs") == 0)
968 Resources.maxVertexAttribs = value;
969 else if (strcmp(token, "MaxVertexUniformComponents") == 0)
970 Resources.maxVertexUniformComponents = value;
971 else if (strcmp(token, "MaxVaryingFloats") == 0)
972 Resources.maxVaryingFloats = value;
973 else if (strcmp(token, "MaxVertexTextureImageUnits") == 0)
974 Resources.maxVertexTextureImageUnits = value;
975 else if (strcmp(token, "MaxCombinedTextureImageUnits") == 0)
976 Resources.maxCombinedTextureImageUnits = value;
977 else if (strcmp(token, "MaxTextureImageUnits") == 0)
978 Resources.maxTextureImageUnits = value;
979 else if (strcmp(token, "MaxFragmentUniformComponents") == 0)
980 Resources.maxFragmentUniformComponents = value;
981 else if (strcmp(token, "MaxDrawBuffers") == 0)
982 Resources.maxDrawBuffers = value;
983 else if (strcmp(token, "MaxVertexUniformVectors") == 0)
984 Resources.maxVertexUniformVectors = value;
985 else if (strcmp(token, "MaxVaryingVectors") == 0)
986 Resources.maxVaryingVectors = value;
987 else if (strcmp(token, "MaxFragmentUniformVectors") == 0)
988 Resources.maxFragmentUniformVectors = value;
989 else if (strcmp(token, "MaxVertexOutputVectors") == 0)
990 Resources.maxVertexOutputVectors = value;
991 else if (strcmp(token, "MaxFragmentInputVectors") == 0)
992 Resources.maxFragmentInputVectors = value;
993 else if (strcmp(token, "MinProgramTexelOffset") == 0)
994 Resources.minProgramTexelOffset = value;
995 else if (strcmp(token, "MaxProgramTexelOffset") == 0)
996 Resources.maxProgramTexelOffset = value;
997 else if (strcmp(token, "MaxClipDistances") == 0)
998 Resources.maxClipDistances = value;
999 else if (strcmp(token, "MaxComputeWorkGroupCountX") == 0)
1000 Resources.maxComputeWorkGroupCountX = value;
1001 else if (strcmp(token, "MaxComputeWorkGroupCountY") == 0)
1002 Resources.maxComputeWorkGroupCountY = value;
1003 else if (strcmp(token, "MaxComputeWorkGroupCountZ") == 0)
1004 Resources.maxComputeWorkGroupCountZ = value;
1005 else if (strcmp(token, "MaxComputeWorkGroupSizeX") == 0)
1006 Resources.maxComputeWorkGroupSizeX = value;
1007 else if (strcmp(token, "MaxComputeWorkGroupSizeY") == 0)
1008 Resources.maxComputeWorkGroupSizeY = value;
1009 else if (strcmp(token, "MaxComputeWorkGroupSizeZ") == 0)
1010 Resources.maxComputeWorkGroupSizeZ = value;
1011 else if (strcmp(token, "MaxComputeUniformComponents") == 0)
1012 Resources.maxComputeUniformComponents = value;
1013 else if (strcmp(token, "MaxComputeTextureImageUnits") == 0)
1014 Resources.maxComputeTextureImageUnits = value;
1015 else if (strcmp(token, "MaxComputeImageUniforms") == 0)
1016 Resources.maxComputeImageUniforms = value;
1017 else if (strcmp(token, "MaxComputeAtomicCounters") == 0)
1018 Resources.maxComputeAtomicCounters = value;
1019 else if (strcmp(token, "MaxComputeAtomicCounterBuffers") == 0)
1020 Resources.maxComputeAtomicCounterBuffers = value;
1021 else if (strcmp(token, "MaxVaryingComponents") == 0)
1022 Resources.maxVaryingComponents = value;
1023 else if (strcmp(token, "MaxVertexOutputComponents") == 0)
1024 Resources.maxVertexOutputComponents = value;
1025 else if (strcmp(token, "MaxGeometryInputComponents") == 0)
1026 Resources.maxGeometryInputComponents = value;
1027 else if (strcmp(token, "MaxGeometryOutputComponents") == 0)
1028 Resources.maxGeometryOutputComponents = value;
1029 else if (strcmp(token, "MaxFragmentInputComponents") == 0)
1030 Resources.maxFragmentInputComponents = value;
1031 else if (strcmp(token, "MaxImageUnits") == 0)
1032 Resources.maxImageUnits = value;
1033 else if (strcmp(token, "MaxCombinedImageUnitsAndFragmentOutputs") == 0)
1034 Resources.maxCombinedImageUnitsAndFragmentOutputs = value;
1035 else if (strcmp(token, "MaxCombinedShaderOutputResources") == 0)
1036 Resources.maxCombinedShaderOutputResources = value;
1037 else if (strcmp(token, "MaxImageSamples") == 0)
1038 Resources.maxImageSamples = value;
1039 else if (strcmp(token, "MaxVertexImageUniforms") == 0)
1040 Resources.maxVertexImageUniforms = value;
1041 else if (strcmp(token, "MaxTessControlImageUniforms") == 0)
1042 Resources.maxTessControlImageUniforms = value;
1043 else if (strcmp(token, "MaxTessEvaluationImageUniforms") == 0)
1044 Resources.maxTessEvaluationImageUniforms = value;
1045 else if (strcmp(token, "MaxGeometryImageUniforms") == 0)
1046 Resources.maxGeometryImageUniforms = value;
1047 else if (strcmp(token, "MaxFragmentImageUniforms") == 0)
1048 Resources.maxFragmentImageUniforms = value;
1049 else if (strcmp(token, "MaxCombinedImageUniforms") == 0)
1050 Resources.maxCombinedImageUniforms = value;
1051 else if (strcmp(token, "MaxGeometryTextureImageUnits") == 0)
1052 Resources.maxGeometryTextureImageUnits = value;
1053 else if (strcmp(token, "MaxGeometryOutputVertices") == 0)
1054 Resources.maxGeometryOutputVertices = value;
1055 else if (strcmp(token, "MaxGeometryTotalOutputComponents") == 0)
1056 Resources.maxGeometryTotalOutputComponents = value;
1057 else if (strcmp(token, "MaxGeometryUniformComponents") == 0)
1058 Resources.maxGeometryUniformComponents = value;
1059 else if (strcmp(token, "MaxGeometryVaryingComponents") == 0)
1060 Resources.maxGeometryVaryingComponents = value;
1061 else if (strcmp(token, "MaxTessControlInputComponents") == 0)
1062 Resources.maxTessControlInputComponents = value;
1063 else if (strcmp(token, "MaxTessControlOutputComponents") == 0)
1064 Resources.maxTessControlOutputComponents = value;
1065 else if (strcmp(token, "MaxTessControlTextureImageUnits") == 0)
1066 Resources.maxTessControlTextureImageUnits = value;
1067 else if (strcmp(token, "MaxTessControlUniformComponents") == 0)
1068 Resources.maxTessControlUniformComponents = value;
1069 else if (strcmp(token, "MaxTessControlTotalOutputComponents") == 0)
1070 Resources.maxTessControlTotalOutputComponents = value;
1071 else if (strcmp(token, "MaxTessEvaluationInputComponents") == 0)
1072 Resources.maxTessEvaluationInputComponents = value;
1073 else if (strcmp(token, "MaxTessEvaluationOutputComponents") == 0)
1074 Resources.maxTessEvaluationOutputComponents = value;
1075 else if (strcmp(token, "MaxTessEvaluationTextureImageUnits") == 0)
1076 Resources.maxTessEvaluationTextureImageUnits = value;
1077 else if (strcmp(token, "MaxTessEvaluationUniformComponents") == 0)
1078 Resources.maxTessEvaluationUniformComponents = value;
1079 else if (strcmp(token, "MaxTessPatchComponents") == 0)
1080 Resources.maxTessPatchComponents = value;
1081 else if (strcmp(token, "MaxPatchVertices") == 0)
1082 Resources.maxPatchVertices = value;
1083 else if (strcmp(token, "MaxTessGenLevel") == 0)
1084 Resources.maxTessGenLevel = value;
1085 else if (strcmp(token, "MaxViewports") == 0)
1086 Resources.maxViewports = value;
1087 else if (strcmp(token, "MaxVertexAtomicCounters") == 0)
1088 Resources.maxVertexAtomicCounters = value;
1089 else if (strcmp(token, "MaxTessControlAtomicCounters") == 0)
1090 Resources.maxTessControlAtomicCounters = value;
1091 else if (strcmp(token, "MaxTessEvaluationAtomicCounters") == 0)
1092 Resources.maxTessEvaluationAtomicCounters = value;
1093 else if (strcmp(token, "MaxGeometryAtomicCounters") == 0)
1094 Resources.maxGeometryAtomicCounters = value;
1095 else if (strcmp(token, "MaxFragmentAtomicCounters") == 0)
1096 Resources.maxFragmentAtomicCounters = value;
1097 else if (strcmp(token, "MaxCombinedAtomicCounters") == 0)
1098 Resources.maxCombinedAtomicCounters = value;
1099 else if (strcmp(token, "MaxAtomicCounterBindings") == 0)
1100 Resources.maxAtomicCounterBindings = value;
1101 else if (strcmp(token, "MaxVertexAtomicCounterBuffers") == 0)
1102 Resources.maxVertexAtomicCounterBuffers = value;
1103 else if (strcmp(token, "MaxTessControlAtomicCounterBuffers") == 0)
1104 Resources.maxTessControlAtomicCounterBuffers = value;
1105 else if (strcmp(token, "MaxTessEvaluationAtomicCounterBuffers") == 0)
1106 Resources.maxTessEvaluationAtomicCounterBuffers = value;
1107 else if (strcmp(token, "MaxGeometryAtomicCounterBuffers") == 0)
1108 Resources.maxGeometryAtomicCounterBuffers = value;
1109 else if (strcmp(token, "MaxFragmentAtomicCounterBuffers") == 0)
1110 Resources.maxFragmentAtomicCounterBuffers = value;
1111 else if (strcmp(token, "MaxCombinedAtomicCounterBuffers") == 0)
1112 Resources.maxCombinedAtomicCounterBuffers = value;
1113 else if (strcmp(token, "MaxAtomicCounterBufferSize") == 0)
1114 Resources.maxAtomicCounterBufferSize = value;
1115 else if (strcmp(token, "MaxTransformFeedbackBuffers") == 0)
1116 Resources.maxTransformFeedbackBuffers = value;
1117 else if (strcmp(token, "MaxTransformFeedbackInterleavedComponents") == 0)
1118 Resources.maxTransformFeedbackInterleavedComponents = value;
1119 else if (strcmp(token, "MaxCullDistances") == 0)
1120 Resources.maxCullDistances = value;
1121 else if (strcmp(token, "MaxCombinedClipAndCullDistances") == 0)
1122 Resources.maxCombinedClipAndCullDistances = value;
1123 else if (strcmp(token, "MaxSamples") == 0)
1124 Resources.maxSamples = value;
1125
1126 else if (strcmp(token, "nonInductiveForLoops") == 0)
1127 Resources.limits.nonInductiveForLoops = (value != 0);
1128 else if (strcmp(token, "whileLoops") == 0)
1129 Resources.limits.whileLoops = (value != 0);
1130 else if (strcmp(token, "doWhileLoops") == 0)
1131 Resources.limits.doWhileLoops = (value != 0);
1132 else if (strcmp(token, "generalUniformIndexing") == 0)
1133 Resources.limits.generalUniformIndexing = (value != 0);
1134 else if (strcmp(token, "generalAttributeMatrixVectorIndexing") == 0)
1135 Resources.limits.generalAttributeMatrixVectorIndexing = (value != 0);
1136 else if (strcmp(token, "generalVaryingIndexing") == 0)
1137 Resources.limits.generalVaryingIndexing = (value != 0);
1138 else if (strcmp(token, "generalSamplerIndexing") == 0)
1139 Resources.limits.generalSamplerIndexing = (value != 0);
1140 else if (strcmp(token, "generalVariableIndexing") == 0)
1141 Resources.limits.generalVariableIndexing = (value != 0);
1142 else if (strcmp(token, "generalConstantMatrixVectorIndexing") == 0)
1143 Resources.limits.generalConstantMatrixVectorIndexing = (value != 0);
1144 else
1145 printf("Warning: unrecognized limit (%s) in configuration file.\n", token);
1146
1147 token = strtok(0, delims);
1148 }
1149 if (configStrings)
1150 FreeFileData(configStrings);
1151}
1152
Tony Barbour6918cd52015-04-09 12:58:51 -06001153void VkTestFramework::SetMessageOptions(EShMessages& messages)
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001154{
1155 if (m_compile_options & EOptionRelaxedErrors)
1156 messages = (EShMessages)(messages | EShMsgRelaxedErrors);
1157 if (m_compile_options & EOptionIntermediate)
1158 messages = (EShMessages)(messages | EShMsgAST);
1159 if (m_compile_options & EOptionSuppressWarnings)
1160 messages = (EShMessages)(messages | EShMsgSuppressWarnings);
1161}
1162
1163//
1164// Malloc a string of sufficient size and read a string into it.
1165//
Tony Barbour6918cd52015-04-09 12:58:51 -06001166char** VkTestFramework::ReadFileData(const char* fileName)
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001167{
1168 FILE *in;
1169 #if defined(_WIN32) && defined(__GNUC__)
1170 in = fopen(fileName, "r");
1171 int errorCode = in ? 0 : 1;
1172 #else
1173 int errorCode = fopen_s(&in, fileName, "r");
1174 #endif
1175
1176 char *fdata;
1177 int count = 0;
1178 const int maxSourceStrings = 5;
1179 char** return_data = (char**)malloc(sizeof(char *) * (maxSourceStrings+1));
1180
1181 if (errorCode) {
1182 printf("Error: unable to open input file: %s\n", fileName);
1183 return 0;
1184 }
1185
1186 while (fgetc(in) != EOF)
1187 count++;
1188
1189 fseek(in, 0, SEEK_SET);
1190
1191 if (!(fdata = (char*)malloc(count+2))) {
1192 printf("Error allocating memory\n");
1193 return 0;
1194 }
1195 if (fread(fdata,1,count, in)!=count) {
1196 printf("Error reading input file: %s\n", fileName);
1197 return 0;
1198 }
1199 fdata[count] = '\0';
1200 fclose(in);
1201 if (count == 0) {
1202 return_data[0]=(char*)malloc(count+2);
1203 return_data[0][0]='\0';
1204 m_num_shader_strings = 0;
1205 return return_data;
1206 } else
1207 m_num_shader_strings = 1;
1208
1209 int len = (int)(ceil)((float)count/(float)m_num_shader_strings);
1210 int ptr_len=0,i=0;
1211 while(count>0){
1212 return_data[i]=(char*)malloc(len+2);
1213 memcpy(return_data[i],fdata+ptr_len,len);
1214 return_data[i][len]='\0';
1215 count-=(len);
1216 ptr_len+=(len);
1217 if(count<len){
1218 if(count==0){
1219 m_num_shader_strings=(i+1);
1220 break;
1221 }
1222 len = count;
1223 }
1224 ++i;
1225 }
1226 return return_data;
1227}
1228
Tony Barbour6918cd52015-04-09 12:58:51 -06001229void VkTestFramework::FreeFileData(char** data)
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001230{
1231 for(int i=0;i<m_num_shader_strings;i++)
1232 free(data[i]);
1233}
1234
1235//
1236// Deduce the language from the filename. Files must end in one of the
1237// following extensions:
1238//
1239// .vert = vertex
1240// .tesc = tessellation control
1241// .tese = tessellation evaluation
1242// .geom = geometry
1243// .frag = fragment
1244// .comp = compute
1245//
Tony Barbour6918cd52015-04-09 12:58:51 -06001246EShLanguage VkTestFramework::FindLanguage(const std::string& name)
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001247{
1248 size_t ext = name.rfind('.');
1249 if (ext == std::string::npos) {
1250 return EShLangVertex;
1251 }
1252
1253 std::string suffix = name.substr(ext + 1, std::string::npos);
1254 if (suffix == "vert")
1255 return EShLangVertex;
1256 else if (suffix == "tesc")
1257 return EShLangTessControl;
1258 else if (suffix == "tese")
1259 return EShLangTessEvaluation;
1260 else if (suffix == "geom")
1261 return EShLangGeometry;
1262 else if (suffix == "frag")
1263 return EShLangFragment;
1264 else if (suffix == "comp")
1265 return EShLangCompute;
1266
1267 return EShLangVertex;
1268}
1269
1270//
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001271// Convert VK shader type to compiler's
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001272//
Tony Barbourd1c35722015-04-16 15:59:00 -06001273EShLanguage VkTestFramework::FindLanguage(const VkShaderStage shader_type)
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001274{
1275 switch (shader_type) {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001276 case VK_SHADER_STAGE_VERTEX:
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001277 return EShLangVertex;
1278
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001279 case VK_SHADER_STAGE_TESS_CONTROL:
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001280 return EShLangTessControl;
1281
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001282 case VK_SHADER_STAGE_TESS_EVALUATION:
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001283 return EShLangTessEvaluation;
1284
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001285 case VK_SHADER_STAGE_GEOMETRY:
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001286 return EShLangGeometry;
1287
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001288 case VK_SHADER_STAGE_FRAGMENT:
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001289 return EShLangFragment;
1290
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001291 case VK_SHADER_STAGE_COMPUTE:
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001292 return EShLangCompute;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001293
Chia-I Wub4c2aa42014-12-15 23:50:11 +08001294 default:
1295 return EShLangVertex;
1296 }
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001297}
1298
1299
1300//
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001301// Compile a given string containing GLSL into SPV for use by VK
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001302// Return value of false means an error was encountered.
1303//
Tony Barbourd1c35722015-04-16 15:59:00 -06001304bool VkTestFramework::GLSLtoSPV(const VkShaderStage shader_type,
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001305 const char *pshader,
Cody Northrop3bfd27c2015-03-17 15:55:58 -06001306 std::vector<unsigned int> &spv)
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001307{
1308 glslang::TProgram& program = *new glslang::TProgram;
1309 const char *shaderStrings[1];
1310
1311 // TODO: Do we want to load a special config file depending on the
1312 // shader source? Optional name maybe?
1313 // SetConfigFile(fileName);
1314
1315 ProcessConfigFile();
1316
1317 EShMessages messages = EShMsgDefault;
1318 SetMessageOptions(messages);
1319
1320 EShLanguage stage = FindLanguage(shader_type);
1321 glslang::TShader* shader = new glslang::TShader(stage);
1322
1323 shaderStrings[0] = pshader;
1324 shader->setStrings(shaderStrings, 1);
1325
1326 if (! shader->parse(&Resources, (m_compile_options & EOptionDefaultDesktop) ? 110 : 100, false, messages)) {
1327
Cody Northrop195d6622014-11-03 12:54:37 -07001328 if (! (m_compile_options & EOptionSuppressInfolog)) {
1329 puts(shader->getInfoLog());
1330 puts(shader->getInfoDebugLog());
1331 }
1332
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001333 return false; // something didn't work
1334 }
1335
1336 program.addShader(shader);
1337
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001338
1339 //
1340 // Program-level processing...
1341 //
1342
Cody Northrop195d6622014-11-03 12:54:37 -07001343 if (! program.link(messages)) {
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001344
Cody Northrop195d6622014-11-03 12:54:37 -07001345 if (! (m_compile_options & EOptionSuppressInfolog)) {
1346 puts(shader->getInfoLog());
1347 puts(shader->getInfoDebugLog());
1348 }
1349
1350 return false;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001351 }
1352
1353 if (m_compile_options & EOptionDumpReflection) {
1354 program.buildReflection();
1355 program.dumpReflection();
1356 }
1357
Cody Northrop3bfd27c2015-03-17 15:55:58 -06001358 glslang::GlslangToSpv(*program.getIntermediate(stage), spv);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001359
1360 return true;
1361}
1362
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001363
1364
Tony Barbour6918cd52015-04-09 12:58:51 -06001365VkTestImageRecord::VkTestImageRecord() : // Constructor
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001366 m_width( 0 ),
1367 m_height( 0 ),
Chia-I Wu837f9952014-12-15 23:29:34 +08001368 m_data( NULL ),
Tony Barbour96db8822015-02-25 12:28:39 -07001369 m_presentableImage( NULL ),
1370 m_presentableMemory( NULL),
Chia-I Wu837f9952014-12-15 23:29:34 +08001371 m_data_size( 0 )
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001372{
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001373}
1374
Tony Barbour6918cd52015-04-09 12:58:51 -06001375VkTestImageRecord::~VkTestImageRecord()
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001376{
1377
1378}
1379
Tony Barbour6918cd52015-04-09 12:58:51 -06001380VkTestImageRecord::VkTestImageRecord(const VkTestImageRecord &copyin) // Copy constructor to handle pass by value.
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001381{
1382 m_title = copyin.m_title;
1383 m_width = copyin.m_width;
1384 m_height = copyin.m_height;
1385 m_data_size = copyin.m_data_size;
1386 m_data = copyin.m_data; // TODO: Do we need to copy the data or is pointer okay?
Tony Barbour96db8822015-02-25 12:28:39 -07001387 m_presentableImage = copyin.m_presentableImage;
1388 m_presentableMemory = copyin.m_presentableMemory;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001389}
1390
Tony Barbour6918cd52015-04-09 12:58:51 -06001391ostream &operator<<(ostream &output, const VkTestImageRecord &VkTestImageRecord)
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001392{
Tony Barbour6918cd52015-04-09 12:58:51 -06001393 output << VkTestImageRecord.m_title << " (" << VkTestImageRecord.m_width <<
1394 "," << VkTestImageRecord.m_height << ")" << endl;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001395 return output;
1396}
1397
Tony Barbour6918cd52015-04-09 12:58:51 -06001398VkTestImageRecord& VkTestImageRecord::operator=(const VkTestImageRecord &rhs)
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001399{
1400 m_title = rhs.m_title;
1401 m_width = rhs.m_width;
1402 m_height = rhs.m_height;
1403 m_data_size = rhs.m_data_size;
1404 m_data = rhs.m_data;
Tony Barbour96db8822015-02-25 12:28:39 -07001405 m_presentableImage = rhs.m_presentableImage;
1406 m_presentableMemory = rhs.m_presentableMemory;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001407 return *this;
1408}
1409
Tony Barbour6918cd52015-04-09 12:58:51 -06001410int VkTestImageRecord::operator==(const VkTestImageRecord &rhs) const
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001411{
1412 if( this->m_data != rhs.m_data) return 0;
1413 return 1;
1414}
1415
1416// This function is required for built-in STL list functions like sort
Tony Barbour6918cd52015-04-09 12:58:51 -06001417int VkTestImageRecord::operator<(const VkTestImageRecord &rhs) const
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001418{
1419 if( this->m_data_size < rhs.m_data_size ) return 1;
1420 return 0;
1421}
1422