blob: 1851eed8fbcbc8f5cdd6bbbd637ffb48e9f40722 [file] [log] [blame]
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001// VK tests
Courtney Goeltzenleuchterd0d7ccc2014-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 Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060023#include "vktestframework.h"
24#include "vkrenderframework.h"
Cody Northropeb9130e2015-06-03 13:01:54 -060025#include "SPIRV/GlslangToSpv.h"
26#include "SPIRV/SPVRemapper.h"
Tony Barbour772c5ef2014-12-10 17:00:20 -070027#include <limits.h>
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -060028#include <math.h>
Chia-I Wu3d9ebb22014-12-02 11:54:24 +080029#include <wand/MagickWand.h>
Chia-I Wu5b66aa52015-04-16 22:02:10 +080030#include <xcb/xcb.h>
Ian Elliott338dedb2015-08-21 15:09:33 -060031#include "vk_ext_khr_swapchain.h"
32#include "vk_ext_khr_device_swapchain.h"
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -060033
Tony Barbour25e3b832015-05-20 16:53:31 -060034#if defined(PATH_MAX) && !defined(MAX_PATH)
35#define MAX_PATH PATH_MAX
36#endif
37
Tony Barbourb3744222015-07-23 10:36:18 -060038#ifdef _WIN32
39#define ERR_EXIT(err_msg, err_class) \
40 do { \
41 MessageBox(NULL, err_msg, err_class, MB_OK); \
42 exit(1); \
43 } while (0)
44#else // _WIN32
45
46#define ERR_EXIT(err_msg, err_class) \
47 do { \
48 printf(err_msg); \
49 fflush(stdout); \
50 exit(1); \
51 } while (0)
52#endif // _WIN32
53
54#define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \
55{ \
56 m_fp##entrypoint = (PFN_vk##entrypoint) vkGetInstanceProcAddr(inst, "vk"#entrypoint); \
57 if (m_fp##entrypoint == NULL) { \
58 ERR_EXIT("vkGetInstanceProcAddr failed to find vk"#entrypoint, \
59 "vkGetInstanceProcAddr Failure"); \
60 } \
61}
62
63#define GET_DEVICE_PROC_ADDR(dev, entrypoint) \
64{ \
65 m_fp##entrypoint = (PFN_vk##entrypoint) vkGetDeviceProcAddr(dev, "vk"#entrypoint); \
66 if (m_fp##entrypoint == NULL) { \
67 ERR_EXIT("vkGetDeviceProcAddr failed to find vk"#entrypoint, \
68 "vkGetDeviceProcAddr Failure"); \
69 } \
70}
71
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -060072// Command-line options
73enum TOptions {
74 EOptionNone = 0x000,
75 EOptionIntermediate = 0x001,
76 EOptionSuppressInfolog = 0x002,
77 EOptionMemoryLeakMode = 0x004,
78 EOptionRelaxedErrors = 0x008,
79 EOptionGiveWarnings = 0x010,
80 EOptionLinkProgram = 0x020,
81 EOptionMultiThreaded = 0x040,
82 EOptionDumpConfig = 0x080,
83 EOptionDumpReflection = 0x100,
84 EOptionSuppressWarnings = 0x200,
85 EOptionDumpVersions = 0x400,
Cody Northropacfb0492015-03-17 15:55:58 -060086 EOptionSpv = 0x800,
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -060087 EOptionDefaultDesktop = 0x1000,
88};
89
Ian Elliott338dedb2015-08-21 15:09:33 -060090typedef struct _SwapchainBuffers {
Tony Barbourb3744222015-07-23 10:36:18 -060091 VkImage image;
92 VkCmdBuffer cmd;
Courtney Goeltzenleuchter1856d6f2015-09-01 17:30:39 -060093 VkImageView view;
Ian Elliott338dedb2015-08-21 15:09:33 -060094} SwapchainBuffers;
Tony Barbourb3744222015-07-23 10:36:18 -060095
Chia-I Wu5b66aa52015-04-16 22:02:10 +080096class TestFrameworkVkPresent
97{
98public:
99 TestFrameworkVkPresent(vk_testing::Device &device);
100
101 void Run();
Jon Ashburncedc15f2015-05-21 18:13:33 -0600102 void InitPresentFramework(std::list<VkTestImageRecord> &imagesIn, VkInstance inst);
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800103 void CreateMyWindow();
Ian Elliott338dedb2015-08-21 15:09:33 -0600104 void CreateSwapchain();
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800105 void TearDown();
Tony Barbour25e3b832015-05-20 16:53:31 -0600106#ifdef _WIN32
107 static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
108#endif
109
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800110
111protected:
112 vk_testing::Device &m_device;
113 vk_testing::Queue &m_queue;
Dana Jansens6e2dda12015-07-30 13:04:16 -0700114 vk_testing::CmdPool m_cmdpool;
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800115 vk_testing::CmdBuffer m_cmdbuf;
116
117private:
Tony Barbour25e3b832015-05-20 16:53:31 -0600118#ifdef _WIN32
119 HINSTANCE m_connection; // hInstance - Windows Instance
120 HWND m_window; // hWnd - window handle
121
122#else
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800123 xcb_connection_t *m_connection;
124 xcb_screen_t *m_screen;
125 xcb_window_t m_window;
126 xcb_intern_atom_reply_t *m_atom_wm_delete_window;
Ian Elliott338dedb2015-08-21 15:09:33 -0600127 VkPlatformHandleXcbKHR m_platform_handle_xcb;
Tony Barbour25e3b832015-05-20 16:53:31 -0600128#endif
Courtney Goeltzenleuchterec69b9c2015-04-22 10:09:35 -0600129 std::list<VkTestImageRecord> m_images;
Tony Barbourb3744222015-07-23 10:36:18 -0600130 uint32_t m_present_queue_node_index;
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800131
Ian Elliott338dedb2015-08-21 15:09:33 -0600132 PFN_vkGetPhysicalDeviceSurfaceSupportKHR m_fpGetPhysicalDeviceSurfaceSupportKHR;
133 PFN_vkGetSurfacePropertiesKHR m_fpGetSurfacePropertiesKHR;
134 PFN_vkGetSurfaceFormatsKHR m_fpGetSurfaceFormatsKHR;
135 PFN_vkGetSurfacePresentModesKHR m_fpGetSurfacePresentModesKHR;
136 PFN_vkCreateSwapchainKHR m_fpCreateSwapchainKHR;
137 PFN_vkDestroySwapchainKHR m_fpDestroySwapchainKHR;
138 PFN_vkGetSwapchainImagesKHR m_fpGetSwapchainImagesKHR;
139 PFN_vkAcquireNextImageKHR m_fpAcquireNextImageKHR;
140 PFN_vkQueuePresentKHR m_fpQueuePresentKHR;
141 VkSurfaceDescriptionWindowKHR m_surface_description;
142 uint32_t m_swapchainImageCount;
143 VkSwapchainKHR m_swap_chain;
144 SwapchainBuffers *m_buffers;
Tony Barbourb3744222015-07-23 10:36:18 -0600145 VkFormat m_format;
Ian Elliott338dedb2015-08-21 15:09:33 -0600146 VkColorSpaceKHR m_color_space;
Tony Barbourb3744222015-07-23 10:36:18 -0600147
148 uint32_t m_current_buffer;
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800149
150 bool m_quit;
151 bool m_pause;
152
Tony Barbour8bef8ee2015-05-22 09:44:58 -0600153 int m_width;
154 int m_height;
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800155
156 std::list<VkTestImageRecord>::iterator m_display_image;
157
158 void Display();
159 void HandleEvent(xcb_generic_event_t *event);
160};
161
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -0600162#ifndef _WIN32
163
164#include <errno.h>
165
166int fopen_s(
167 FILE** pFile,
168 const char* filename,
169 const char* mode
170)
171{
172 if (!pFile || !filename || !mode) {
173 return EINVAL;
174 }
175
176 FILE* f = fopen(filename, mode);
177 if (! f) {
178 if (errno != 0) {
179 return errno;
180 } else {
181 return ENOENT;
182 }
183 }
184 *pFile = f;
185
186 return 0;
187}
188
189#endif
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600190
Tony Barbour25e3b832015-05-20 16:53:31 -0600191
192
Courtney Goeltzenleuchterf12c7762014-10-08 08:46:51 -0600193// Set up environment for GLSL compiler
194// Must be done once per process
195void TestEnvironment::SetUp()
196{
Cody Northropacfb0492015-03-17 15:55:58 -0600197 // Initialize GLSL to SPV compiler utility
Courtney Goeltzenleuchterf12c7762014-10-08 08:46:51 -0600198 glslang::InitializeProcess();
Chia-I Wu1c9869e2014-12-28 14:27:28 +0800199
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600200 vk_testing::set_error_callback(test_error_callback);
Courtney Goeltzenleuchterf12c7762014-10-08 08:46:51 -0600201}
202
203void TestEnvironment::TearDown()
204{
205 glslang::FinalizeProcess();
206}
207
Tony Barbour01999182015-04-09 12:58:51 -0600208VkTestFramework::VkTestFramework() :
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -0600209 m_compile_options( 0 ),
210 m_num_shader_strings( 0 )
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600211{
Courtney Goeltzenleuchterf12c7762014-10-08 08:46:51 -0600212
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -0600213}
214
Tony Barbour01999182015-04-09 12:58:51 -0600215VkTestFramework::~VkTestFramework()
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -0600216{
Courtney Goeltzenleuchterf12c7762014-10-08 08:46:51 -0600217
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600218}
219
220// Define all the static elements
Cody Northropa392a292015-06-09 13:00:45 -0600221bool VkTestFramework::m_show_images = false;
222bool VkTestFramework::m_save_images = false;
223bool VkTestFramework::m_compare_images = false;
224bool VkTestFramework::m_use_glsl = false;
225bool VkTestFramework::m_canonicalize_spv = false;
226bool VkTestFramework::m_strip_spv = false;
Cody Northropeb9130e2015-06-03 13:01:54 -0600227bool VkTestFramework::m_do_everything_spv = false;
Tony Barbour01999182015-04-09 12:58:51 -0600228int VkTestFramework::m_width = 0;
229int VkTestFramework::m_height = 0;
230std::list<VkTestImageRecord> VkTestFramework::m_images;
231std::list<VkTestImageRecord>::iterator VkTestFramework::m_display_image;
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600232int m_display_image_idx = 0;
233
Cody Northrop1cfbd172015-06-03 16:49:20 -0600234bool VkTestFramework::optionMatch(const char* option, char* optionLine)
235{
236 if (strncmp(option, optionLine, strlen(option)) == 0)
237 return true;
238 else
239 return false;
240}
241
Tony Barbour01999182015-04-09 12:58:51 -0600242void VkTestFramework::InitArgs(int *argc, char *argv[])
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600243{
244 int i, n;
245
Cody Northrop1cfbd172015-06-03 16:49:20 -0600246 for (i=1, n=1; i< *argc; i++) {
247 if (optionMatch("--show-images", argv[i]))
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600248 m_show_images = true;
Cody Northrop1cfbd172015-06-03 16:49:20 -0600249 else if (optionMatch("--save-images", argv[i]))
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600250 m_save_images = true;
Cody Northrop1cfbd172015-06-03 16:49:20 -0600251 else if (optionMatch("--no-SPV", argv[i]))
252 m_use_glsl = true;
253 else if (optionMatch("--strip-SPV", argv[i]))
254 m_strip_spv = true;
255 else if (optionMatch("--canonicalize-SPV", argv[i]))
256 m_canonicalize_spv = true;
257 else if (optionMatch("--compare-images", argv[i]))
Tony Barbour32f368c2014-10-30 14:29:04 -0600258 m_compare_images = true;
Tony Barbour32f368c2014-10-30 14:29:04 -0600259
Cody Northrop1cfbd172015-06-03 16:49:20 -0600260 else if (optionMatch("--help", argv[i]) ||
261 optionMatch("-h", argv[i])) {
Courtney Goeltzenleuchterb7f26e02014-12-02 13:13:10 -0700262 printf("\nOther options:\n");
263 printf("\t--show-images\n"
264 "\t\tDisplay test images in viewer after tests complete.\n");
265 printf("\t--save-images\n"
266 "\t\tSave tests images as ppm files in current working directory.\n"
267 "\t\tUsed to generate golden images for compare-images.\n");
268 printf("\t--compare-images\n"
269 "\t\tCompare test images to 'golden' image in golden folder.\n"
Tony Barbour0e4235d2014-12-11 09:52:49 -0700270 "\t\tAlso saves the generated test image in current working\n"
271 "\t\t\tdirectory but only if the image is different from the golden\n"
272 "\t\tSetting RENDERTEST_GOLDEN_DIR environment variable can specify\n"
273 "\t\t\tdifferent directory for golden images\n"
Courtney Goeltzenleuchterb7f26e02014-12-02 13:13:10 -0700274 "\t\tSignal test failure if different.\n");
Cody Northropacfb0492015-03-17 15:55:58 -0600275 printf("\t--no-SPV\n"
276 "\t\tUse built-in GLSL compiler rather than SPV code path.\n");
Cody Northrop1cfbd172015-06-03 16:49:20 -0600277 printf("\t--strip-SPV\n"
Cody Northrop1e056dd2015-07-13 12:48:41 -0600278 "\t\tStrip SPIR-V debug information (line numbers, names, etc).\n");
Cody Northrop1cfbd172015-06-03 16:49:20 -0600279 printf("\t--canonicalize-SPV\n"
Cody Northrop1e056dd2015-07-13 12:48:41 -0600280 "\t\tRemap SPIR-V ids before submission to aid compression.\n");
Cody Northrop1cfbd172015-06-03 16:49:20 -0600281 exit(0);
282 } else {
283 printf("\nUnrecognized option: %s\n", argv[i]);
284 printf("\nUse --help or -h for option list.\n");
Tony Barbour772c5ef2014-12-10 17:00:20 -0700285 exit(0);
Courtney Goeltzenleuchterb7f26e02014-12-02 13:13:10 -0700286 }
287
Cody Northrop1cfbd172015-06-03 16:49:20 -0600288 /*
289 * Since the above "consume" inputs, update argv
290 * so that it contains the trimmed list of args for glutInit
291 */
292
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600293 argv[n] = argv[i];
294 n++;
295 }
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600296}
297
Tony Barbour01999182015-04-09 12:58:51 -0600298void VkTestFramework::WritePPM( const char *basename, VkImageObj *image )
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600299{
300 string filename;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600301 VkResult err;
Tony Barbour8bef8ee2015-05-22 09:44:58 -0600302 uint32_t x, y;
Tony Barbour01999182015-04-09 12:58:51 -0600303 VkImageObj displayImage(image->device());
Tony Barbour94310562015-04-22 15:10:33 -0600304 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
Tony Barbouredc49d92015-04-02 14:02:33 -0600305
Tony Barboura7ec3ba2015-07-21 17:01:42 -0600306 displayImage.init(image->extent().width, image->extent().height, image->format(), VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT, VK_IMAGE_TILING_LINEAR, reqs);
Tony Barbouredc49d92015-04-02 14:02:33 -0600307 displayImage.CopyImage(*image);
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600308
309 filename.append(basename);
310 filename.append(".ppm");
Tony Barbour25e3b832015-05-20 16:53:31 -0600311
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600312 const VkImageSubresource sr = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600313 VK_IMAGE_ASPECT_COLOR, 0, 0
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600314 };
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600315 VkSubresourceLayout sr_layout;
Tony Barbour25e3b832015-05-20 16:53:31 -0600316
Tony Barbour426b9052015-06-24 16:06:58 -0600317 err = vkGetImageSubresourceLayout(image->device()->device(), displayImage.image(), &sr, &sr_layout);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600318 ASSERT_VK_SUCCESS( err );
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600319
Tony Barbouredc49d92015-04-02 14:02:33 -0600320 char *ptr;
Chia-I Wuf4aed6c2015-07-03 13:44:34 +0800321 ptr = (char *) displayImage.MapMemory();
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600322 ptr += sr_layout.offset;
Tony Barbour25e3b832015-05-20 16:53:31 -0600323 ofstream file (filename.c_str(), ios::binary);
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600324 ASSERT_TRUE(file.is_open()) << "Unable to open file: " << filename;
325
326 file << "P6\n";
Tony Barbouredc49d92015-04-02 14:02:33 -0600327 file << displayImage.width() << "\n";
328 file << displayImage.height() << "\n";
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600329 file << 255 << "\n";
330
Tony Barbouredc49d92015-04-02 14:02:33 -0600331 for (y = 0; y < displayImage.height(); y++) {
Tony Barboure2668672015-02-25 11:25:11 -0700332 const int *row = (const int *) ptr;
333 int swapped;
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600334
Tony Barbour8205d902015-04-16 15:59:00 -0600335 if (displayImage.format() == VK_FORMAT_B8G8R8A8_UNORM)
Tony Barboure2668672015-02-25 11:25:11 -0700336 {
Tony Barbouredc49d92015-04-02 14:02:33 -0600337 for (x = 0; x < displayImage.width(); x++) {
Tony Barboure2668672015-02-25 11:25:11 -0700338 swapped = (*row & 0xff00ff00) | (*row & 0x000000ff) << 16 | (*row & 0x00ff0000) >> 16;
339 file.write((char *) &swapped, 3);
340 row++;
341 }
342 }
Tony Barbour8205d902015-04-16 15:59:00 -0600343 else if (displayImage.format() == VK_FORMAT_R8G8B8A8_UNORM)
Tony Barboure2668672015-02-25 11:25:11 -0700344 {
Tony Barbouredc49d92015-04-02 14:02:33 -0600345 for (x = 0; x < displayImage.width(); x++) {
Tony Barboure2668672015-02-25 11:25:11 -0700346 file.write((char *) row, 3);
347 row++;
348 }
349 }
350 else {
351 printf("Unrecognized image format - will not write image files");
352 break;
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600353 }
354
355 ptr += sr_layout.rowPitch;
356 }
357
358 file.close();
Chia-I Wuf4aed6c2015-07-03 13:44:34 +0800359 displayImage.UnmapMemory();
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600360}
361
Tony Barbour01999182015-04-09 12:58:51 -0600362void VkTestFramework::Compare(const char *basename, VkImageObj *image )
Tony Barbour32f368c2014-10-30 14:29:04 -0600363{
364
365 MagickWand *magick_wand_1;
366 MagickWand *magick_wand_2;
367 MagickWand *compare_wand;
368 MagickBooleanType status;
Tony Barbour25e3b832015-05-20 16:53:31 -0600369 char testimage[256],golden[MAX_PATH+256],golddir[MAX_PATH] = "./golden";
Tony Barbour32f368c2014-10-30 14:29:04 -0600370 double differenz;
371
Tony Barbour772c5ef2014-12-10 17:00:20 -0700372 if (getenv("RENDERTEST_GOLDEN_DIR"))
373 {
374 strcpy(golddir,getenv("RENDERTEST_GOLDEN_DIR"));
375 }
376
Tony Barbour32f368c2014-10-30 14:29:04 -0600377 MagickWandGenesis();
378 magick_wand_1=NewMagickWand();
379 sprintf(testimage,"%s.ppm",basename);
380 status=MagickReadImage(magick_wand_1,testimage);
Tony Barbour8bef8ee2015-05-22 09:44:58 -0600381 ASSERT_EQ(status, MagickTrue) << "Unable to open file: " << testimage;
Tony Barbour32f368c2014-10-30 14:29:04 -0600382
383
384 MagickWandGenesis();
385 magick_wand_2=NewMagickWand();
Tony Barbour772c5ef2014-12-10 17:00:20 -0700386 sprintf(golden,"%s/%s.ppm",golddir,basename);
Tony Barbour32f368c2014-10-30 14:29:04 -0600387 status=MagickReadImage(magick_wand_2,golden);
Tony Barbour8bef8ee2015-05-22 09:44:58 -0600388 ASSERT_EQ(status, MagickTrue) << "Unable to open file: " << golden;
Tony Barbour32f368c2014-10-30 14:29:04 -0600389
Tony Barbour32f368c2014-10-30 14:29:04 -0600390 compare_wand=MagickCompareImages(magick_wand_1,magick_wand_2, MeanAbsoluteErrorMetric, &differenz);
391 if (differenz != 0.0)
392 {
393 char difference[256];
394
395 sprintf(difference,"%s-diff.ppm",basename);
396 status = MagickWriteImage(compare_wand, difference);
397 ASSERT_TRUE(differenz == 0.0) << "Image comparison failed - diff file written";
398 }
399 DestroyMagickWand(compare_wand);
400
401 DestroyMagickWand(magick_wand_1);
402 DestroyMagickWand(magick_wand_2);
403 MagickWandTerminus();
Courtney Goeltzenleuchterdfa97b82014-12-05 15:41:02 -0700404
405 if (differenz == 0.0)
406 {
407 /*
408 * If test image and golden image match, we do not need to
409 * keep around the test image.
410 */
411 remove(testimage);
412 }
Tony Barbour32f368c2014-10-30 14:29:04 -0600413}
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600414
Tony Barbour01999182015-04-09 12:58:51 -0600415void VkTestFramework::Show(const char *comment, VkImageObj *image)
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600416{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600417 VkResult err;
Courtney Goeltzenleuchtere5871c72015-04-29 10:53:31 -0600418 VkSubresourceLayout sr_layout;
419 char *ptr;
420 VkTestImageRecord record;
Courtney Goeltzenleuchtere5871c72015-04-29 10:53:31 -0600421 VkImageObj displayImage(image->device());
422 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
423
Cody Northrop025cbb12015-06-18 17:05:15 -0600424 displayImage.init(image->extent().width, image->extent().height, image->format(), VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT, VK_IMAGE_TILING_LINEAR, reqs);
425
Courtney Goeltzenleuchtere5871c72015-04-29 10:53:31 -0600426 displayImage.CopyImage(*image);
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600427
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600428 const VkImageSubresource sr = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600429 VK_IMAGE_ASPECT_COLOR, 0, 0
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600430 };
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600431
Tony Barbour426b9052015-06-24 16:06:58 -0600432 err = vkGetImageSubresourceLayout(displayImage.device()->device(), displayImage.image(), &sr, &sr_layout);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600433 ASSERT_VK_SUCCESS( err );
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600434
Chia-I Wuf4aed6c2015-07-03 13:44:34 +0800435 ptr = (char *) displayImage.MapMemory();
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600436 ASSERT_VK_SUCCESS( err );
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600437
438 ptr += sr_layout.offset;
439
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600440 record.m_title.append(comment);
Courtney Goeltzenleuchtere5871c72015-04-29 10:53:31 -0600441 record.m_width = displayImage.width();
442 record.m_height = displayImage.height();
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600443 // TODO: Need to make this more robust to handle different image formats
Tony-LunarGf05ba082015-05-19 14:08:26 -0600444 record.m_data_size = displayImage.width() * displayImage.height() * 4;
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600445 record.m_data = malloc(record.m_data_size);
446 memcpy(record.m_data, ptr, record.m_data_size);
447 m_images.push_back(record);
448 m_display_image = --m_images.end();
449
Chia-I Wuf4aed6c2015-07-03 13:44:34 +0800450 displayImage.UnmapMemory();
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600451}
452
Tony Barbour01999182015-04-09 12:58:51 -0600453void VkTestFramework::RecordImages(vector<VkImageObj *> images)
Tony Barbour32f368c2014-10-30 14:29:04 -0600454{
Courtney Goeltzenleuchtercd5ed1e2015-04-02 14:17:44 -0600455 for (int32_t i = 0; i < images.size(); i++) {
456 RecordImage(images[i]);
Tony Barbour32f368c2014-10-30 14:29:04 -0600457 }
458}
459
Tony Barbour01999182015-04-09 12:58:51 -0600460void VkTestFramework::RecordImage(VkImageObj * image)
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600461{
462 const ::testing::TestInfo* const test_info =
463 ::testing::UnitTest::GetInstance()->current_test_info();
Tony Barbour32f368c2014-10-30 14:29:04 -0600464 ostringstream filestream;
465 string filename;
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600466
Tony Barbour32f368c2014-10-30 14:29:04 -0600467 m_width = 40;
468
469 if (strcmp(test_info->name(), m_testName.c_str())) {
470 filestream << test_info->name();
471 m_testName.assign(test_info->name());
Tony Barboura48b0812014-11-18 17:02:36 -0700472 m_frameNum = 2;
473 filename = filestream.str();
Tony Barbour32f368c2014-10-30 14:29:04 -0600474 }
475 else {
476 filestream << test_info->name() << "-" << m_frameNum;
477 m_frameNum++;
Tony Barboura48b0812014-11-18 17:02:36 -0700478 filename = filestream.str();
Tony Barbour32f368c2014-10-30 14:29:04 -0600479 }
480
Tony Barbour32f368c2014-10-30 14:29:04 -0600481 // ToDo - scrub string for bad characters
482
483 if (m_save_images || m_compare_images) {
484 WritePPM(filename.c_str(), image);
485 if (m_compare_images) {
486 Compare(filename.c_str(), image);
487 }
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600488 }
489
490 if (m_show_images) {
Courtney Goeltzenleuchtere5409342014-10-08 14:26:40 -0600491 Show(test_info->name(), image);
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600492 }
493}
494
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800495TestFrameworkVkPresent::TestFrameworkVkPresent(vk_testing::Device &device) :
496 m_device(device),
Courtney Goeltzenleuchterdd745fd2015-03-05 16:47:18 -0700497 m_queue(*m_device.graphics_queues()[0]),
Dana Jansens6e2dda12015-07-30 13:04:16 -0700498 m_cmdpool(m_device, vk_testing::CmdPool::create_info(m_device.graphics_queue_node_index_)),
499 m_cmdbuf(m_device, vk_testing::CmdBuffer::create_info(m_cmdpool.handle()))
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600500{
Tony Barbouref20d322015-02-25 12:28:39 -0700501 m_quit = false;
502 m_pause = false;
503 m_width = 0;
504 m_height = 0;
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600505}
506
Tony Barbour01999182015-04-09 12:58:51 -0600507void TestFrameworkVkPresent::Display()
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600508{
Tony Barbour22a30862015-04-22 09:02:32 -0600509 VkResult U_ASSERT_ONLY err;
Tony-LunarGf05ba082015-05-19 14:08:26 -0600510 vk_testing::Buffer buf;
511 void *dest_ptr;
512
Tony Barbourb3744222015-07-23 10:36:18 -0600513 VkSemaphore presentCompleteSemaphore;
514 VkSemaphoreCreateInfo presentCompleteSemaphoreCreateInfo = {};
515 presentCompleteSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
516 presentCompleteSemaphoreCreateInfo.pNext = NULL;
517 presentCompleteSemaphoreCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
518
519
520 err = vkCreateSemaphore(m_device.handle(),
521 &presentCompleteSemaphoreCreateInfo,
522 &presentCompleteSemaphore);
523 assert(!err);
524
525 // Get the index of the next available swapchain image:
Ian Elliott338dedb2015-08-21 15:09:33 -0600526 err = m_fpAcquireNextImageKHR(m_device.handle(), m_swap_chain,
Tony Barbourb3744222015-07-23 10:36:18 -0600527 UINT64_MAX,
528 presentCompleteSemaphore,
529 &m_current_buffer);
Ian Elliott338dedb2015-08-21 15:09:33 -0600530 // TODO: Deal with the VK_SUBOPTIMAL_KHR and VK_ERROR_OUT_OF_DATE_KHR
Tony Barbourb3744222015-07-23 10:36:18 -0600531 // return codes
532 assert(!err);
533
534 // Wait for the present complete semaphore to be signaled to ensure
535 // that the image won't be rendered to until the presentation
536 // engine has fully released ownership to the application, and it is
537 // okay to render to the image.
538 vkQueueWaitSemaphore(m_queue.handle(), presentCompleteSemaphore);
Tony-LunarGf05ba082015-05-19 14:08:26 -0600539
540 VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
Cody Northropd0e7d222015-06-22 14:56:14 -0600541 buf.init_as_src(m_device, (VkDeviceSize)m_display_image->m_data_size, flags);
Chia-I Wuf4aed6c2015-07-03 13:44:34 +0800542 dest_ptr = buf.memory().map();
Tony-LunarGf05ba082015-05-19 14:08:26 -0600543 memcpy(dest_ptr, m_display_image->m_data, m_display_image->m_data_size);
Chia-I Wuf4aed6c2015-07-03 13:44:34 +0800544 buf.memory().unmap();
Tony-LunarGf05ba082015-05-19 14:08:26 -0600545
546 m_cmdbuf.begin();
547
548 VkBufferImageCopy region = {};
549 region.imageExtent.height = m_display_image->m_height;
550 region.imageExtent.width = m_display_image->m_width;
551 region.imageExtent.depth = 1;
552
Chia-I Wu78c2a352015-07-03 11:49:42 +0800553 vkCmdCopyBufferToImage(m_cmdbuf.handle(),
Chia-I Wuf4aed6c2015-07-03 13:44:34 +0800554 buf.handle(),
Tony Barbourb3744222015-07-23 10:36:18 -0600555 m_buffers[m_current_buffer].image, VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL,
Tony-LunarGf05ba082015-05-19 14:08:26 -0600556 1, &region);
557 m_cmdbuf.end();
558
559 VkCmdBuffer cmdBufs[1];
Chia-I Wu78c2a352015-07-03 11:49:42 +0800560 cmdBufs[0] = m_cmdbuf.handle();
Tony-LunarGf05ba082015-05-19 14:08:26 -0600561
Tony Barboure84a8d62015-07-10 14:10:27 -0600562 VkFence nullFence = { VK_NULL_HANDLE };
563 vkQueueSubmit(m_queue.handle(), 1, cmdBufs, nullFence);
Tony-LunarGf05ba082015-05-19 14:08:26 -0600564 m_queue.wait();
Tony Barbouref20d322015-02-25 12:28:39 -0700565
Ian Elliott338dedb2015-08-21 15:09:33 -0600566 VkPresentInfoKHR present = {};
567 present.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
Tony Barbourb3744222015-07-23 10:36:18 -0600568 present.pNext = NULL;
Ian Elliott338dedb2015-08-21 15:09:33 -0600569 present.swapchainCount = 1;
570 present.swapchains = & m_swap_chain;
Tony Barbourb3744222015-07-23 10:36:18 -0600571 present.imageIndices = &m_current_buffer;
Tony Barbouref20d322015-02-25 12:28:39 -0700572
Tony Barbour25e3b832015-05-20 16:53:31 -0600573#ifndef _WIN32
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800574 xcb_change_property (m_connection,
Tony Barbouref20d322015-02-25 12:28:39 -0700575 XCB_PROP_MODE_REPLACE,
576 m_window,
577 XCB_ATOM_WM_NAME,
578 XCB_ATOM_STRING,
579 8,
580 m_display_image->m_title.size(),
581 m_display_image->m_title.c_str());
Tony Barbour25e3b832015-05-20 16:53:31 -0600582#endif
Jon Ashburncedc15f2015-05-21 18:13:33 -0600583
Ian Elliott338dedb2015-08-21 15:09:33 -0600584 err = m_fpQueuePresentKHR(m_queue.handle(), &present);
Tony Barbouref20d322015-02-25 12:28:39 -0700585 assert(!err);
586
587 m_queue.wait();
Tony-LunarGf05ba082015-05-19 14:08:26 -0600588 m_current_buffer = (m_current_buffer + 1) % 2;
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600589}
590
Tony Barbour25e3b832015-05-20 16:53:31 -0600591#ifdef _WIN32
Tony-LunarGf05ba082015-05-19 14:08:26 -0600592# define PREVIOUSLY_DOWN 1<<29
Tony Barbour25e3b832015-05-20 16:53:31 -0600593// MS-Windows event handling function:
594LRESULT CALLBACK TestFrameworkVkPresent::WndProc(HWND hWnd,
595 UINT uMsg,
596 WPARAM wParam,
597 LPARAM lParam)
598{
599
600 switch(uMsg)
601 {
602 case WM_CLOSE:
603 PostQuitMessage(0);
604 break;
605
606 case WM_PAINT:
607 {
608 TestFrameworkVkPresent* me = reinterpret_cast<TestFrameworkVkPresent*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
609 if (me) {
Tony-LunarGf05ba082015-05-19 14:08:26 -0600610 SetWindowText(hWnd, me->m_display_image->m_title.c_str());
Tony Barbour25e3b832015-05-20 16:53:31 -0600611 me->Display();
612 }
613 }
Tony-LunarGf05ba082015-05-19 14:08:26 -0600614 break;
615
616 case WM_KEYDOWN:
617 {
618 if (lParam & (PREVIOUSLY_DOWN)){
619 break;
620 }
621 // To be able to be a CALLBACK, WndProc had to be static, so it doesn't get a this pointer. When we created
622 // the window, we put the this pointer into the window's user data so we could get it back now
623 TestFrameworkVkPresent* me = reinterpret_cast<TestFrameworkVkPresent*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
624 switch (wParam)
625 {
626 case VK_ESCAPE: me->m_quit = true;
627 break;
628
629 case VK_LEFT: // left arrow key
630 if (me->m_display_image == me->m_images.begin()) {
631 me->m_display_image = --me->m_images.end();
632 }
633 else {
634 --me->m_display_image;
635 }
636 break;
637
638 case VK_RIGHT: // right arrow key
639 ++me->m_display_image;
640 if (me->m_display_image == me->m_images.end()) {
641 me->m_display_image = me->m_images.begin();
642 }
643 break;
644
645 default:
646 break;
647 }
648 SetWindowText(hWnd, me->m_display_image->m_title.c_str());
649 me->Display();
650 }
Tony Barbour25e3b832015-05-20 16:53:31 -0600651 }
652 return (DefWindowProc(hWnd, uMsg, wParam, lParam));
653}
654
655void TestFrameworkVkPresent::Run()
656{
657 MSG msg; // message
Tony Barbour25e3b832015-05-20 16:53:31 -0600658
Tony Barbour25e3b832015-05-20 16:53:31 -0600659 /* main message loop*/
Tony-LunarGf05ba082015-05-19 14:08:26 -0600660 while(! m_quit) {
661 GetMessage(&msg, m_window, 0, 0);
Tony Barbour25e3b832015-05-20 16:53:31 -0600662 if (msg.message == WM_QUIT) {
Tony-LunarGf05ba082015-05-19 14:08:26 -0600663 m_quit = true; //if found, quit app
Tony Barbour25e3b832015-05-20 16:53:31 -0600664 } else {
665 /* Translate and dispatch to event queue*/
666 TranslateMessage(&msg);
667 DispatchMessage(&msg);
668 }
669 }
670}
671
672#else
Tony Barbour01999182015-04-09 12:58:51 -0600673void TestFrameworkVkPresent::HandleEvent(xcb_generic_event_t *event)
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600674{
Tony Barbour3a5cda02015-04-02 15:48:24 -0600675 uint8_t event_code = event->response_type & 0x7f;
Tony Barbouref20d322015-02-25 12:28:39 -0700676 switch (event_code) {
677 case XCB_EXPOSE:
678 Display(); // TODO: handle resize
679 break;
680 case XCB_CLIENT_MESSAGE:
681 if((*(xcb_client_message_event_t*)event).data.data32[0] ==
682 (m_atom_wm_delete_window)->atom) {
683 m_quit = true;
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600684 }
685 break;
Tony Barbouref20d322015-02-25 12:28:39 -0700686 case XCB_KEY_RELEASE:
687 {
688 const xcb_key_release_event_t *key =
689 (const xcb_key_release_event_t *) event;
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600690
Tony Barbouref20d322015-02-25 12:28:39 -0700691 switch (key->detail) {
692 case 0x9: // Escape
693 m_quit = true;
694 break;
695 case 0x71: // left arrow key
696 if (m_display_image == m_images.begin()) {
697 m_display_image = --m_images.end();
698 } else {
699 --m_display_image;
700 }
701 break;
702 case 0x72: // right arrow key
703 ++m_display_image;
704 if (m_display_image == m_images.end()) {
705 m_display_image = m_images.begin();
706 }
707 break;
708 case 0x41:
709 m_pause = !m_pause;
710 break;
711 }
712 Display();
713 }
714 break;
715 default:
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -0600716 break;
717 }
Tony Barbouref20d322015-02-25 12:28:39 -0700718}
719
Tony Barbour01999182015-04-09 12:58:51 -0600720void TestFrameworkVkPresent::Run()
Tony Barbouref20d322015-02-25 12:28:39 -0700721{
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800722 xcb_flush(m_connection);
Tony Barbouref20d322015-02-25 12:28:39 -0700723
724 while (! m_quit) {
725 xcb_generic_event_t *event;
726
727 if (m_pause) {
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800728 event = xcb_wait_for_event(m_connection);
Tony Barbouref20d322015-02-25 12:28:39 -0700729 } else {
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800730 event = xcb_poll_for_event(m_connection);
Tony Barbouref20d322015-02-25 12:28:39 -0700731 }
732 if (event) {
733 HandleEvent(event);
734 free(event);
735 }
736 }
737}
Tony Barbour25e3b832015-05-20 16:53:31 -0600738#endif // _WIN32
Tony Barbouref20d322015-02-25 12:28:39 -0700739
Ian Elliott338dedb2015-08-21 15:09:33 -0600740void TestFrameworkVkPresent::CreateSwapchain()
Tony Barbouref20d322015-02-25 12:28:39 -0700741{
Tony Barbour22a30862015-04-22 09:02:32 -0600742 VkResult U_ASSERT_ONLY err;
Tony Barbouref20d322015-02-25 12:28:39 -0700743
Tony-LunarGf05ba082015-05-19 14:08:26 -0600744 m_display_image = m_images.begin();
745 m_current_buffer = 0;
746
Tony Barbourb3744222015-07-23 10:36:18 -0600747 // Construct the WSI surface description:
Ian Elliott338dedb2015-08-21 15:09:33 -0600748 m_surface_description.sType = VK_STRUCTURE_TYPE_SURFACE_DESCRIPTION_WINDOW_KHR;
Tony Barbourb3744222015-07-23 10:36:18 -0600749 m_surface_description.pNext = NULL;
Ian Elliott331f4e82015-07-06 14:33:04 -0600750#ifdef _WIN32
Ian Elliott338dedb2015-08-21 15:09:33 -0600751 m_surface_description.platform = VK_PLATFORM_WIN32_KHR;
Tony Barbourb3744222015-07-23 10:36:18 -0600752 m_surface_description.pPlatformHandle = m_connection;
753 m_surface_description.pPlatformWindow = m_window;
Ian Elliott331f4e82015-07-06 14:33:04 -0600754#else // _WIN32
Tony Barbourb3744222015-07-23 10:36:18 -0600755 m_platform_handle_xcb.connection = m_connection;
756 m_platform_handle_xcb.root = m_screen->root;
Ian Elliott338dedb2015-08-21 15:09:33 -0600757 m_surface_description.platform = VK_PLATFORM_XCB_KHR;
Tony Barbourb3744222015-07-23 10:36:18 -0600758 m_surface_description.pPlatformHandle = &m_platform_handle_xcb;
759 m_surface_description.pPlatformWindow = &m_window;
Ian Elliott331f4e82015-07-06 14:33:04 -0600760#endif // _WIN32
Tony Barbourb3744222015-07-23 10:36:18 -0600761
762 // Iterate over each queue to learn whether it supports presenting to WSI:
763 VkBool32 supportsPresent;
764 m_present_queue_node_index = UINT32_MAX;
765 std::vector<vk_testing::Queue *> queues = m_device.graphics_queues();
766 for (int i=0; i < queues.size(); i++)
767 {
768 int family_index = queues[i]->get_family_index();
Ian Elliott338dedb2015-08-21 15:09:33 -0600769 m_fpGetPhysicalDeviceSurfaceSupportKHR(m_device.phy().handle(),
Tony Barbourb3744222015-07-23 10:36:18 -0600770 family_index,
Ian Elliott338dedb2015-08-21 15:09:33 -0600771 (VkSurfaceDescriptionKHR *) &m_surface_description,
Tony Barbourb3744222015-07-23 10:36:18 -0600772 &supportsPresent);
773 if (supportsPresent) {
774 m_present_queue_node_index = family_index;
775 }
776 }
777
778 assert(m_present_queue_node_index != UINT32_MAX);
779
780
781 // Get the list of VkFormat's that are supported:
Ian Elliottdad13202015-08-07 11:51:12 -0600782 uint32_t formatCount;
Ian Elliott338dedb2015-08-21 15:09:33 -0600783 err = m_fpGetSurfaceFormatsKHR(m_device.handle(),
784 (VkSurfaceDescriptionKHR *) &m_surface_description,
Ian Elliottdad13202015-08-07 11:51:12 -0600785 &formatCount, NULL);
Tony Barbourb3744222015-07-23 10:36:18 -0600786 assert(!err);
Ian Elliott338dedb2015-08-21 15:09:33 -0600787 VkSurfaceFormatKHR *surfFormats =
788 (VkSurfaceFormatKHR *)malloc(formatCount * sizeof(VkSurfaceFormatKHR));
789 err = m_fpGetSurfaceFormatsKHR(m_device.handle(),
790 (VkSurfaceDescriptionKHR *) &m_surface_description,
Ian Elliottdad13202015-08-07 11:51:12 -0600791 &formatCount, surfFormats);
Tony Barbourb3744222015-07-23 10:36:18 -0600792 assert(!err);
793 // If the format list includes just one entry of VK_FORMAT_UNDEFINED,
794 // the surface has no preferred format. Otherwise, at least one
795 // supported format will be returned.
Tony Barbourb3744222015-07-23 10:36:18 -0600796 if (formatCount == 1 && surfFormats[0].format == VK_FORMAT_UNDEFINED)
797 {
798 m_format = VK_FORMAT_B8G8R8A8_UNORM;
799 }
800 else
801 {
802 assert(formatCount >= 1);
803 m_format = surfFormats[0].format;
804 }
Ian Elliottdad13202015-08-07 11:51:12 -0600805 m_color_space = surfFormats[0].colorSpace;
Tony Barbourb3744222015-07-23 10:36:18 -0600806
807 // Check the surface proprties and formats
Ian Elliott338dedb2015-08-21 15:09:33 -0600808 VkSurfacePropertiesKHR surfProperties;
809 err = m_fpGetSurfacePropertiesKHR(m_device.handle(),
810 (const VkSurfaceDescriptionKHR *)&m_surface_description,
Ian Elliottdad13202015-08-07 11:51:12 -0600811 &surfProperties);
Tony Barbourb3744222015-07-23 10:36:18 -0600812 assert(!err);
813
Ian Elliottdad13202015-08-07 11:51:12 -0600814 uint32_t presentModeCount;
Ian Elliott338dedb2015-08-21 15:09:33 -0600815 err = m_fpGetSurfacePresentModesKHR(m_device.handle(),
816 (const VkSurfaceDescriptionKHR *)&m_surface_description,
Ian Elliottdad13202015-08-07 11:51:12 -0600817 &presentModeCount, NULL);
Tony Barbourb3744222015-07-23 10:36:18 -0600818 assert(!err);
Ian Elliott338dedb2015-08-21 15:09:33 -0600819 VkPresentModeKHR *presentModes =
820 (VkPresentModeKHR *)malloc(presentModeCount * sizeof(VkPresentModeKHR));
Ian Elliottdad13202015-08-07 11:51:12 -0600821 assert(presentModes);
Ian Elliott338dedb2015-08-21 15:09:33 -0600822 err = m_fpGetSurfacePresentModesKHR(m_device.handle(),
823 (const VkSurfaceDescriptionKHR *)&m_surface_description,
Ian Elliottdad13202015-08-07 11:51:12 -0600824 &presentModeCount, presentModes);
Tony Barbourb3744222015-07-23 10:36:18 -0600825 assert(!err);
826
Ian Elliott338dedb2015-08-21 15:09:33 -0600827 VkExtent2D swapchainExtent;
Tony Barbourb3744222015-07-23 10:36:18 -0600828 // width and height are either both -1, or both not -1.
Ian Elliottdad13202015-08-07 11:51:12 -0600829 if (surfProperties.currentExtent.width == -1)
Tony Barbourb3744222015-07-23 10:36:18 -0600830 {
831 // If the surface size is undefined, the size is set to
832 // the size of the images requested.
Ian Elliott338dedb2015-08-21 15:09:33 -0600833 swapchainExtent.width = m_width;
834 swapchainExtent.height = m_height;
Tony Barbourb3744222015-07-23 10:36:18 -0600835 }
836 else
837 {
838 // If the surface size is defined, the swap chain size must match
Ian Elliott338dedb2015-08-21 15:09:33 -0600839 swapchainExtent = surfProperties.currentExtent;
Tony Barbourb3744222015-07-23 10:36:18 -0600840 }
841
842 // If mailbox mode is available, use it, as is the lowest-latency non-
Ian Elliotta96de0f2015-08-10 13:20:49 -0600843 // tearing mode. If not, try IMMEDIATE which will usually be available,
844 // and is fastest (though it tears). If not, fall back to FIFO which is
845 // always available.
Ian Elliott338dedb2015-08-21 15:09:33 -0600846 VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
Tony Barbourb3744222015-07-23 10:36:18 -0600847 for (size_t i = 0; i < presentModeCount; i++) {
Ian Elliott338dedb2015-08-21 15:09:33 -0600848 if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
849 swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
Tony Barbourb3744222015-07-23 10:36:18 -0600850 break;
851 }
Ian Elliott338dedb2015-08-21 15:09:33 -0600852 if ((swapchainPresentMode != VK_PRESENT_MODE_MAILBOX_KHR) &&
853 (presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR)) {
854 swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
Ian Elliotta96de0f2015-08-10 13:20:49 -0600855 }
Tony Barbourb3744222015-07-23 10:36:18 -0600856 }
857
858 // Determine the number of VkImage's to use in the swap chain (we desire to
859 // own only 1 image at a time, besides the images being displayed and
860 // queued for display):
Ian Elliott338dedb2015-08-21 15:09:33 -0600861 uint32_t desiredNumberOfSwapchainImages = surfProperties.minImageCount + 1;
Ian Elliottdad13202015-08-07 11:51:12 -0600862 if ((surfProperties.maxImageCount > 0) &&
Ian Elliott338dedb2015-08-21 15:09:33 -0600863 (desiredNumberOfSwapchainImages > surfProperties.maxImageCount))
Tony Barbourb3744222015-07-23 10:36:18 -0600864 {
865 // Application must settle for fewer images than desired:
Ian Elliott338dedb2015-08-21 15:09:33 -0600866 desiredNumberOfSwapchainImages = surfProperties.maxImageCount;
Tony Barbourb3744222015-07-23 10:36:18 -0600867 }
868
Ian Elliott338dedb2015-08-21 15:09:33 -0600869 VkSurfaceTransformKHR preTransform;
870 if (surfProperties.supportedTransforms & VK_SURFACE_TRANSFORM_NONE_BIT_KHR) {
871 preTransform = VK_SURFACE_TRANSFORM_NONE_KHR;
Tony Barbourb3744222015-07-23 10:36:18 -0600872 } else {
Ian Elliottdad13202015-08-07 11:51:12 -0600873 preTransform = surfProperties.currentTransform;
Tony Barbourb3744222015-07-23 10:36:18 -0600874 }
Ian Elliott331f4e82015-07-06 14:33:04 -0600875
Cody Northrop3b0a3ef2015-08-28 16:22:48 -0600876 // We want to blit to the swap chain, ensure the driver supports it. Color is always supported, per WSI spec.
877 assert((surfProperties.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT) != 0);
878
Ian Elliott338dedb2015-08-21 15:09:33 -0600879 VkSwapchainCreateInfoKHR swap_chain = {};
880 swap_chain.sType = VK_STRUCTURE_TYPE_SWAP_CHAIN_CREATE_INFO_KHR;
Ian Elliott331f4e82015-07-06 14:33:04 -0600881 swap_chain.pNext = NULL;
Ian Elliott338dedb2015-08-21 15:09:33 -0600882 swap_chain.pSurfaceDescription = (const VkSurfaceDescriptionKHR *)&m_surface_description;
883 swap_chain.minImageCount = desiredNumberOfSwapchainImages;
Tony Barbourb3744222015-07-23 10:36:18 -0600884 swap_chain.imageFormat = m_format;
Ian Elliottdad13202015-08-07 11:51:12 -0600885 swap_chain.imageColorSpace = m_color_space;
Ian Elliott338dedb2015-08-21 15:09:33 -0600886 swap_chain.imageExtent.width = swapchainExtent.width;
887 swap_chain.imageExtent.height = swapchainExtent.height;
Cody Northrop7f815382015-08-05 15:38:39 -0600888 swap_chain.imageUsageFlags = VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT |
889 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
Tony Barbourb3744222015-07-23 10:36:18 -0600890 swap_chain.preTransform = preTransform;
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800891 swap_chain.imageArraySize = 1;
Ian Elliottdad13202015-08-07 11:51:12 -0600892 swap_chain.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
893 swap_chain.queueFamilyCount = 0;
894 swap_chain.pQueueFamilyIndices = NULL;
Ian Elliott338dedb2015-08-21 15:09:33 -0600895 swap_chain.presentMode = swapchainPresentMode;
896 swap_chain.oldSwapchain.handle = 0;
Tony Barbourb3744222015-07-23 10:36:18 -0600897 swap_chain.clipped = true;
898
899 uint32_t i;
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800900
Ian Elliott338dedb2015-08-21 15:09:33 -0600901 err = m_fpCreateSwapchainKHR(m_device.handle(), &swap_chain, &m_swap_chain);
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800902 assert(!err);
903
Ian Elliott338dedb2015-08-21 15:09:33 -0600904 err = m_fpGetSwapchainImagesKHR(m_device.handle(), m_swap_chain,
905 &m_swapchainImageCount, NULL);
Tony Barbourb3744222015-07-23 10:36:18 -0600906 assert(!err);
907
Ian Elliott338dedb2015-08-21 15:09:33 -0600908 VkImage* swapchainImages = (VkImage*)malloc(m_swapchainImageCount * sizeof(VkImage));
909 assert(swapchainImages);
910 err = m_fpGetSwapchainImagesKHR(m_device.handle(), m_swap_chain,
911 &m_swapchainImageCount, swapchainImages);
Tony Barbourb3744222015-07-23 10:36:18 -0600912 assert(!err);
913
Ian Elliott338dedb2015-08-21 15:09:33 -0600914 m_buffers = (SwapchainBuffers*)malloc(sizeof(SwapchainBuffers)*m_swapchainImageCount);
Tony Barbourb3744222015-07-23 10:36:18 -0600915 assert(m_buffers);
916
Ian Elliott338dedb2015-08-21 15:09:33 -0600917 for (i = 0; i < m_swapchainImageCount; i++) {
Courtney Goeltzenleuchter1856d6f2015-09-01 17:30:39 -0600918 VkImageViewCreateInfo color_image_view = {};
919 color_image_view.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
920 color_image_view.pNext = NULL;
Courtney Goeltzenleuchter065983e2015-09-11 15:22:06 -0600921 color_image_view.viewType = VK_IMAGE_VIEW_TYPE_2D;
Courtney Goeltzenleuchter1856d6f2015-09-01 17:30:39 -0600922 color_image_view.format = m_format;
Courtney Goeltzenleuchteraeffeae2015-09-10 17:58:54 -0600923 color_image_view.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
Courtney Goeltzenleuchter1856d6f2015-09-01 17:30:39 -0600924 color_image_view.subresourceRange.baseMipLevel = 0;
925 color_image_view.subresourceRange.mipLevels = 1;
Courtney Goeltzenleuchter3dee8082015-09-10 16:38:41 -0600926 color_image_view.subresourceRange.baseArrayLayer = 0;
Courtney Goeltzenleuchter1856d6f2015-09-01 17:30:39 -0600927 color_image_view.subresourceRange.arraySize = 1;
Tony Barbourb3744222015-07-23 10:36:18 -0600928
Ian Elliott338dedb2015-08-21 15:09:33 -0600929 m_buffers[i].image = swapchainImages[i];
Tony Barbourb3744222015-07-23 10:36:18 -0600930
Courtney Goeltzenleuchter1856d6f2015-09-01 17:30:39 -0600931 color_image_view.image = m_buffers[i].image;
932 err = vkCreateImageView(m_device.handle(),
933 &color_image_view, &m_buffers[i].view);
Tony Barbourb3744222015-07-23 10:36:18 -0600934 assert(!err);
935 }
Tony Barbouref20d322015-02-25 12:28:39 -0700936}
937
Jon Ashburncedc15f2015-05-21 18:13:33 -0600938void TestFrameworkVkPresent::InitPresentFramework(std::list<VkTestImageRecord> &imagesIn, VkInstance inst)
Tony Barbouref20d322015-02-25 12:28:39 -0700939{
Ian Elliott338dedb2015-08-21 15:09:33 -0600940 GET_INSTANCE_PROC_ADDR(inst, GetPhysicalDeviceSurfaceSupportKHR);
941 GET_DEVICE_PROC_ADDR(m_device.handle(), GetSurfacePropertiesKHR);
942 GET_DEVICE_PROC_ADDR(m_device.handle(), GetSurfaceFormatsKHR);
943 GET_DEVICE_PROC_ADDR(m_device.handle(), GetSurfacePresentModesKHR);
944 GET_DEVICE_PROC_ADDR(m_device.handle(), CreateSwapchainKHR);
945 GET_DEVICE_PROC_ADDR(m_device.handle(), CreateSwapchainKHR);
946 GET_DEVICE_PROC_ADDR(m_device.handle(), DestroySwapchainKHR);
947 GET_DEVICE_PROC_ADDR(m_device.handle(), GetSwapchainImagesKHR);
948 GET_DEVICE_PROC_ADDR(m_device.handle(), AcquireNextImageKHR);
949 GET_DEVICE_PROC_ADDR(m_device.handle(), QueuePresentKHR);
Jon Ashburncedc15f2015-05-21 18:13:33 -0600950
Tony Barbouref20d322015-02-25 12:28:39 -0700951 m_images = imagesIn;
952}
953
Tony Barbour25e3b832015-05-20 16:53:31 -0600954#ifdef _WIN32
955void TestFrameworkVkPresent::CreateMyWindow()
956{
957 WNDCLASSEX win_class;
958 // const ::testing::TestInfo* const test_info =
959 // ::testing::UnitTest::GetInstance()->current_test_info();
960 m_connection = GetModuleHandle(NULL);
961
962 for (std::list<VkTestImageRecord>::const_iterator it = m_images.begin();
963 it != m_images.end(); it++) {
964 if (m_width < it->m_width)
965 m_width = it->m_width;
966 if (m_height < it->m_height)
967 m_height = it->m_height;
968 }
969 // Initialize the window class structure:
970 win_class.cbSize = sizeof(WNDCLASSEX);
971 win_class.style = CS_HREDRAW | CS_VREDRAW;
972 win_class.lpfnWndProc = (WNDPROC) &TestFrameworkVkPresent::WndProc;
973 win_class.cbClsExtra = 0;
974 win_class.cbWndExtra = 0;
975 win_class.hInstance = m_connection; // hInstance
976 win_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
977 win_class.hCursor = LoadCursor(NULL, IDC_ARROW);
978 win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
979 win_class.lpszMenuName = NULL;
980 win_class.lpszClassName = "Test";
981 win_class.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
982 // Register window class:
983 if (!RegisterClassEx(&win_class)) {
984 // It didn't work, so try to give a useful error:
985 printf("Unexpected error trying to start the application!\n");
986 fflush(stdout);
987 exit(1);
988 }
989 // Create window with the registered class:
Cody Northropb746ee72015-08-05 15:39:31 -0600990 RECT wr = { 0, 0, m_width, m_height };
991 AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
Tony Barbour25e3b832015-05-20 16:53:31 -0600992 m_window = CreateWindowEx(0,
993 "Test", // class name
994 "Test", // app name
995 WS_OVERLAPPEDWINDOW | // window style
996 WS_VISIBLE |
997 WS_SYSMENU,
998 100,100, // x/y coords
Cody Northropb746ee72015-08-05 15:39:31 -0600999 wr.right - wr.left, // width
1000 wr.bottom - wr.top, // height
Tony Barbour25e3b832015-05-20 16:53:31 -06001001 NULL, // handle to parent
1002 NULL, // handle to menu
1003 m_connection, // hInstance
1004 NULL); // no extra parameters
1005
1006 if (!m_window) {
1007 // It didn't work, so try to give a useful error:
1008 DWORD error = GetLastError();
1009 char message[120];
1010 sprintf(message, "Cannot create a window in which to draw!\n GetLastError = %d", error);
1011 MessageBox(NULL, message, "Error", MB_OK);
1012 exit(1);
1013 }
Tony-LunarGf05ba082015-05-19 14:08:26 -06001014 // Put our this pointer into the window's user data so our WndProc can use it when it starts.
1015 SetWindowLongPtr(m_window, GWLP_USERDATA, (LONG_PTR) this);
Tony Barbour25e3b832015-05-20 16:53:31 -06001016}
1017#else
Tony Barbour01999182015-04-09 12:58:51 -06001018void TestFrameworkVkPresent::CreateMyWindow()
Tony Barbouref20d322015-02-25 12:28:39 -07001019{
Chia-I Wu5b66aa52015-04-16 22:02:10 +08001020 const xcb_setup_t *setup;
1021 xcb_screen_iterator_t iter;
1022 int scr;
Tony Barbouref20d322015-02-25 12:28:39 -07001023 uint32_t value_mask, value_list[32];
1024
Chia-I Wu5b66aa52015-04-16 22:02:10 +08001025 m_connection = xcb_connect(NULL, &scr);
1026
1027 setup = xcb_get_setup(m_connection);
1028 iter = xcb_setup_roots_iterator(setup);
1029 while (scr-- > 0)
1030 xcb_screen_next(&iter);
1031
1032 m_screen = iter.data;
1033
1034 for (std::list<VkTestImageRecord>::const_iterator it = m_images.begin();
1035 it != m_images.end(); it++) {
1036 if (m_width < it->m_width)
1037 m_width = it->m_width;
1038 if (m_height < it->m_height)
1039 m_height = it->m_height;
1040 }
1041
1042 m_window = xcb_generate_id(m_connection);
Tony Barbouref20d322015-02-25 12:28:39 -07001043
1044 value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
Chia-I Wu5b66aa52015-04-16 22:02:10 +08001045 value_list[0] = m_screen->black_pixel;
Tony Barbouref20d322015-02-25 12:28:39 -07001046 value_list[1] = XCB_EVENT_MASK_KEY_RELEASE |
1047 XCB_EVENT_MASK_EXPOSURE |
1048 XCB_EVENT_MASK_STRUCTURE_NOTIFY;
1049
Chia-I Wu5b66aa52015-04-16 22:02:10 +08001050 xcb_create_window(m_connection,
Tony Barbouref20d322015-02-25 12:28:39 -07001051 XCB_COPY_FROM_PARENT,
Chia-I Wu5b66aa52015-04-16 22:02:10 +08001052 m_window, m_screen->root,
Tony Barbouref20d322015-02-25 12:28:39 -07001053 0, 0, m_width, m_height, 0,
1054 XCB_WINDOW_CLASS_INPUT_OUTPUT,
Chia-I Wu5b66aa52015-04-16 22:02:10 +08001055 m_screen->root_visual,
Tony Barbouref20d322015-02-25 12:28:39 -07001056 value_mask, value_list);
1057
1058 /* Magic code that will send notification when window is destroyed */
Chia-I Wu5b66aa52015-04-16 22:02:10 +08001059 xcb_intern_atom_cookie_t cookie = xcb_intern_atom(m_connection, 1, 12,
Tony Barbouref20d322015-02-25 12:28:39 -07001060 "WM_PROTOCOLS");
Chia-I Wu5b66aa52015-04-16 22:02:10 +08001061 xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(m_connection, cookie, 0);
Tony Barbouref20d322015-02-25 12:28:39 -07001062
Chia-I Wu5b66aa52015-04-16 22:02:10 +08001063 xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(m_connection, 0, 16, "WM_DELETE_WINDOW");
1064 m_atom_wm_delete_window = xcb_intern_atom_reply(m_connection, cookie2, 0);
Tony Barbouref20d322015-02-25 12:28:39 -07001065
Chia-I Wu5b66aa52015-04-16 22:02:10 +08001066 xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE,
Tony Barbouref20d322015-02-25 12:28:39 -07001067 m_window, (*reply).atom, 4, 32, 1,
1068 &(*m_atom_wm_delete_window).atom);
1069 free(reply);
1070
Chia-I Wu5b66aa52015-04-16 22:02:10 +08001071 xcb_map_window(m_connection, m_window);
Tony Barbouref20d322015-02-25 12:28:39 -07001072}
Tony Barbour25e3b832015-05-20 16:53:31 -06001073#endif
Tony Barbouref20d322015-02-25 12:28:39 -07001074
Tony Barbour01999182015-04-09 12:58:51 -06001075void TestFrameworkVkPresent::TearDown()
Tony Barbouref20d322015-02-25 12:28:39 -07001076{
Ian Elliott338dedb2015-08-21 15:09:33 -06001077 m_fpDestroySwapchainKHR(m_device.handle(), m_swap_chain);
Tony Barbour25e3b832015-05-20 16:53:31 -06001078#ifndef _WIN32
Chia-I Wu5b66aa52015-04-16 22:02:10 +08001079 xcb_destroy_window(m_connection, m_window);
1080 xcb_disconnect(m_connection);
Tony Barbour25e3b832015-05-20 16:53:31 -06001081#endif
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -06001082}
1083
Tony Barbour01999182015-04-09 12:58:51 -06001084void VkTestFramework::Finish()
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -06001085{
1086 if (m_images.size() == 0) return;
1087
Chia-I Wu5b66aa52015-04-16 22:02:10 +08001088 vk_testing::Environment env;
1089 env.SetUp();
Tony Barbouref20d322015-02-25 12:28:39 -07001090 {
Chia-I Wu5b66aa52015-04-16 22:02:10 +08001091 TestFrameworkVkPresent vkPresent(env.default_device());
Tony Barbouref20d322015-02-25 12:28:39 -07001092
Jon Ashburncedc15f2015-05-21 18:13:33 -06001093 vkPresent.InitPresentFramework(m_images, env.get_instance());
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001094 vkPresent.CreateMyWindow();
Ian Elliott338dedb2015-08-21 15:09:33 -06001095 vkPresent.CreateSwapchain();
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001096 vkPresent.Run();
1097 vkPresent.TearDown();
Tony Barbouref20d322015-02-25 12:28:39 -07001098 }
Chia-I Wu5b66aa52015-04-16 22:02:10 +08001099 env.TearDown();
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -06001100}
1101
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001102//
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001103// These are the default resources for TBuiltInResources, used for both
1104// - parsing this string for the case where the user didn't supply one
1105// - dumping out a template for user construction of a config file
1106//
1107static const char* DefaultConfig =
1108 "MaxLights 32\n"
1109 "MaxClipPlanes 6\n"
1110 "MaxTextureUnits 32\n"
1111 "MaxTextureCoords 32\n"
1112 "MaxVertexAttribs 64\n"
1113 "MaxVertexUniformComponents 4096\n"
1114 "MaxVaryingFloats 64\n"
1115 "MaxVertexTextureImageUnits 32\n"
1116 "MaxCombinedTextureImageUnits 80\n"
1117 "MaxTextureImageUnits 32\n"
1118 "MaxFragmentUniformComponents 4096\n"
1119 "MaxDrawBuffers 32\n"
1120 "MaxVertexUniformVectors 128\n"
1121 "MaxVaryingVectors 8\n"
1122 "MaxFragmentUniformVectors 16\n"
1123 "MaxVertexOutputVectors 16\n"
1124 "MaxFragmentInputVectors 15\n"
1125 "MinProgramTexelOffset -8\n"
1126 "MaxProgramTexelOffset 7\n"
1127 "MaxClipDistances 8\n"
1128 "MaxComputeWorkGroupCountX 65535\n"
1129 "MaxComputeWorkGroupCountY 65535\n"
1130 "MaxComputeWorkGroupCountZ 65535\n"
1131 "MaxComputeWorkGroupSizeX 1024\n"
1132 "MaxComputeWorkGroupSizeY 1024\n"
1133 "MaxComputeWorkGroupSizeZ 64\n"
1134 "MaxComputeUniformComponents 1024\n"
1135 "MaxComputeTextureImageUnits 16\n"
1136 "MaxComputeImageUniforms 8\n"
1137 "MaxComputeAtomicCounters 8\n"
1138 "MaxComputeAtomicCounterBuffers 1\n"
1139 "MaxVaryingComponents 60\n"
1140 "MaxVertexOutputComponents 64\n"
1141 "MaxGeometryInputComponents 64\n"
1142 "MaxGeometryOutputComponents 128\n"
1143 "MaxFragmentInputComponents 128\n"
1144 "MaxImageUnits 8\n"
1145 "MaxCombinedImageUnitsAndFragmentOutputs 8\n"
1146 "MaxCombinedShaderOutputResources 8\n"
1147 "MaxImageSamples 0\n"
1148 "MaxVertexImageUniforms 0\n"
1149 "MaxTessControlImageUniforms 0\n"
1150 "MaxTessEvaluationImageUniforms 0\n"
1151 "MaxGeometryImageUniforms 0\n"
1152 "MaxFragmentImageUniforms 8\n"
1153 "MaxCombinedImageUniforms 8\n"
1154 "MaxGeometryTextureImageUnits 16\n"
1155 "MaxGeometryOutputVertices 256\n"
1156 "MaxGeometryTotalOutputComponents 1024\n"
1157 "MaxGeometryUniformComponents 1024\n"
1158 "MaxGeometryVaryingComponents 64\n"
1159 "MaxTessControlInputComponents 128\n"
1160 "MaxTessControlOutputComponents 128\n"
1161 "MaxTessControlTextureImageUnits 16\n"
1162 "MaxTessControlUniformComponents 1024\n"
1163 "MaxTessControlTotalOutputComponents 4096\n"
1164 "MaxTessEvaluationInputComponents 128\n"
1165 "MaxTessEvaluationOutputComponents 128\n"
1166 "MaxTessEvaluationTextureImageUnits 16\n"
1167 "MaxTessEvaluationUniformComponents 1024\n"
1168 "MaxTessPatchComponents 120\n"
1169 "MaxPatchVertices 32\n"
1170 "MaxTessGenLevel 64\n"
1171 "MaxViewports 16\n"
1172 "MaxVertexAtomicCounters 0\n"
1173 "MaxTessControlAtomicCounters 0\n"
1174 "MaxTessEvaluationAtomicCounters 0\n"
1175 "MaxGeometryAtomicCounters 0\n"
1176 "MaxFragmentAtomicCounters 8\n"
1177 "MaxCombinedAtomicCounters 8\n"
1178 "MaxAtomicCounterBindings 1\n"
1179 "MaxVertexAtomicCounterBuffers 0\n"
1180 "MaxTessControlAtomicCounterBuffers 0\n"
1181 "MaxTessEvaluationAtomicCounterBuffers 0\n"
1182 "MaxGeometryAtomicCounterBuffers 0\n"
1183 "MaxFragmentAtomicCounterBuffers 1\n"
1184 "MaxCombinedAtomicCounterBuffers 1\n"
1185 "MaxAtomicCounterBufferSize 16384\n"
1186 "MaxTransformFeedbackBuffers 4\n"
1187 "MaxTransformFeedbackInterleavedComponents 64\n"
1188 "MaxCullDistances 8\n"
1189 "MaxCombinedClipAndCullDistances 8\n"
1190 "MaxSamples 4\n"
1191
1192 "nonInductiveForLoops 1\n"
1193 "whileLoops 1\n"
1194 "doWhileLoops 1\n"
1195 "generalUniformIndexing 1\n"
1196 "generalAttributeMatrixVectorIndexing 1\n"
1197 "generalVaryingIndexing 1\n"
1198 "generalSamplerIndexing 1\n"
1199 "generalVariableIndexing 1\n"
1200 "generalConstantMatrixVectorIndexing 1\n"
1201 ;
1202
1203//
1204// *.conf => this is a config file that can set limits/resources
1205//
Tony Barbour01999182015-04-09 12:58:51 -06001206bool VkTestFramework::SetConfigFile(const std::string& name)
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001207{
1208 if (name.size() < 5)
1209 return false;
1210
1211 if (name.compare(name.size() - 5, 5, ".conf") == 0) {
1212 ConfigFile = name;
1213 return true;
1214 }
1215
1216 return false;
1217}
1218
1219//
1220// Parse either a .conf file provided by the user or the default string above.
1221//
Tony Barbour01999182015-04-09 12:58:51 -06001222void VkTestFramework::ProcessConfigFile()
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001223{
1224 char** configStrings = 0;
1225 char* config = 0;
1226 if (ConfigFile.size() > 0) {
1227 configStrings = ReadFileData(ConfigFile.c_str());
1228 if (configStrings)
1229 config = *configStrings;
1230 else {
1231 printf("Error opening configuration file; will instead use the default configuration\n");
1232 }
1233 }
1234
1235 if (config == 0) {
1236 config = new char[strlen(DefaultConfig) + 1];
1237 strcpy(config, DefaultConfig);
1238 }
1239
1240 const char* delims = " \t\n\r";
1241 const char* token = strtok(config, delims);
1242 while (token) {
1243 const char* valueStr = strtok(0, delims);
1244 if (valueStr == 0 || ! (valueStr[0] == '-' || (valueStr[0] >= '0' && valueStr[0] <= '9'))) {
1245 printf("Error: '%s' bad .conf file. Each name must be followed by one number.\n", valueStr ? valueStr : "");
1246 return;
1247 }
1248 int value = atoi(valueStr);
1249
1250 if (strcmp(token, "MaxLights") == 0)
1251 Resources.maxLights = value;
1252 else if (strcmp(token, "MaxClipPlanes") == 0)
1253 Resources.maxClipPlanes = value;
1254 else if (strcmp(token, "MaxTextureUnits") == 0)
1255 Resources.maxTextureUnits = value;
1256 else if (strcmp(token, "MaxTextureCoords") == 0)
1257 Resources.maxTextureCoords = value;
1258 else if (strcmp(token, "MaxVertexAttribs") == 0)
1259 Resources.maxVertexAttribs = value;
1260 else if (strcmp(token, "MaxVertexUniformComponents") == 0)
1261 Resources.maxVertexUniformComponents = value;
1262 else if (strcmp(token, "MaxVaryingFloats") == 0)
1263 Resources.maxVaryingFloats = value;
1264 else if (strcmp(token, "MaxVertexTextureImageUnits") == 0)
1265 Resources.maxVertexTextureImageUnits = value;
1266 else if (strcmp(token, "MaxCombinedTextureImageUnits") == 0)
1267 Resources.maxCombinedTextureImageUnits = value;
1268 else if (strcmp(token, "MaxTextureImageUnits") == 0)
1269 Resources.maxTextureImageUnits = value;
1270 else if (strcmp(token, "MaxFragmentUniformComponents") == 0)
1271 Resources.maxFragmentUniformComponents = value;
1272 else if (strcmp(token, "MaxDrawBuffers") == 0)
1273 Resources.maxDrawBuffers = value;
1274 else if (strcmp(token, "MaxVertexUniformVectors") == 0)
1275 Resources.maxVertexUniformVectors = value;
1276 else if (strcmp(token, "MaxVaryingVectors") == 0)
1277 Resources.maxVaryingVectors = value;
1278 else if (strcmp(token, "MaxFragmentUniformVectors") == 0)
1279 Resources.maxFragmentUniformVectors = value;
1280 else if (strcmp(token, "MaxVertexOutputVectors") == 0)
1281 Resources.maxVertexOutputVectors = value;
1282 else if (strcmp(token, "MaxFragmentInputVectors") == 0)
1283 Resources.maxFragmentInputVectors = value;
1284 else if (strcmp(token, "MinProgramTexelOffset") == 0)
1285 Resources.minProgramTexelOffset = value;
1286 else if (strcmp(token, "MaxProgramTexelOffset") == 0)
1287 Resources.maxProgramTexelOffset = value;
1288 else if (strcmp(token, "MaxClipDistances") == 0)
1289 Resources.maxClipDistances = value;
1290 else if (strcmp(token, "MaxComputeWorkGroupCountX") == 0)
1291 Resources.maxComputeWorkGroupCountX = value;
1292 else if (strcmp(token, "MaxComputeWorkGroupCountY") == 0)
1293 Resources.maxComputeWorkGroupCountY = value;
1294 else if (strcmp(token, "MaxComputeWorkGroupCountZ") == 0)
1295 Resources.maxComputeWorkGroupCountZ = value;
1296 else if (strcmp(token, "MaxComputeWorkGroupSizeX") == 0)
1297 Resources.maxComputeWorkGroupSizeX = value;
1298 else if (strcmp(token, "MaxComputeWorkGroupSizeY") == 0)
1299 Resources.maxComputeWorkGroupSizeY = value;
1300 else if (strcmp(token, "MaxComputeWorkGroupSizeZ") == 0)
1301 Resources.maxComputeWorkGroupSizeZ = value;
1302 else if (strcmp(token, "MaxComputeUniformComponents") == 0)
1303 Resources.maxComputeUniformComponents = value;
1304 else if (strcmp(token, "MaxComputeTextureImageUnits") == 0)
1305 Resources.maxComputeTextureImageUnits = value;
1306 else if (strcmp(token, "MaxComputeImageUniforms") == 0)
1307 Resources.maxComputeImageUniforms = value;
1308 else if (strcmp(token, "MaxComputeAtomicCounters") == 0)
1309 Resources.maxComputeAtomicCounters = value;
1310 else if (strcmp(token, "MaxComputeAtomicCounterBuffers") == 0)
1311 Resources.maxComputeAtomicCounterBuffers = value;
1312 else if (strcmp(token, "MaxVaryingComponents") == 0)
1313 Resources.maxVaryingComponents = value;
1314 else if (strcmp(token, "MaxVertexOutputComponents") == 0)
1315 Resources.maxVertexOutputComponents = value;
1316 else if (strcmp(token, "MaxGeometryInputComponents") == 0)
1317 Resources.maxGeometryInputComponents = value;
1318 else if (strcmp(token, "MaxGeometryOutputComponents") == 0)
1319 Resources.maxGeometryOutputComponents = value;
1320 else if (strcmp(token, "MaxFragmentInputComponents") == 0)
1321 Resources.maxFragmentInputComponents = value;
1322 else if (strcmp(token, "MaxImageUnits") == 0)
1323 Resources.maxImageUnits = value;
1324 else if (strcmp(token, "MaxCombinedImageUnitsAndFragmentOutputs") == 0)
1325 Resources.maxCombinedImageUnitsAndFragmentOutputs = value;
1326 else if (strcmp(token, "MaxCombinedShaderOutputResources") == 0)
1327 Resources.maxCombinedShaderOutputResources = value;
1328 else if (strcmp(token, "MaxImageSamples") == 0)
1329 Resources.maxImageSamples = value;
1330 else if (strcmp(token, "MaxVertexImageUniforms") == 0)
1331 Resources.maxVertexImageUniforms = value;
1332 else if (strcmp(token, "MaxTessControlImageUniforms") == 0)
1333 Resources.maxTessControlImageUniforms = value;
1334 else if (strcmp(token, "MaxTessEvaluationImageUniforms") == 0)
1335 Resources.maxTessEvaluationImageUniforms = value;
1336 else if (strcmp(token, "MaxGeometryImageUniforms") == 0)
1337 Resources.maxGeometryImageUniforms = value;
1338 else if (strcmp(token, "MaxFragmentImageUniforms") == 0)
1339 Resources.maxFragmentImageUniforms = value;
1340 else if (strcmp(token, "MaxCombinedImageUniforms") == 0)
1341 Resources.maxCombinedImageUniforms = value;
1342 else if (strcmp(token, "MaxGeometryTextureImageUnits") == 0)
1343 Resources.maxGeometryTextureImageUnits = value;
1344 else if (strcmp(token, "MaxGeometryOutputVertices") == 0)
1345 Resources.maxGeometryOutputVertices = value;
1346 else if (strcmp(token, "MaxGeometryTotalOutputComponents") == 0)
1347 Resources.maxGeometryTotalOutputComponents = value;
1348 else if (strcmp(token, "MaxGeometryUniformComponents") == 0)
1349 Resources.maxGeometryUniformComponents = value;
1350 else if (strcmp(token, "MaxGeometryVaryingComponents") == 0)
1351 Resources.maxGeometryVaryingComponents = value;
1352 else if (strcmp(token, "MaxTessControlInputComponents") == 0)
1353 Resources.maxTessControlInputComponents = value;
1354 else if (strcmp(token, "MaxTessControlOutputComponents") == 0)
1355 Resources.maxTessControlOutputComponents = value;
1356 else if (strcmp(token, "MaxTessControlTextureImageUnits") == 0)
1357 Resources.maxTessControlTextureImageUnits = value;
1358 else if (strcmp(token, "MaxTessControlUniformComponents") == 0)
1359 Resources.maxTessControlUniformComponents = value;
1360 else if (strcmp(token, "MaxTessControlTotalOutputComponents") == 0)
1361 Resources.maxTessControlTotalOutputComponents = value;
1362 else if (strcmp(token, "MaxTessEvaluationInputComponents") == 0)
1363 Resources.maxTessEvaluationInputComponents = value;
1364 else if (strcmp(token, "MaxTessEvaluationOutputComponents") == 0)
1365 Resources.maxTessEvaluationOutputComponents = value;
1366 else if (strcmp(token, "MaxTessEvaluationTextureImageUnits") == 0)
1367 Resources.maxTessEvaluationTextureImageUnits = value;
1368 else if (strcmp(token, "MaxTessEvaluationUniformComponents") == 0)
1369 Resources.maxTessEvaluationUniformComponents = value;
1370 else if (strcmp(token, "MaxTessPatchComponents") == 0)
1371 Resources.maxTessPatchComponents = value;
1372 else if (strcmp(token, "MaxPatchVertices") == 0)
1373 Resources.maxPatchVertices = value;
1374 else if (strcmp(token, "MaxTessGenLevel") == 0)
1375 Resources.maxTessGenLevel = value;
1376 else if (strcmp(token, "MaxViewports") == 0)
1377 Resources.maxViewports = value;
1378 else if (strcmp(token, "MaxVertexAtomicCounters") == 0)
1379 Resources.maxVertexAtomicCounters = value;
1380 else if (strcmp(token, "MaxTessControlAtomicCounters") == 0)
1381 Resources.maxTessControlAtomicCounters = value;
1382 else if (strcmp(token, "MaxTessEvaluationAtomicCounters") == 0)
1383 Resources.maxTessEvaluationAtomicCounters = value;
1384 else if (strcmp(token, "MaxGeometryAtomicCounters") == 0)
1385 Resources.maxGeometryAtomicCounters = value;
1386 else if (strcmp(token, "MaxFragmentAtomicCounters") == 0)
1387 Resources.maxFragmentAtomicCounters = value;
1388 else if (strcmp(token, "MaxCombinedAtomicCounters") == 0)
1389 Resources.maxCombinedAtomicCounters = value;
1390 else if (strcmp(token, "MaxAtomicCounterBindings") == 0)
1391 Resources.maxAtomicCounterBindings = value;
1392 else if (strcmp(token, "MaxVertexAtomicCounterBuffers") == 0)
1393 Resources.maxVertexAtomicCounterBuffers = value;
1394 else if (strcmp(token, "MaxTessControlAtomicCounterBuffers") == 0)
1395 Resources.maxTessControlAtomicCounterBuffers = value;
1396 else if (strcmp(token, "MaxTessEvaluationAtomicCounterBuffers") == 0)
1397 Resources.maxTessEvaluationAtomicCounterBuffers = value;
1398 else if (strcmp(token, "MaxGeometryAtomicCounterBuffers") == 0)
1399 Resources.maxGeometryAtomicCounterBuffers = value;
1400 else if (strcmp(token, "MaxFragmentAtomicCounterBuffers") == 0)
1401 Resources.maxFragmentAtomicCounterBuffers = value;
1402 else if (strcmp(token, "MaxCombinedAtomicCounterBuffers") == 0)
1403 Resources.maxCombinedAtomicCounterBuffers = value;
1404 else if (strcmp(token, "MaxAtomicCounterBufferSize") == 0)
1405 Resources.maxAtomicCounterBufferSize = value;
1406 else if (strcmp(token, "MaxTransformFeedbackBuffers") == 0)
1407 Resources.maxTransformFeedbackBuffers = value;
1408 else if (strcmp(token, "MaxTransformFeedbackInterleavedComponents") == 0)
1409 Resources.maxTransformFeedbackInterleavedComponents = value;
1410 else if (strcmp(token, "MaxCullDistances") == 0)
1411 Resources.maxCullDistances = value;
1412 else if (strcmp(token, "MaxCombinedClipAndCullDistances") == 0)
1413 Resources.maxCombinedClipAndCullDistances = value;
1414 else if (strcmp(token, "MaxSamples") == 0)
1415 Resources.maxSamples = value;
1416
1417 else if (strcmp(token, "nonInductiveForLoops") == 0)
1418 Resources.limits.nonInductiveForLoops = (value != 0);
1419 else if (strcmp(token, "whileLoops") == 0)
1420 Resources.limits.whileLoops = (value != 0);
1421 else if (strcmp(token, "doWhileLoops") == 0)
1422 Resources.limits.doWhileLoops = (value != 0);
1423 else if (strcmp(token, "generalUniformIndexing") == 0)
1424 Resources.limits.generalUniformIndexing = (value != 0);
1425 else if (strcmp(token, "generalAttributeMatrixVectorIndexing") == 0)
1426 Resources.limits.generalAttributeMatrixVectorIndexing = (value != 0);
1427 else if (strcmp(token, "generalVaryingIndexing") == 0)
1428 Resources.limits.generalVaryingIndexing = (value != 0);
1429 else if (strcmp(token, "generalSamplerIndexing") == 0)
1430 Resources.limits.generalSamplerIndexing = (value != 0);
1431 else if (strcmp(token, "generalVariableIndexing") == 0)
1432 Resources.limits.generalVariableIndexing = (value != 0);
1433 else if (strcmp(token, "generalConstantMatrixVectorIndexing") == 0)
1434 Resources.limits.generalConstantMatrixVectorIndexing = (value != 0);
1435 else
1436 printf("Warning: unrecognized limit (%s) in configuration file.\n", token);
1437
1438 token = strtok(0, delims);
1439 }
1440 if (configStrings)
1441 FreeFileData(configStrings);
1442}
1443
Tony Barbour01999182015-04-09 12:58:51 -06001444void VkTestFramework::SetMessageOptions(EShMessages& messages)
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001445{
1446 if (m_compile_options & EOptionRelaxedErrors)
1447 messages = (EShMessages)(messages | EShMsgRelaxedErrors);
1448 if (m_compile_options & EOptionIntermediate)
1449 messages = (EShMessages)(messages | EShMsgAST);
1450 if (m_compile_options & EOptionSuppressWarnings)
1451 messages = (EShMessages)(messages | EShMsgSuppressWarnings);
1452}
1453
1454//
1455// Malloc a string of sufficient size and read a string into it.
1456//
Tony Barbour01999182015-04-09 12:58:51 -06001457char** VkTestFramework::ReadFileData(const char* fileName)
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001458{
1459 FILE *in;
1460 #if defined(_WIN32) && defined(__GNUC__)
1461 in = fopen(fileName, "r");
1462 int errorCode = in ? 0 : 1;
1463 #else
1464 int errorCode = fopen_s(&in, fileName, "r");
1465 #endif
1466
1467 char *fdata;
1468 int count = 0;
1469 const int maxSourceStrings = 5;
1470 char** return_data = (char**)malloc(sizeof(char *) * (maxSourceStrings+1));
1471
1472 if (errorCode) {
1473 printf("Error: unable to open input file: %s\n", fileName);
1474 return 0;
1475 }
1476
1477 while (fgetc(in) != EOF)
1478 count++;
1479
1480 fseek(in, 0, SEEK_SET);
1481
1482 if (!(fdata = (char*)malloc(count+2))) {
1483 printf("Error allocating memory\n");
1484 return 0;
1485 }
1486 if (fread(fdata,1,count, in)!=count) {
1487 printf("Error reading input file: %s\n", fileName);
1488 return 0;
1489 }
1490 fdata[count] = '\0';
1491 fclose(in);
1492 if (count == 0) {
1493 return_data[0]=(char*)malloc(count+2);
1494 return_data[0][0]='\0';
1495 m_num_shader_strings = 0;
1496 return return_data;
1497 } else
1498 m_num_shader_strings = 1;
1499
1500 int len = (int)(ceil)((float)count/(float)m_num_shader_strings);
1501 int ptr_len=0,i=0;
1502 while(count>0){
1503 return_data[i]=(char*)malloc(len+2);
1504 memcpy(return_data[i],fdata+ptr_len,len);
1505 return_data[i][len]='\0';
1506 count-=(len);
1507 ptr_len+=(len);
1508 if(count<len){
1509 if(count==0){
1510 m_num_shader_strings=(i+1);
1511 break;
1512 }
1513 len = count;
1514 }
1515 ++i;
1516 }
1517 return return_data;
1518}
1519
Tony Barbour01999182015-04-09 12:58:51 -06001520void VkTestFramework::FreeFileData(char** data)
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001521{
1522 for(int i=0;i<m_num_shader_strings;i++)
1523 free(data[i]);
1524}
1525
1526//
1527// Deduce the language from the filename. Files must end in one of the
1528// following extensions:
1529//
1530// .vert = vertex
1531// .tesc = tessellation control
1532// .tese = tessellation evaluation
1533// .geom = geometry
1534// .frag = fragment
1535// .comp = compute
1536//
Tony Barbour01999182015-04-09 12:58:51 -06001537EShLanguage VkTestFramework::FindLanguage(const std::string& name)
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001538{
1539 size_t ext = name.rfind('.');
1540 if (ext == std::string::npos) {
1541 return EShLangVertex;
1542 }
1543
1544 std::string suffix = name.substr(ext + 1, std::string::npos);
1545 if (suffix == "vert")
1546 return EShLangVertex;
1547 else if (suffix == "tesc")
1548 return EShLangTessControl;
1549 else if (suffix == "tese")
1550 return EShLangTessEvaluation;
1551 else if (suffix == "geom")
1552 return EShLangGeometry;
1553 else if (suffix == "frag")
1554 return EShLangFragment;
1555 else if (suffix == "comp")
1556 return EShLangCompute;
1557
1558 return EShLangVertex;
1559}
1560
1561//
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001562// Convert VK shader type to compiler's
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001563//
Tony Barbour8205d902015-04-16 15:59:00 -06001564EShLanguage VkTestFramework::FindLanguage(const VkShaderStage shader_type)
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001565{
1566 switch (shader_type) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001567 case VK_SHADER_STAGE_VERTEX:
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001568 return EShLangVertex;
1569
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001570 case VK_SHADER_STAGE_TESS_CONTROL:
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001571 return EShLangTessControl;
1572
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001573 case VK_SHADER_STAGE_TESS_EVALUATION:
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001574 return EShLangTessEvaluation;
1575
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001576 case VK_SHADER_STAGE_GEOMETRY:
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001577 return EShLangGeometry;
1578
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001579 case VK_SHADER_STAGE_FRAGMENT:
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001580 return EShLangFragment;
1581
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001582 case VK_SHADER_STAGE_COMPUTE:
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001583 return EShLangCompute;
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001584
Chia-I Wubbdeacc2014-12-15 23:50:11 +08001585 default:
1586 return EShLangVertex;
1587 }
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001588}
1589
1590
1591//
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001592// Compile a given string containing GLSL into SPV for use by VK
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001593// Return value of false means an error was encountered.
1594//
Tony Barbour8205d902015-04-16 15:59:00 -06001595bool VkTestFramework::GLSLtoSPV(const VkShaderStage shader_type,
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001596 const char *pshader,
Cody Northropeb9130e2015-06-03 13:01:54 -06001597 std::vector<unsigned int> &spirv)
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001598{
1599 glslang::TProgram& program = *new glslang::TProgram;
1600 const char *shaderStrings[1];
1601
1602 // TODO: Do we want to load a special config file depending on the
1603 // shader source? Optional name maybe?
1604 // SetConfigFile(fileName);
1605
1606 ProcessConfigFile();
1607
1608 EShMessages messages = EShMsgDefault;
1609 SetMessageOptions(messages);
1610
1611 EShLanguage stage = FindLanguage(shader_type);
1612 glslang::TShader* shader = new glslang::TShader(stage);
1613
1614 shaderStrings[0] = pshader;
1615 shader->setStrings(shaderStrings, 1);
1616
1617 if (! shader->parse(&Resources, (m_compile_options & EOptionDefaultDesktop) ? 110 : 100, false, messages)) {
1618
Cody Northropad306f02014-11-03 12:54:37 -07001619 if (! (m_compile_options & EOptionSuppressInfolog)) {
1620 puts(shader->getInfoLog());
1621 puts(shader->getInfoDebugLog());
1622 }
1623
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001624 return false; // something didn't work
1625 }
1626
1627 program.addShader(shader);
1628
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001629
1630 //
1631 // Program-level processing...
1632 //
1633
Cody Northropad306f02014-11-03 12:54:37 -07001634 if (! program.link(messages)) {
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001635
Cody Northropad306f02014-11-03 12:54:37 -07001636 if (! (m_compile_options & EOptionSuppressInfolog)) {
1637 puts(shader->getInfoLog());
1638 puts(shader->getInfoDebugLog());
1639 }
1640
1641 return false;
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001642 }
1643
1644 if (m_compile_options & EOptionDumpReflection) {
1645 program.buildReflection();
1646 program.dumpReflection();
1647 }
1648
Cody Northropeb9130e2015-06-03 13:01:54 -06001649 glslang::GlslangToSpv(*program.getIntermediate(stage), spirv);
1650
1651 //
1652 // Test the different modes of SPIR-V modification
1653 //
1654 if (this->m_canonicalize_spv) {
1655 spv::spirvbin_t(0).remap(spirv, spv::spirvbin_t::ALL_BUT_STRIP);
1656 }
1657
1658 if (this->m_strip_spv) {
1659 spv::spirvbin_t(0).remap(spirv, spv::spirvbin_t::STRIP);
1660 }
1661
1662 if (this->m_do_everything_spv) {
1663 spv::spirvbin_t(0).remap(spirv, spv::spirvbin_t::DO_EVERYTHING);
1664 }
1665
Courtney Goeltzenleuchter94192032014-10-03 09:53:32 -06001666
1667 return true;
1668}
1669
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -06001670
1671
Tony Barbour01999182015-04-09 12:58:51 -06001672VkTestImageRecord::VkTestImageRecord() : // Constructor
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -06001673 m_width( 0 ),
1674 m_height( 0 ),
Chia-I Wub2c2dea2014-12-15 23:29:34 +08001675 m_data( NULL ),
1676 m_data_size( 0 )
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -06001677{
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -06001678}
1679
Tony Barbour01999182015-04-09 12:58:51 -06001680VkTestImageRecord::~VkTestImageRecord()
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -06001681{
1682
1683}
1684
Tony Barbour01999182015-04-09 12:58:51 -06001685VkTestImageRecord::VkTestImageRecord(const VkTestImageRecord &copyin) // Copy constructor to handle pass by value.
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -06001686{
1687 m_title = copyin.m_title;
1688 m_width = copyin.m_width;
1689 m_height = copyin.m_height;
1690 m_data_size = copyin.m_data_size;
1691 m_data = copyin.m_data; // TODO: Do we need to copy the data or is pointer okay?
1692}
1693
Tony Barbour01999182015-04-09 12:58:51 -06001694ostream &operator<<(ostream &output, const VkTestImageRecord &VkTestImageRecord)
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -06001695{
Tony Barbour01999182015-04-09 12:58:51 -06001696 output << VkTestImageRecord.m_title << " (" << VkTestImageRecord.m_width <<
1697 "," << VkTestImageRecord.m_height << ")" << endl;
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -06001698 return output;
1699}
1700
Tony Barbour01999182015-04-09 12:58:51 -06001701VkTestImageRecord& VkTestImageRecord::operator=(const VkTestImageRecord &rhs)
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -06001702{
1703 m_title = rhs.m_title;
1704 m_width = rhs.m_width;
1705 m_height = rhs.m_height;
1706 m_data_size = rhs.m_data_size;
1707 m_data = rhs.m_data;
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -06001708 return *this;
1709}
1710
Tony Barbour01999182015-04-09 12:58:51 -06001711int VkTestImageRecord::operator==(const VkTestImageRecord &rhs) const
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -06001712{
1713 if( this->m_data != rhs.m_data) return 0;
1714 return 1;
1715}
1716
1717// This function is required for built-in STL list functions like sort
Tony Barbour01999182015-04-09 12:58:51 -06001718int VkTestImageRecord::operator<(const VkTestImageRecord &rhs) const
Courtney Goeltzenleuchterd0d7ccc2014-09-04 16:24:19 -06001719{
1720 if( this->m_data_size < rhs.m_data_size ) return 1;
1721 return 0;
1722}
1723