blob: 69361cf8b4645cdfb1c55023913bae1e36c03975 [file] [log] [blame]
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001//
Courtney Goeltzenleuchterfcbe16f2015-10-29 13:50:34 -06002// Copyright (C) 2015 Valve Corporation
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06003//
4// Permission is hereby granted, free of charge, to any person obtaining a
5// copy of this software and associated documentation files (the "Software"),
6// to deal in the Software without restriction, including without limitation
7// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8// and/or sell copies of the Software, and to permit persons to whom the
9// Software is furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included
12// in all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20// DEALINGS IN THE SOFTWARE.
Courtney Goeltzenleuchter05559522015-10-30 11:14:30 -060021//
22// Author: Chia-I Wu <olv@lunarg.com>
23// Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
24// Author: Tony Barbour <tony@LunarG.com>
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -060025
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060026#include "vktestframework.h"
27#include "vkrenderframework.h"
Jon Ashburn94207e92015-12-04 17:03:59 -070028//TODO FIXME remove this once glslang doesn't define this
29#undef BadValue
Cody Northrop5a95b472015-06-03 13:01:54 -060030#include "SPIRV/GlslangToSpv.h"
31#include "SPIRV/SPVRemapper.h"
Tony Barbour4ab45422014-12-10 17:00:20 -070032#include <limits.h>
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -060033#include <math.h>
Chia-I Wuec664fa2014-12-02 11:54:24 +080034#include <wand/MagickWand.h>
Jon Ashburn94207e92015-12-04 17:03:59 -070035
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -060036
Tony Barbour3d69c9e2015-05-20 16:53:31 -060037#if defined(PATH_MAX) && !defined(MAX_PATH)
38#define MAX_PATH PATH_MAX
39#endif
40
Tony Barbour6a3faf02015-07-23 10:36:18 -060041#ifdef _WIN32
42#define ERR_EXIT(err_msg, err_class) \
43 do { \
44 MessageBox(NULL, err_msg, err_class, MB_OK); \
45 exit(1); \
46 } while (0)
47#else // _WIN32
48
49#define ERR_EXIT(err_msg, err_class) \
50 do { \
51 printf(err_msg); \
52 fflush(stdout); \
53 exit(1); \
54 } while (0)
55#endif // _WIN32
56
57#define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \
58{ \
59 m_fp##entrypoint = (PFN_vk##entrypoint) vkGetInstanceProcAddr(inst, "vk"#entrypoint); \
60 if (m_fp##entrypoint == NULL) { \
61 ERR_EXIT("vkGetInstanceProcAddr failed to find vk"#entrypoint, \
62 "vkGetInstanceProcAddr Failure"); \
63 } \
64}
65
66#define GET_DEVICE_PROC_ADDR(dev, entrypoint) \
67{ \
68 m_fp##entrypoint = (PFN_vk##entrypoint) vkGetDeviceProcAddr(dev, "vk"#entrypoint); \
69 if (m_fp##entrypoint == NULL) { \
70 ERR_EXIT("vkGetDeviceProcAddr failed to find vk"#entrypoint, \
71 "vkGetDeviceProcAddr Failure"); \
72 } \
73}
74
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -060075// Command-line options
76enum TOptions {
77 EOptionNone = 0x000,
78 EOptionIntermediate = 0x001,
79 EOptionSuppressInfolog = 0x002,
80 EOptionMemoryLeakMode = 0x004,
81 EOptionRelaxedErrors = 0x008,
82 EOptionGiveWarnings = 0x010,
83 EOptionLinkProgram = 0x020,
84 EOptionMultiThreaded = 0x040,
85 EOptionDumpConfig = 0x080,
86 EOptionDumpReflection = 0x100,
87 EOptionSuppressWarnings = 0x200,
88 EOptionDumpVersions = 0x400,
Cody Northrop3bfd27c2015-03-17 15:55:58 -060089 EOptionSpv = 0x800,
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -060090 EOptionDefaultDesktop = 0x1000,
91};
92
Ian Elliott7e40db92015-08-21 15:09:33 -060093typedef struct _SwapchainBuffers {
Tony Barbour6a3faf02015-07-23 10:36:18 -060094 VkImage image;
Chia-I Wu3432a0c2015-10-27 18:04:07 +080095 VkCommandBuffer cmd;
Courtney Goeltzenleuchter5861a1b2015-09-01 17:30:39 -060096 VkImageView view;
Ian Elliott7e40db92015-08-21 15:09:33 -060097} SwapchainBuffers;
Tony Barbour6a3faf02015-07-23 10:36:18 -060098
Chia-I Wuf8693382015-04-16 22:02:10 +080099class TestFrameworkVkPresent
100{
101public:
102 TestFrameworkVkPresent(vk_testing::Device &device);
103
104 void Run();
Jon Ashburn07daee72015-05-21 18:13:33 -0600105 void InitPresentFramework(std::list<VkTestImageRecord> &imagesIn, VkInstance inst);
Chia-I Wuf8693382015-04-16 22:02:10 +0800106 void CreateMyWindow();
Tony Barbour2d6d54e2015-12-03 16:05:11 -0700107 VkFormat GetPresentFormat();
Tony Barboure1837292015-12-07 13:46:11 -0700108 void DestroyMyWindow();
Ian Elliott7e40db92015-08-21 15:09:33 -0600109 void CreateSwapchain();
Tony Barbourbd094ce2015-10-23 11:00:15 -0600110 void SetImageLayout(VkImage image, VkImageAspectFlags aspectMask,
111 VkImageLayout old_image_layout, VkImageLayout new_image_layout);
Chia-I Wuf8693382015-04-16 22:02:10 +0800112 void TearDown();
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600113#ifdef _WIN32
114 static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
115#endif
116
Chia-I Wuf8693382015-04-16 22:02:10 +0800117
118protected:
119 vk_testing::Device &m_device;
120 vk_testing::Queue &m_queue;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800121 vk_testing::CommandPool m_cmdpool;
122 vk_testing::CommandBuffer m_cmdbuf;
Chia-I Wuf8693382015-04-16 22:02:10 +0800123
124private:
Ian Elliottc11750d2015-10-30 13:24:12 -0600125 VkInstance m_instance;
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600126#ifdef _WIN32
127 HINSTANCE m_connection; // hInstance - Windows Instance
128 HWND m_window; // hWnd - window handle
129
130#else
Chia-I Wuf8693382015-04-16 22:02:10 +0800131 xcb_connection_t *m_connection;
132 xcb_screen_t *m_screen;
133 xcb_window_t m_window;
134 xcb_intern_atom_reply_t *m_atom_wm_delete_window;
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600135#endif
Ian Elliottc11750d2015-10-30 13:24:12 -0600136 VkSurfaceKHR m_surface;
Courtney Goeltzenleuchterd6079ec2015-04-22 10:09:35 -0600137 std::list<VkTestImageRecord> m_images;
Tony Barbour6a3faf02015-07-23 10:36:18 -0600138 uint32_t m_present_queue_node_index;
Chia-I Wuf8693382015-04-16 22:02:10 +0800139
Ian Elliott7e40db92015-08-21 15:09:33 -0600140 PFN_vkGetPhysicalDeviceSurfaceSupportKHR m_fpGetPhysicalDeviceSurfaceSupportKHR;
Ian Elliottc11750d2015-10-30 13:24:12 -0600141 PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR m_fpGetPhysicalDeviceSurfaceCapabilitiesKHR;
142 PFN_vkGetPhysicalDeviceSurfaceFormatsKHR m_fpGetPhysicalDeviceSurfaceFormatsKHR;
143 PFN_vkGetPhysicalDeviceSurfacePresentModesKHR m_fpGetPhysicalDeviceSurfacePresentModesKHR;
Ian Elliott7e40db92015-08-21 15:09:33 -0600144 PFN_vkCreateSwapchainKHR m_fpCreateSwapchainKHR;
145 PFN_vkDestroySwapchainKHR m_fpDestroySwapchainKHR;
146 PFN_vkGetSwapchainImagesKHR m_fpGetSwapchainImagesKHR;
147 PFN_vkAcquireNextImageKHR m_fpAcquireNextImageKHR;
148 PFN_vkQueuePresentKHR m_fpQueuePresentKHR;
Tony Barbour2d6d54e2015-12-03 16:05:11 -0700149 PFN_vkDestroySurfaceKHR m_fpDestroySurfaceKHR;
Ian Elliott7e40db92015-08-21 15:09:33 -0600150 uint32_t m_swapchainImageCount;
151 VkSwapchainKHR m_swap_chain;
152 SwapchainBuffers *m_buffers;
Tony Barbour6a3faf02015-07-23 10:36:18 -0600153 VkFormat m_format;
Ian Elliott7e40db92015-08-21 15:09:33 -0600154 VkColorSpaceKHR m_color_space;
Tony Barbour6a3faf02015-07-23 10:36:18 -0600155
156 uint32_t m_current_buffer;
Chia-I Wuf8693382015-04-16 22:02:10 +0800157
158 bool m_quit;
159 bool m_pause;
160
Tony Barbour7ea6aa22015-05-22 09:44:58 -0600161 int m_width;
162 int m_height;
Chia-I Wuf8693382015-04-16 22:02:10 +0800163
164 std::list<VkTestImageRecord>::iterator m_display_image;
165
166 void Display();
Tony Barbourfeb61962015-09-21 15:17:33 -0600167#ifndef _WIN32
Chia-I Wuf8693382015-04-16 22:02:10 +0800168 void HandleEvent(xcb_generic_event_t *event);
Tony Barbourfeb61962015-09-21 15:17:33 -0600169#endif
Chia-I Wuf8693382015-04-16 22:02:10 +0800170};
171
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600172#ifndef _WIN32
173
174#include <errno.h>
175
176int fopen_s(
177 FILE** pFile,
178 const char* filename,
179 const char* mode
180)
181{
182 if (!pFile || !filename || !mode) {
183 return EINVAL;
184 }
185
186 FILE* f = fopen(filename, mode);
187 if (! f) {
188 if (errno != 0) {
189 return errno;
190 } else {
191 return ENOENT;
192 }
193 }
194 *pFile = f;
195
196 return 0;
197}
198
199#endif
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600200
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600201
202
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600203// Set up environment for GLSL compiler
204// Must be done once per process
205void TestEnvironment::SetUp()
206{
Cody Northrop3bfd27c2015-03-17 15:55:58 -0600207 // Initialize GLSL to SPV compiler utility
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600208 glslang::InitializeProcess();
Chia-I Wub76e0fa2014-12-28 14:27:28 +0800209
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600210 vk_testing::set_error_callback(test_error_callback);
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600211}
212
213void TestEnvironment::TearDown()
214{
215 glslang::FinalizeProcess();
216}
217
Tony Barbour6918cd52015-04-09 12:58:51 -0600218VkTestFramework::VkTestFramework() :
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600219 m_compile_options( 0 ),
220 m_num_shader_strings( 0 )
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600221{
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600222
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600223}
224
Tony Barbour6918cd52015-04-09 12:58:51 -0600225VkTestFramework::~VkTestFramework()
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -0600226{
Courtney Goeltzenleuchtera0f74c52014-10-08 08:46:51 -0600227
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600228}
229
230// Define all the static elements
Cody Northropa3673cf2015-06-09 13:00:45 -0600231bool VkTestFramework::m_show_images = false;
232bool VkTestFramework::m_save_images = false;
233bool VkTestFramework::m_compare_images = false;
234bool VkTestFramework::m_use_glsl = false;
235bool VkTestFramework::m_canonicalize_spv = false;
236bool VkTestFramework::m_strip_spv = false;
Cody Northrop5a95b472015-06-03 13:01:54 -0600237bool VkTestFramework::m_do_everything_spv = false;
Tony Barbour6918cd52015-04-09 12:58:51 -0600238int VkTestFramework::m_width = 0;
239int VkTestFramework::m_height = 0;
240std::list<VkTestImageRecord> VkTestFramework::m_images;
241std::list<VkTestImageRecord>::iterator VkTestFramework::m_display_image;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600242int m_display_image_idx = 0;
243
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600244bool VkTestFramework::optionMatch(const char* option, char* optionLine)
245{
246 if (strncmp(option, optionLine, strlen(option)) == 0)
247 return true;
248 else
249 return false;
250}
251
Tony Barbour6918cd52015-04-09 12:58:51 -0600252void VkTestFramework::InitArgs(int *argc, char *argv[])
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600253{
254 int i, n;
255
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600256 for (i=1, n=1; i< *argc; i++) {
257 if (optionMatch("--show-images", argv[i]))
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600258 m_show_images = true;
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600259 else if (optionMatch("--save-images", argv[i]))
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600260 m_save_images = true;
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600261 else if (optionMatch("--no-SPV", argv[i]))
262 m_use_glsl = true;
263 else if (optionMatch("--strip-SPV", argv[i]))
264 m_strip_spv = true;
265 else if (optionMatch("--canonicalize-SPV", argv[i]))
266 m_canonicalize_spv = true;
267 else if (optionMatch("--compare-images", argv[i]))
Tony Barbour247bf372014-10-30 14:29:04 -0600268 m_compare_images = true;
Tony Barbour247bf372014-10-30 14:29:04 -0600269
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600270 else if (optionMatch("--help", argv[i]) ||
271 optionMatch("-h", argv[i])) {
Courtney Goeltzenleuchter31144b72014-12-02 13:13:10 -0700272 printf("\nOther options:\n");
273 printf("\t--show-images\n"
274 "\t\tDisplay test images in viewer after tests complete.\n");
275 printf("\t--save-images\n"
276 "\t\tSave tests images as ppm files in current working directory.\n"
277 "\t\tUsed to generate golden images for compare-images.\n");
278 printf("\t--compare-images\n"
279 "\t\tCompare test images to 'golden' image in golden folder.\n"
Tony Barboura98d3932014-12-11 09:52:49 -0700280 "\t\tAlso saves the generated test image in current working\n"
281 "\t\t\tdirectory but only if the image is different from the golden\n"
282 "\t\tSetting RENDERTEST_GOLDEN_DIR environment variable can specify\n"
283 "\t\t\tdifferent directory for golden images\n"
Courtney Goeltzenleuchter31144b72014-12-02 13:13:10 -0700284 "\t\tSignal test failure if different.\n");
Cody Northrop3bfd27c2015-03-17 15:55:58 -0600285 printf("\t--no-SPV\n"
286 "\t\tUse built-in GLSL compiler rather than SPV code path.\n");
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600287 printf("\t--strip-SPV\n"
Cody Northropa9bad9c2015-07-13 12:48:41 -0600288 "\t\tStrip SPIR-V debug information (line numbers, names, etc).\n");
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600289 printf("\t--canonicalize-SPV\n"
Cody Northropa9bad9c2015-07-13 12:48:41 -0600290 "\t\tRemap SPIR-V ids before submission to aid compression.\n");
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600291 exit(0);
292 } else {
293 printf("\nUnrecognized option: %s\n", argv[i]);
294 printf("\nUse --help or -h for option list.\n");
Tony Barbour4ab45422014-12-10 17:00:20 -0700295 exit(0);
Courtney Goeltzenleuchter31144b72014-12-02 13:13:10 -0700296 }
297
Cody Northrop50a2a4b2015-06-03 16:49:20 -0600298 /*
299 * Since the above "consume" inputs, update argv
300 * so that it contains the trimmed list of args for glutInit
301 */
302
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600303 argv[n] = argv[i];
304 n++;
305 }
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600306}
307
Tony Barbour2d6d54e2015-12-03 16:05:11 -0700308VkFormat VkTestFramework::GetFormat(VkInstance instance, vk_testing::Device *device)
309{
310 VkFormatProperties format_props;
311 if (!m_show_images)
312 {
313 vkGetPhysicalDeviceFormatProperties(device->phy().handle(), VK_FORMAT_B8G8R8A8_UNORM, &format_props);
314 if (format_props.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT ||
315 format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)
316 {
317 return VK_FORMAT_B8G8R8A8_UNORM;
318 }
319 vkGetPhysicalDeviceFormatProperties(device->phy().handle(), VK_FORMAT_R8G8B8A8_UNORM, &format_props);
320 if (format_props.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT ||
321 format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)
322 {
323 return VK_FORMAT_R8G8B8A8_UNORM;
324 }
325 printf("Error - device does not support VK_FORMAT_B8G8R8A8_UNORM nor VK_FORMAT_R8G8B8A8_UNORM - exiting\n");
326 exit(0);
327 }
328 else
329 {
330 /* To find which formats are presentable, you have to provide a surface to vkGetPhysicalDeviceSurfaceFormatsKHR */
331 /* To create a surface, you need a window. Use the present object to create a window, use that to create a */
332 /* KHR surface, and then find out what formats are presentable */
333 VkFormat presentFormat;
334 std::list<VkTestImageRecord> list;
335 VkTestImageRecord placeholder;
336 /* Use a dummy image record with non-zero area so the window will create on Windows */
337 placeholder.m_width = placeholder.m_height = 20;
338 list.push_back(placeholder);
339 TestFrameworkVkPresent vkPresent(*device);
340 vkPresent.InitPresentFramework(list, instance);
341 vkPresent.CreateMyWindow();
342 presentFormat = vkPresent.GetPresentFormat();
Tony Barboure1837292015-12-07 13:46:11 -0700343 vkPresent.DestroyMyWindow();
Tony Barbour2d6d54e2015-12-03 16:05:11 -0700344 return presentFormat;
345 }
346}
347
Tony Barbour6918cd52015-04-09 12:58:51 -0600348void VkTestFramework::WritePPM( const char *basename, VkImageObj *image )
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600349{
350 string filename;
Tony Barbour7ea6aa22015-05-22 09:44:58 -0600351 uint32_t x, y;
Tony Barbour6918cd52015-04-09 12:58:51 -0600352 VkImageObj displayImage(image->device());
Tony Barbour4c97d7a2015-04-22 15:10:33 -0600353 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
Tony Barbour84d448c2015-04-02 14:02:33 -0600354
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800355 displayImage.init(image->extent().width, image->extent().height, image->format(), VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_LINEAR, reqs);
Tony Barbour84d448c2015-04-02 14:02:33 -0600356 displayImage.CopyImage(*image);
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600357
358 filename.append(basename);
359 filename.append(".ppm");
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600360
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600361 const VkImageSubresource sr = {
Courtney Goeltzenleuchter908e7672015-10-21 17:00:51 -0600362 VK_IMAGE_ASPECT_COLOR_BIT, 0, 0
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600363 };
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600364 VkSubresourceLayout sr_layout;
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600365
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600366 vkGetImageSubresourceLayout(image->device()->device(), displayImage.image(), &sr, &sr_layout);
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600367
Tony Barbour84d448c2015-04-02 14:02:33 -0600368 char *ptr;
Chia-I Wu681d7a02015-07-03 13:44:34 +0800369 ptr = (char *) displayImage.MapMemory();
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600370 ptr += sr_layout.offset;
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600371 ofstream file (filename.c_str(), ios::binary);
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600372 ASSERT_TRUE(file.is_open()) << "Unable to open file: " << filename;
373
374 file << "P6\n";
Tony Barbourfeb61962015-09-21 15:17:33 -0600375 file << displayImage.width() << " ";
Tony Barbour84d448c2015-04-02 14:02:33 -0600376 file << displayImage.height() << "\n";
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600377 file << 255 << "\n";
378
Tony Barbour84d448c2015-04-02 14:02:33 -0600379 for (y = 0; y < displayImage.height(); y++) {
Tony Barboura53a6942015-02-25 11:25:11 -0700380 const int *row = (const int *) ptr;
381 int swapped;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600382
Tony Barbourd1c35722015-04-16 15:59:00 -0600383 if (displayImage.format() == VK_FORMAT_B8G8R8A8_UNORM)
Tony Barboura53a6942015-02-25 11:25:11 -0700384 {
Tony Barbour84d448c2015-04-02 14:02:33 -0600385 for (x = 0; x < displayImage.width(); x++) {
Tony Barboura53a6942015-02-25 11:25:11 -0700386 swapped = (*row & 0xff00ff00) | (*row & 0x000000ff) << 16 | (*row & 0x00ff0000) >> 16;
387 file.write((char *) &swapped, 3);
388 row++;
389 }
390 }
Tony Barbourd1c35722015-04-16 15:59:00 -0600391 else if (displayImage.format() == VK_FORMAT_R8G8B8A8_UNORM)
Tony Barboura53a6942015-02-25 11:25:11 -0700392 {
Tony Barbour84d448c2015-04-02 14:02:33 -0600393 for (x = 0; x < displayImage.width(); x++) {
Tony Barboura53a6942015-02-25 11:25:11 -0700394 file.write((char *) row, 3);
395 row++;
396 }
397 }
398 else {
399 printf("Unrecognized image format - will not write image files");
400 break;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600401 }
402
403 ptr += sr_layout.rowPitch;
404 }
405
406 file.close();
Chia-I Wu681d7a02015-07-03 13:44:34 +0800407 displayImage.UnmapMemory();
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600408}
409
Tony Barbour6918cd52015-04-09 12:58:51 -0600410void VkTestFramework::Compare(const char *basename, VkImageObj *image )
Tony Barbour247bf372014-10-30 14:29:04 -0600411{
412
413 MagickWand *magick_wand_1;
414 MagickWand *magick_wand_2;
415 MagickWand *compare_wand;
416 MagickBooleanType status;
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600417 char testimage[256],golden[MAX_PATH+256],golddir[MAX_PATH] = "./golden";
Tony Barbour247bf372014-10-30 14:29:04 -0600418 double differenz;
419
Tony Barbour4ab45422014-12-10 17:00:20 -0700420 if (getenv("RENDERTEST_GOLDEN_DIR"))
421 {
422 strcpy(golddir,getenv("RENDERTEST_GOLDEN_DIR"));
423 }
424
Tony Barbour247bf372014-10-30 14:29:04 -0600425 MagickWandGenesis();
426 magick_wand_1=NewMagickWand();
427 sprintf(testimage,"%s.ppm",basename);
428 status=MagickReadImage(magick_wand_1,testimage);
Tony Barbour7ea6aa22015-05-22 09:44:58 -0600429 ASSERT_EQ(status, MagickTrue) << "Unable to open file: " << testimage;
Tony Barbour247bf372014-10-30 14:29:04 -0600430
431
432 MagickWandGenesis();
433 magick_wand_2=NewMagickWand();
Tony Barbour4ab45422014-12-10 17:00:20 -0700434 sprintf(golden,"%s/%s.ppm",golddir,basename);
Tony Barbour247bf372014-10-30 14:29:04 -0600435 status=MagickReadImage(magick_wand_2,golden);
Tony Barbour7ea6aa22015-05-22 09:44:58 -0600436 ASSERT_EQ(status, MagickTrue) << "Unable to open file: " << golden;
Tony Barbour247bf372014-10-30 14:29:04 -0600437
Tony Barbour247bf372014-10-30 14:29:04 -0600438 compare_wand=MagickCompareImages(magick_wand_1,magick_wand_2, MeanAbsoluteErrorMetric, &differenz);
439 if (differenz != 0.0)
440 {
441 char difference[256];
442
443 sprintf(difference,"%s-diff.ppm",basename);
444 status = MagickWriteImage(compare_wand, difference);
445 ASSERT_TRUE(differenz == 0.0) << "Image comparison failed - diff file written";
446 }
447 DestroyMagickWand(compare_wand);
448
449 DestroyMagickWand(magick_wand_1);
450 DestroyMagickWand(magick_wand_2);
451 MagickWandTerminus();
Courtney Goeltzenleuchterfcda72d2014-12-05 15:41:02 -0700452
453 if (differenz == 0.0)
454 {
455 /*
456 * If test image and golden image match, we do not need to
457 * keep around the test image.
458 */
459 remove(testimage);
460 }
Tony Barbour247bf372014-10-30 14:29:04 -0600461}
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600462
Tony Barbour6918cd52015-04-09 12:58:51 -0600463void VkTestFramework::Show(const char *comment, VkImageObj *image)
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600464{
Courtney Goeltzenleuchterfcf43ab2015-04-29 10:53:31 -0600465 VkSubresourceLayout sr_layout;
466 char *ptr;
467 VkTestImageRecord record;
Courtney Goeltzenleuchterfcf43ab2015-04-29 10:53:31 -0600468 VkImageObj displayImage(image->device());
469 VkMemoryPropertyFlags reqs = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
470
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800471 displayImage.init(image->extent().width, image->extent().height, image->format(), VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_LINEAR, reqs);
Cody Northropc9a69912015-06-18 17:05:15 -0600472
Courtney Goeltzenleuchterfcf43ab2015-04-29 10:53:31 -0600473 displayImage.CopyImage(*image);
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600474
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600475 const VkImageSubresource sr = {
Courtney Goeltzenleuchter908e7672015-10-21 17:00:51 -0600476 VK_IMAGE_ASPECT_COLOR_BIT, 0, 0
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600477 };
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600478
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600479 vkGetImageSubresourceLayout(displayImage.device()->device(), displayImage.image(), &sr, &sr_layout);
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600480
Chia-I Wu681d7a02015-07-03 13:44:34 +0800481 ptr = (char *) displayImage.MapMemory();
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600482 ptr += sr_layout.offset;
483
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600484 record.m_title.append(comment);
Courtney Goeltzenleuchterfcf43ab2015-04-29 10:53:31 -0600485 record.m_width = displayImage.width();
486 record.m_height = displayImage.height();
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600487 // TODO: Need to make this more robust to handle different image formats
Tony-LunarG399dfca2015-05-19 14:08:26 -0600488 record.m_data_size = displayImage.width() * displayImage.height() * 4;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600489 record.m_data = malloc(record.m_data_size);
490 memcpy(record.m_data, ptr, record.m_data_size);
491 m_images.push_back(record);
492 m_display_image = --m_images.end();
493
Chia-I Wu681d7a02015-07-03 13:44:34 +0800494 displayImage.UnmapMemory();
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600495}
496
Tony Barbour6918cd52015-04-09 12:58:51 -0600497void VkTestFramework::RecordImages(vector<VkImageObj *> images)
Tony Barbour247bf372014-10-30 14:29:04 -0600498{
Courtney Goeltzenleuchtere5f0e6c2015-04-02 14:17:44 -0600499 for (int32_t i = 0; i < images.size(); i++) {
500 RecordImage(images[i]);
Tony Barbour247bf372014-10-30 14:29:04 -0600501 }
502}
503
Tony Barbour6918cd52015-04-09 12:58:51 -0600504void VkTestFramework::RecordImage(VkImageObj * image)
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600505{
506 const ::testing::TestInfo* const test_info =
507 ::testing::UnitTest::GetInstance()->current_test_info();
Tony Barbour247bf372014-10-30 14:29:04 -0600508 ostringstream filestream;
509 string filename;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600510
Tony Barbour247bf372014-10-30 14:29:04 -0600511 m_width = 40;
512
513 if (strcmp(test_info->name(), m_testName.c_str())) {
514 filestream << test_info->name();
515 m_testName.assign(test_info->name());
Tony Barboura0e2ee82014-11-18 17:02:36 -0700516 m_frameNum = 2;
517 filename = filestream.str();
Tony Barbour247bf372014-10-30 14:29:04 -0600518 }
519 else {
520 filestream << test_info->name() << "-" << m_frameNum;
521 m_frameNum++;
Tony Barboura0e2ee82014-11-18 17:02:36 -0700522 filename = filestream.str();
Tony Barbour247bf372014-10-30 14:29:04 -0600523 }
524
Tony Barbour247bf372014-10-30 14:29:04 -0600525 // ToDo - scrub string for bad characters
526
527 if (m_save_images || m_compare_images) {
528 WritePPM(filename.c_str(), image);
529 if (m_compare_images) {
530 Compare(filename.c_str(), image);
531 }
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600532 }
533
534 if (m_show_images) {
Courtney Goeltzenleuchter02d33c12014-10-08 14:26:40 -0600535 Show(test_info->name(), image);
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600536 }
537}
538
Chia-I Wuf8693382015-04-16 22:02:10 +0800539TestFrameworkVkPresent::TestFrameworkVkPresent(vk_testing::Device &device) :
540 m_device(device),
Courtney Goeltzenleuchterb4337c12015-03-05 16:47:18 -0700541 m_queue(*m_device.graphics_queues()[0]),
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800542 m_cmdpool(m_device, vk_testing::CommandPool::create_info(m_device.graphics_queue_node_index_)),
543 m_cmdbuf(m_device, vk_testing::CommandBuffer::create_info(m_cmdpool.handle()))
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600544{
Tony Barbour96db8822015-02-25 12:28:39 -0700545 m_quit = false;
546 m_pause = false;
547 m_width = 0;
548 m_height = 0;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600549}
550
Tony Barbour2d6d54e2015-12-03 16:05:11 -0700551VkFormat TestFrameworkVkPresent::GetPresentFormat()
552{
553 uint32_t formatCount;
554 VkResult U_ASSERT_ONLY res;
555 VkSurfaceKHR surface;
556 VkFormat returnFormat;
557
558#ifdef _WIN32
Ian Elliotta8914ac2015-12-11 14:05:35 -0700559 VkWin32SurfaceCreateInfoKHR createInfo;
560 createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
561 createInfo.pNext = NULL;
562 createInfo.flags = 0;
563 createInfo.connection = m_connection;
564 createInfo.window = m_window;
565
566 res = vkCreateWin32SurfaceKHR(m_instance, &createInfo, NULL, &surface);
Tony Barbour2d6d54e2015-12-03 16:05:11 -0700567#else // _WIN32
Ian Elliotta8914ac2015-12-11 14:05:35 -0700568 VkXcbSurfaceCreateInfoKHR createInfo;
569 createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
570 createInfo.pNext = NULL;
571 createInfo.flags = 0;
572 createInfo.connection = m_connection;
573 createInfo.window = m_window;
574
575 res = vkCreateXcbSurfaceKHR(m_instance, &createInfo, NULL, &surface);
Tony Barbour2d6d54e2015-12-03 16:05:11 -0700576#endif // _WIN32
577 assert(res == VK_SUCCESS);
578
579 m_fpGetPhysicalDeviceSurfaceFormatsKHR(
580 m_device.phy().handle(),
581 surface,
582 &formatCount, NULL);
583 VkSurfaceFormatKHR *surfFormats =
584 (VkSurfaceFormatKHR *)malloc(formatCount * sizeof(VkSurfaceFormatKHR));
585 m_fpGetPhysicalDeviceSurfaceFormatsKHR(
586 m_device.phy().handle(),
587 surface,
588 &formatCount, surfFormats);
589
590 m_fpDestroySurfaceKHR(m_instance, surface, NULL);
591
592 returnFormat = surfFormats[0].format;
593 free(surfFormats);
594 return returnFormat;
595}
596
Tony Barbour6918cd52015-04-09 12:58:51 -0600597void TestFrameworkVkPresent::Display()
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600598{
Tony Barbourf20f87b2015-04-22 09:02:32 -0600599 VkResult U_ASSERT_ONLY err;
Tony-LunarG399dfca2015-05-19 14:08:26 -0600600 vk_testing::Buffer buf;
601 void *dest_ptr;
602
Tony Barbour6a3faf02015-07-23 10:36:18 -0600603 VkSemaphore presentCompleteSemaphore;
604 VkSemaphoreCreateInfo presentCompleteSemaphoreCreateInfo = {};
605 presentCompleteSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
606 presentCompleteSemaphoreCreateInfo.pNext = NULL;
607 presentCompleteSemaphoreCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
608
609
610 err = vkCreateSemaphore(m_device.handle(),
611 &presentCompleteSemaphoreCreateInfo,
Chia-I Wuf7458c52015-10-26 21:10:41 +0800612 NULL, &presentCompleteSemaphore);
Tony Barbour6a3faf02015-07-23 10:36:18 -0600613 assert(!err);
614
615 // Get the index of the next available swapchain image:
Ian Elliott7e40db92015-08-21 15:09:33 -0600616 err = m_fpAcquireNextImageKHR(m_device.handle(), m_swap_chain,
Tony Barbour6a3faf02015-07-23 10:36:18 -0600617 UINT64_MAX,
618 presentCompleteSemaphore,
Ian Elliottc11750d2015-10-30 13:24:12 -0600619 VK_NULL_HANDLE,
Tony Barbour6a3faf02015-07-23 10:36:18 -0600620 &m_current_buffer);
Ian Elliott7e40db92015-08-21 15:09:33 -0600621 // TODO: Deal with the VK_SUBOPTIMAL_KHR and VK_ERROR_OUT_OF_DATE_KHR
Tony Barbour6a3faf02015-07-23 10:36:18 -0600622 // return codes
623 assert(!err);
624
Tony-LunarG399dfca2015-05-19 14:08:26 -0600625 VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
Cody Northrop7fb43862015-06-22 14:56:14 -0600626 buf.init_as_src(m_device, (VkDeviceSize)m_display_image->m_data_size, flags);
Chia-I Wu681d7a02015-07-03 13:44:34 +0800627 dest_ptr = buf.memory().map();
Tony-LunarG399dfca2015-05-19 14:08:26 -0600628 memcpy(dest_ptr, m_display_image->m_data, m_display_image->m_data_size);
Chia-I Wu681d7a02015-07-03 13:44:34 +0800629 buf.memory().unmap();
Tony-LunarG399dfca2015-05-19 14:08:26 -0600630
631 m_cmdbuf.begin();
Tony Barbourbd094ce2015-10-23 11:00:15 -0600632 VkImageMemoryBarrier memoryBarrier = {};
633 memoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
634 memoryBarrier.pNext = NULL;
Tony Barbourd800bbd2015-11-05 10:54:44 -0700635 memoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
Chia-I Wua4594202015-10-27 19:54:37 +0800636 memoryBarrier.dstAccessMask = 0;
Ian Elliott1dcd1092015-11-17 17:29:40 -0700637 memoryBarrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800638 memoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
Tony Barbourbd094ce2015-10-23 11:00:15 -0600639 memoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800640 memoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
Tony Barbourbd094ce2015-10-23 11:00:15 -0600641 memoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
642 memoryBarrier.subresourceRange.baseMipLevel = 0;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800643 memoryBarrier.subresourceRange.levelCount = 1;
Tony Barbourbd094ce2015-10-23 11:00:15 -0600644 memoryBarrier.subresourceRange.baseArrayLayer = 0;
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800645 memoryBarrier.subresourceRange.layerCount = 1;
Tony Barbourbd094ce2015-10-23 11:00:15 -0600646 memoryBarrier.image = m_buffers[m_current_buffer].image;
647 VkImageMemoryBarrier *pmemory_barrier = &memoryBarrier;
Chia-I Wu89d0f942015-10-31 00:31:16 +0800648 vkCmdPipelineBarrier(m_cmdbuf.handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
Chia-I Wu53534662015-10-26 17:08:33 +0800649 0, 1, (const void * const*)&pmemory_barrier);
Tony-LunarG399dfca2015-05-19 14:08:26 -0600650
651 VkBufferImageCopy region = {};
Tony Barbourd800bbd2015-11-05 10:54:44 -0700652 region.bufferRowLength = m_display_image->m_width;
653 region.bufferImageHeight = m_display_image->m_height;
654 region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
655 region.imageSubresource.layerCount = 1;
Tony-LunarG399dfca2015-05-19 14:08:26 -0600656 region.imageExtent.height = m_display_image->m_height;
657 region.imageExtent.width = m_display_image->m_width;
658 region.imageExtent.depth = 1;
659
Chia-I Wube2b9172015-07-03 11:49:42 +0800660 vkCmdCopyBufferToImage(m_cmdbuf.handle(),
Chia-I Wu681d7a02015-07-03 13:44:34 +0800661 buf.handle(),
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800662 m_buffers[m_current_buffer].image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
Tony-LunarG399dfca2015-05-19 14:08:26 -0600663 1, &region);
Tony Barbourbd094ce2015-10-23 11:00:15 -0600664
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800665 memoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
Ian Elliott1dcd1092015-11-17 17:29:40 -0700666 memoryBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
Chia-I Wu89d0f942015-10-31 00:31:16 +0800667 vkCmdPipelineBarrier(m_cmdbuf.handle(), VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
Chia-I Wu53534662015-10-26 17:08:33 +0800668 0, 1, (const void * const*)&pmemory_barrier);
Tony-LunarG399dfca2015-05-19 14:08:26 -0600669 m_cmdbuf.end();
670
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800671 VkCommandBuffer cmdBufs[1];
Chia-I Wube2b9172015-07-03 11:49:42 +0800672 cmdBufs[0] = m_cmdbuf.handle();
Tony-LunarG399dfca2015-05-19 14:08:26 -0600673
Chia-I Wua690b412015-10-29 22:01:53 +0800674 // Wait for the present complete semaphore to be signaled to ensure
675 // that the image won't be rendered to until the presentation
676 // engine has fully released ownership to the application, and it is
677 // okay to render to the image.
Tony Barbour67e99152015-07-10 14:10:27 -0600678 VkFence nullFence = { VK_NULL_HANDLE };
Courtney Goeltzenleuchter806c7002015-10-27 11:22:14 -0600679 VkSubmitInfo submit_info;
Chia-I Wuf9be13c2015-10-26 20:37:06 +0800680 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
681 submit_info.pNext = NULL;
Chia-I Wud50a7d72015-10-26 20:48:51 +0800682 submit_info.waitSemaphoreCount = 1;
Chia-I Wua690b412015-10-29 22:01:53 +0800683 submit_info.pWaitSemaphores = &presentCompleteSemaphore,
Chia-I Wud50a7d72015-10-26 20:48:51 +0800684 submit_info.commandBufferCount = 1;
Courtney Goeltzenleuchter806c7002015-10-27 11:22:14 -0600685 submit_info.pCommandBuffers = cmdBufs;
Chia-I Wud50a7d72015-10-26 20:48:51 +0800686 submit_info.signalSemaphoreCount = 0;
Courtney Goeltzenleuchter806c7002015-10-27 11:22:14 -0600687 submit_info.pSignalSemaphores = NULL;
688
Courtney Goeltzenleuchter646b9072015-10-20 18:04:07 -0600689 vkQueueSubmit(m_queue.handle(), 1, &submit_info, nullFence);
Tony-LunarG399dfca2015-05-19 14:08:26 -0600690 m_queue.wait();
Tony Barbour96db8822015-02-25 12:28:39 -0700691
Chia-I Wuf7458c52015-10-26 21:10:41 +0800692 vkDestroySemaphore(m_device.handle(), presentCompleteSemaphore, NULL);
Chia-I Wua690b412015-10-29 22:01:53 +0800693
Ian Elliott7e40db92015-08-21 15:09:33 -0600694 VkPresentInfoKHR present = {};
695 present.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
Tony Barbour6a3faf02015-07-23 10:36:18 -0600696 present.pNext = NULL;
Ian Elliott7e40db92015-08-21 15:09:33 -0600697 present.swapchainCount = 1;
Ian Elliottc11750d2015-10-30 13:24:12 -0600698 present.pSwapchains = & m_swap_chain;
699 present.pImageIndices = &m_current_buffer;
Tony Barbour96db8822015-02-25 12:28:39 -0700700
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600701#ifndef _WIN32
Chia-I Wuf8693382015-04-16 22:02:10 +0800702 xcb_change_property (m_connection,
Tony Barbour96db8822015-02-25 12:28:39 -0700703 XCB_PROP_MODE_REPLACE,
704 m_window,
705 XCB_ATOM_WM_NAME,
706 XCB_ATOM_STRING,
707 8,
708 m_display_image->m_title.size(),
709 m_display_image->m_title.c_str());
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600710#endif
Jon Ashburn07daee72015-05-21 18:13:33 -0600711
Ian Elliott7e40db92015-08-21 15:09:33 -0600712 err = m_fpQueuePresentKHR(m_queue.handle(), &present);
Tony Barbour96db8822015-02-25 12:28:39 -0700713 assert(!err);
714
715 m_queue.wait();
Tony-LunarG399dfca2015-05-19 14:08:26 -0600716 m_current_buffer = (m_current_buffer + 1) % 2;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600717}
718
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600719#ifdef _WIN32
Tony-LunarG399dfca2015-05-19 14:08:26 -0600720# define PREVIOUSLY_DOWN 1<<29
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600721// MS-Windows event handling function:
722LRESULT CALLBACK TestFrameworkVkPresent::WndProc(HWND hWnd,
723 UINT uMsg,
724 WPARAM wParam,
725 LPARAM lParam)
726{
727
728 switch(uMsg)
729 {
730 case WM_CLOSE:
731 PostQuitMessage(0);
732 break;
733
734 case WM_PAINT:
735 {
736 TestFrameworkVkPresent* me = reinterpret_cast<TestFrameworkVkPresent*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
737 if (me) {
Tony-LunarG399dfca2015-05-19 14:08:26 -0600738 SetWindowText(hWnd, me->m_display_image->m_title.c_str());
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600739 me->Display();
740 }
741 }
Tony-LunarG399dfca2015-05-19 14:08:26 -0600742 break;
743
744 case WM_KEYDOWN:
745 {
746 if (lParam & (PREVIOUSLY_DOWN)){
747 break;
748 }
749 // To be able to be a CALLBACK, WndProc had to be static, so it doesn't get a this pointer. When we created
750 // the window, we put the this pointer into the window's user data so we could get it back now
751 TestFrameworkVkPresent* me = reinterpret_cast<TestFrameworkVkPresent*>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
752 switch (wParam)
753 {
754 case VK_ESCAPE: me->m_quit = true;
755 break;
756
757 case VK_LEFT: // left arrow key
758 if (me->m_display_image == me->m_images.begin()) {
759 me->m_display_image = --me->m_images.end();
760 }
761 else {
762 --me->m_display_image;
763 }
764 break;
765
766 case VK_RIGHT: // right arrow key
767 ++me->m_display_image;
768 if (me->m_display_image == me->m_images.end()) {
769 me->m_display_image = me->m_images.begin();
770 }
771 break;
772
773 default:
774 break;
775 }
776 SetWindowText(hWnd, me->m_display_image->m_title.c_str());
777 me->Display();
778 }
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600779 }
780 return (DefWindowProc(hWnd, uMsg, wParam, lParam));
781}
782
783void TestFrameworkVkPresent::Run()
784{
785 MSG msg; // message
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600786
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600787 /* main message loop*/
Tony-LunarG399dfca2015-05-19 14:08:26 -0600788 while(! m_quit) {
789 GetMessage(&msg, m_window, 0, 0);
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600790 if (msg.message == WM_QUIT) {
Tony-LunarG399dfca2015-05-19 14:08:26 -0600791 m_quit = true; //if found, quit app
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600792 } else {
793 /* Translate and dispatch to event queue*/
794 TranslateMessage(&msg);
795 DispatchMessage(&msg);
796 }
797 }
798}
799
800#else
Tony Barbour6918cd52015-04-09 12:58:51 -0600801void TestFrameworkVkPresent::HandleEvent(xcb_generic_event_t *event)
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600802{
Tony Barbour0dd968a2015-04-02 15:48:24 -0600803 uint8_t event_code = event->response_type & 0x7f;
Tony Barbour96db8822015-02-25 12:28:39 -0700804 switch (event_code) {
805 case XCB_EXPOSE:
806 Display(); // TODO: handle resize
807 break;
808 case XCB_CLIENT_MESSAGE:
809 if((*(xcb_client_message_event_t*)event).data.data32[0] ==
810 (m_atom_wm_delete_window)->atom) {
811 m_quit = true;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600812 }
813 break;
Tony Barbour96db8822015-02-25 12:28:39 -0700814 case XCB_KEY_RELEASE:
815 {
816 const xcb_key_release_event_t *key =
817 (const xcb_key_release_event_t *) event;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600818
Tony Barbour96db8822015-02-25 12:28:39 -0700819 switch (key->detail) {
820 case 0x9: // Escape
821 m_quit = true;
822 break;
823 case 0x71: // left arrow key
824 if (m_display_image == m_images.begin()) {
825 m_display_image = --m_images.end();
826 } else {
827 --m_display_image;
828 }
829 break;
830 case 0x72: // right arrow key
831 ++m_display_image;
832 if (m_display_image == m_images.end()) {
833 m_display_image = m_images.begin();
834 }
835 break;
836 case 0x41:
837 m_pause = !m_pause;
838 break;
839 }
840 Display();
841 }
842 break;
843 default:
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -0600844 break;
845 }
Tony Barbour96db8822015-02-25 12:28:39 -0700846}
847
Tony Barbour6918cd52015-04-09 12:58:51 -0600848void TestFrameworkVkPresent::Run()
Tony Barbour96db8822015-02-25 12:28:39 -0700849{
Chia-I Wuf8693382015-04-16 22:02:10 +0800850 xcb_flush(m_connection);
Tony Barbour96db8822015-02-25 12:28:39 -0700851
852 while (! m_quit) {
853 xcb_generic_event_t *event;
854
855 if (m_pause) {
Chia-I Wuf8693382015-04-16 22:02:10 +0800856 event = xcb_wait_for_event(m_connection);
Tony Barbour96db8822015-02-25 12:28:39 -0700857 } else {
Chia-I Wuf8693382015-04-16 22:02:10 +0800858 event = xcb_poll_for_event(m_connection);
Tony Barbour96db8822015-02-25 12:28:39 -0700859 }
860 if (event) {
861 HandleEvent(event);
862 free(event);
863 }
864 }
865}
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600866#endif // _WIN32
Tony Barbour96db8822015-02-25 12:28:39 -0700867
Ian Elliott7e40db92015-08-21 15:09:33 -0600868void TestFrameworkVkPresent::CreateSwapchain()
Tony Barbour96db8822015-02-25 12:28:39 -0700869{
Tony Barbourf20f87b2015-04-22 09:02:32 -0600870 VkResult U_ASSERT_ONLY err;
Tony Barbour96db8822015-02-25 12:28:39 -0700871
Tony-LunarG399dfca2015-05-19 14:08:26 -0600872 m_display_image = m_images.begin();
873 m_current_buffer = 0;
874
Ian Elliottc11750d2015-10-30 13:24:12 -0600875 // Create the WSI surface:
Ian Elliott1a3845b2015-07-06 14:33:04 -0600876#ifdef _WIN32
Ian Elliotta8914ac2015-12-11 14:05:35 -0700877 VkWin32SurfaceCreateInfoKHR createInfo;
878 createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
879 createInfo.pNext = NULL;
880 createInfo.flags = 0;
881 createInfo.connection = m_connection;
882 createInfo.window = m_window;
883
884 err = vkCreateWin32SurfaceKHR(m_instance, &createInfo, NULL, &m_surface);
Ian Elliott1a3845b2015-07-06 14:33:04 -0600885#else // _WIN32
Ian Elliotta8914ac2015-12-11 14:05:35 -0700886 VkXcbSurfaceCreateInfoKHR createInfo;
887 createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
888 createInfo.pNext = NULL;
889 createInfo.flags = 0;
890 createInfo.connection = m_connection;
891 createInfo.window = m_window;
892
893 err = vkCreateXcbSurfaceKHR(m_instance, &createInfo, NULL, &m_surface);
Ian Elliott1a3845b2015-07-06 14:33:04 -0600894#endif // _WIN32
Ian Elliottc11750d2015-10-30 13:24:12 -0600895 assert(!err);
Tony Barbour6a3faf02015-07-23 10:36:18 -0600896
897 // Iterate over each queue to learn whether it supports presenting to WSI:
898 VkBool32 supportsPresent;
899 m_present_queue_node_index = UINT32_MAX;
900 std::vector<vk_testing::Queue *> queues = m_device.graphics_queues();
901 for (int i=0; i < queues.size(); i++)
902 {
903 int family_index = queues[i]->get_family_index();
Ian Elliott7e40db92015-08-21 15:09:33 -0600904 m_fpGetPhysicalDeviceSurfaceSupportKHR(m_device.phy().handle(),
Tony Barbour6a3faf02015-07-23 10:36:18 -0600905 family_index,
Ian Elliottc11750d2015-10-30 13:24:12 -0600906 m_surface,
Tony Barbour6a3faf02015-07-23 10:36:18 -0600907 &supportsPresent);
908 if (supportsPresent) {
909 m_present_queue_node_index = family_index;
910 }
911 }
912
913 assert(m_present_queue_node_index != UINT32_MAX);
914
915
916 // Get the list of VkFormat's that are supported:
Ian Elliott8b139792015-08-07 11:51:12 -0600917 uint32_t formatCount;
Ian Elliottc11750d2015-10-30 13:24:12 -0600918 err = m_fpGetPhysicalDeviceSurfaceFormatsKHR(m_device.phy().handle(),
919 m_surface,
Ian Elliott8b139792015-08-07 11:51:12 -0600920 &formatCount, NULL);
Tony Barbour6a3faf02015-07-23 10:36:18 -0600921 assert(!err);
Ian Elliott7e40db92015-08-21 15:09:33 -0600922 VkSurfaceFormatKHR *surfFormats =
923 (VkSurfaceFormatKHR *)malloc(formatCount * sizeof(VkSurfaceFormatKHR));
Ian Elliottc11750d2015-10-30 13:24:12 -0600924 err = m_fpGetPhysicalDeviceSurfaceFormatsKHR(m_device.phy().handle(),
925 m_surface,
Ian Elliott8b139792015-08-07 11:51:12 -0600926 &formatCount, surfFormats);
Tony Barbour6a3faf02015-07-23 10:36:18 -0600927 assert(!err);
928 // If the format list includes just one entry of VK_FORMAT_UNDEFINED,
929 // the surface has no preferred format. Otherwise, at least one
930 // supported format will be returned.
Tony Barbour6a3faf02015-07-23 10:36:18 -0600931 if (formatCount == 1 && surfFormats[0].format == VK_FORMAT_UNDEFINED)
932 {
933 m_format = VK_FORMAT_B8G8R8A8_UNORM;
934 }
935 else
936 {
937 assert(formatCount >= 1);
938 m_format = surfFormats[0].format;
939 }
Ian Elliott8b139792015-08-07 11:51:12 -0600940 m_color_space = surfFormats[0].colorSpace;
Tony Barbour6a3faf02015-07-23 10:36:18 -0600941
Ian Elliottc11750d2015-10-30 13:24:12 -0600942 // Check the surface capabilities and formats
943 VkSurfaceCapabilitiesKHR surfCapabilities;
944 err = m_fpGetPhysicalDeviceSurfaceCapabilitiesKHR(m_device.phy().handle(),
945 m_surface,
946 &surfCapabilities);
Tony Barbour6a3faf02015-07-23 10:36:18 -0600947 assert(!err);
948
Ian Elliott8b139792015-08-07 11:51:12 -0600949 uint32_t presentModeCount;
Ian Elliottc11750d2015-10-30 13:24:12 -0600950 err = m_fpGetPhysicalDeviceSurfacePresentModesKHR(m_device.phy().handle(),
951 m_surface,
Ian Elliott8b139792015-08-07 11:51:12 -0600952 &presentModeCount, NULL);
Tony Barbour6a3faf02015-07-23 10:36:18 -0600953 assert(!err);
Ian Elliott7e40db92015-08-21 15:09:33 -0600954 VkPresentModeKHR *presentModes =
955 (VkPresentModeKHR *)malloc(presentModeCount * sizeof(VkPresentModeKHR));
Ian Elliott8b139792015-08-07 11:51:12 -0600956 assert(presentModes);
Ian Elliottc11750d2015-10-30 13:24:12 -0600957 err = m_fpGetPhysicalDeviceSurfacePresentModesKHR(m_device.phy().handle(),
958 m_surface,
Ian Elliott8b139792015-08-07 11:51:12 -0600959 &presentModeCount, presentModes);
Tony Barbour6a3faf02015-07-23 10:36:18 -0600960 assert(!err);
961
Ian Elliott7e40db92015-08-21 15:09:33 -0600962 VkExtent2D swapchainExtent;
Tony Barbour6a3faf02015-07-23 10:36:18 -0600963 // width and height are either both -1, or both not -1.
Ian Elliottc11750d2015-10-30 13:24:12 -0600964 if (surfCapabilities.currentExtent.width == -1)
Tony Barbour6a3faf02015-07-23 10:36:18 -0600965 {
966 // If the surface size is undefined, the size is set to
967 // the size of the images requested.
Ian Elliott7e40db92015-08-21 15:09:33 -0600968 swapchainExtent.width = m_width;
969 swapchainExtent.height = m_height;
Tony Barbour6a3faf02015-07-23 10:36:18 -0600970 }
971 else
972 {
973 // If the surface size is defined, the swap chain size must match
Ian Elliottc11750d2015-10-30 13:24:12 -0600974 swapchainExtent = surfCapabilities.currentExtent;
Tony Barbour6a3faf02015-07-23 10:36:18 -0600975 }
976
977 // If mailbox mode is available, use it, as is the lowest-latency non-
Ian Elliottae0e8242015-08-10 13:20:49 -0600978 // tearing mode. If not, try IMMEDIATE which will usually be available,
979 // and is fastest (though it tears). If not, fall back to FIFO which is
980 // always available.
Ian Elliott7e40db92015-08-21 15:09:33 -0600981 VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
Tony Barbour6a3faf02015-07-23 10:36:18 -0600982 for (size_t i = 0; i < presentModeCount; i++) {
Ian Elliott7e40db92015-08-21 15:09:33 -0600983 if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
984 swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
Tony Barbour6a3faf02015-07-23 10:36:18 -0600985 break;
986 }
Ian Elliott7e40db92015-08-21 15:09:33 -0600987 if ((swapchainPresentMode != VK_PRESENT_MODE_MAILBOX_KHR) &&
988 (presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR)) {
989 swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
Ian Elliottae0e8242015-08-10 13:20:49 -0600990 }
Tony Barbour6a3faf02015-07-23 10:36:18 -0600991 }
992
993 // Determine the number of VkImage's to use in the swap chain (we desire to
994 // own only 1 image at a time, besides the images being displayed and
995 // queued for display):
Ian Elliottc11750d2015-10-30 13:24:12 -0600996 uint32_t desiredNumberOfSwapchainImages = surfCapabilities.minImageCount + 1;
997 if ((surfCapabilities.maxImageCount > 0) &&
998 (desiredNumberOfSwapchainImages > surfCapabilities.maxImageCount))
Tony Barbour6a3faf02015-07-23 10:36:18 -0600999 {
1000 // Application must settle for fewer images than desired:
Ian Elliottc11750d2015-10-30 13:24:12 -06001001 desiredNumberOfSwapchainImages = surfCapabilities.maxImageCount;
Tony Barbour6a3faf02015-07-23 10:36:18 -06001002 }
1003
Ian Elliottc11750d2015-10-30 13:24:12 -06001004 VkSurfaceTransformFlagsKHR preTransform;
Ian Elliotta8914ac2015-12-11 14:05:35 -07001005 if (surfCapabilities.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
1006 preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
Tony Barbour6a3faf02015-07-23 10:36:18 -06001007 } else {
Ian Elliottc11750d2015-10-30 13:24:12 -06001008 preTransform = surfCapabilities.currentTransform;
Tony Barbour6a3faf02015-07-23 10:36:18 -06001009 }
Ian Elliott1a3845b2015-07-06 14:33:04 -06001010
Cody Northropdf5b0922015-08-28 16:22:48 -06001011 // We want to blit to the swap chain, ensure the driver supports it. Color is always supported, per WSI spec.
Ian Elliottc11750d2015-10-30 13:24:12 -06001012 assert((surfCapabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) != 0);
Cody Northropdf5b0922015-08-28 16:22:48 -06001013
Ian Elliott7e40db92015-08-21 15:09:33 -06001014 VkSwapchainCreateInfoKHR swap_chain = {};
Ian Elliotta257eea2015-09-22 10:20:23 -06001015 swap_chain.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
Ian Elliott1a3845b2015-07-06 14:33:04 -06001016 swap_chain.pNext = NULL;
Ian Elliottc11750d2015-10-30 13:24:12 -06001017 swap_chain.surface = m_surface;
Ian Elliott7e40db92015-08-21 15:09:33 -06001018 swap_chain.minImageCount = desiredNumberOfSwapchainImages;
Tony Barbour6a3faf02015-07-23 10:36:18 -06001019 swap_chain.imageFormat = m_format;
Ian Elliott8b139792015-08-07 11:51:12 -06001020 swap_chain.imageColorSpace = m_color_space;
Ian Elliott7e40db92015-08-21 15:09:33 -06001021 swap_chain.imageExtent.width = swapchainExtent.width;
1022 swap_chain.imageExtent.height = swapchainExtent.height;
Ian Elliottc11750d2015-10-30 13:24:12 -06001023 swap_chain.imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT |
1024 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1025 swap_chain.preTransform = (VkSurfaceTransformFlagBitsKHR) preTransform;
1026 swap_chain.imageArrayLayers = 1;
1027 swap_chain.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
1028 swap_chain.queueFamilyIndexCount = 0;
Ian Elliott8b139792015-08-07 11:51:12 -06001029 swap_chain.pQueueFamilyIndices = NULL;
Ian Elliott7e40db92015-08-21 15:09:33 -06001030 swap_chain.presentMode = swapchainPresentMode;
Chia-I Wue2fc5522015-10-26 20:04:44 +08001031 swap_chain.oldSwapchain = VK_NULL_HANDLE;
Tony Barbour6a3faf02015-07-23 10:36:18 -06001032 swap_chain.clipped = true;
1033
1034 uint32_t i;
Chia-I Wuf8693382015-04-16 22:02:10 +08001035
Ian Elliottc11750d2015-10-30 13:24:12 -06001036 err = m_fpCreateSwapchainKHR(m_device.handle(), &swap_chain, NULL, &m_swap_chain);
Chia-I Wuf8693382015-04-16 22:02:10 +08001037 assert(!err);
1038
Ian Elliott7e40db92015-08-21 15:09:33 -06001039 err = m_fpGetSwapchainImagesKHR(m_device.handle(), m_swap_chain,
1040 &m_swapchainImageCount, NULL);
Tony Barbour6a3faf02015-07-23 10:36:18 -06001041 assert(!err);
1042
Ian Elliott7e40db92015-08-21 15:09:33 -06001043 VkImage* swapchainImages = (VkImage*)malloc(m_swapchainImageCount * sizeof(VkImage));
1044 assert(swapchainImages);
1045 err = m_fpGetSwapchainImagesKHR(m_device.handle(), m_swap_chain,
1046 &m_swapchainImageCount, swapchainImages);
Tony Barbour6a3faf02015-07-23 10:36:18 -06001047 assert(!err);
1048
Ian Elliott7e40db92015-08-21 15:09:33 -06001049 m_buffers = (SwapchainBuffers*)malloc(sizeof(SwapchainBuffers)*m_swapchainImageCount);
Tony Barbour6a3faf02015-07-23 10:36:18 -06001050 assert(m_buffers);
1051
Ian Elliott7e40db92015-08-21 15:09:33 -06001052 for (i = 0; i < m_swapchainImageCount; i++) {
Courtney Goeltzenleuchter5861a1b2015-09-01 17:30:39 -06001053 VkImageViewCreateInfo color_image_view = {};
1054 color_image_view.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
1055 color_image_view.pNext = NULL;
1056 color_image_view.format = m_format;
Tony Barbourd800bbd2015-11-05 10:54:44 -07001057 color_image_view.components.r = VK_COMPONENT_SWIZZLE_R;
1058 color_image_view.components.g = VK_COMPONENT_SWIZZLE_G;
1059 color_image_view.components.b = VK_COMPONENT_SWIZZLE_B;
1060 color_image_view.components.a = VK_COMPONENT_SWIZZLE_A;
Courtney Goeltzenleuchterba724512015-09-10 17:58:54 -06001061 color_image_view.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
Courtney Goeltzenleuchter5861a1b2015-09-01 17:30:39 -06001062 color_image_view.subresourceRange.baseMipLevel = 0;
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001063 color_image_view.subresourceRange.levelCount = 1;
Courtney Goeltzenleuchter4a261892015-09-10 16:38:41 -06001064 color_image_view.subresourceRange.baseArrayLayer = 0;
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001065 color_image_view.subresourceRange.layerCount = 1;
Tony Barbourd800bbd2015-11-05 10:54:44 -07001066 color_image_view.viewType = VK_IMAGE_VIEW_TYPE_2D;
1067 color_image_view.flags = 0;
Tony Barbour6a3faf02015-07-23 10:36:18 -06001068
Ian Elliott7e40db92015-08-21 15:09:33 -06001069 m_buffers[i].image = swapchainImages[i];
Tony Barbour6a3faf02015-07-23 10:36:18 -06001070
Courtney Goeltzenleuchter5861a1b2015-09-01 17:30:39 -06001071 color_image_view.image = m_buffers[i].image;
1072 err = vkCreateImageView(m_device.handle(),
Chia-I Wuf7458c52015-10-26 21:10:41 +08001073 &color_image_view, NULL, &m_buffers[i].view);
Tony Barbour6a3faf02015-07-23 10:36:18 -06001074 assert(!err);
Tony Barbourbd094ce2015-10-23 11:00:15 -06001075
1076 /* Set image layout to PRESENT_SOURCE_KHR so that before the copy, it can be set to */
1077 /* TRANSFER_DESTINATION_OPTIMAL */
1078 SetImageLayout(m_buffers[i].image, VK_IMAGE_ASPECT_COLOR_BIT,
Ian Elliott1dcd1092015-11-17 17:29:40 -07001079 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
Tony Barbourbd094ce2015-10-23 11:00:15 -06001080
Tony Barbour6a3faf02015-07-23 10:36:18 -06001081 }
Tony Barbour96db8822015-02-25 12:28:39 -07001082}
Tony Barbourbd094ce2015-10-23 11:00:15 -06001083void TestFrameworkVkPresent::SetImageLayout(VkImage image, VkImageAspectFlags aspectMask,
1084 VkImageLayout old_image_layout, VkImageLayout new_image_layout)
1085{
1086 VkResult U_ASSERT_ONLY err;
1087
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001088 VkCommandBufferBeginInfo cmd_buf_info = {};
1089 cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
Tony Barbourbd094ce2015-10-23 11:00:15 -06001090 cmd_buf_info.pNext = NULL;
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001091 cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
Tony Barbourbd094ce2015-10-23 11:00:15 -06001092 cmd_buf_info.renderPass = { VK_NULL_HANDLE };
1093 cmd_buf_info.subpass = 0;
1094 cmd_buf_info.framebuffer = { VK_NULL_HANDLE };
Chia-I Wub8d47ae2015-11-11 10:18:12 +08001095 cmd_buf_info.occlusionQueryEnable = VK_FALSE;
1096 cmd_buf_info.queryFlags = 0;
1097 cmd_buf_info.pipelineStatistics = 0;
Tony Barbourbd094ce2015-10-23 11:00:15 -06001098
1099 err = vkBeginCommandBuffer(m_cmdbuf.handle(), &cmd_buf_info);
1100 assert(!err);
1101
1102 VkImageMemoryBarrier image_memory_barrier = {};
1103 image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
1104 image_memory_barrier.pNext = NULL;
Chia-I Wua4594202015-10-27 19:54:37 +08001105 image_memory_barrier.srcAccessMask = 0;
1106 image_memory_barrier.dstAccessMask = 0;
Tony Barbourbd094ce2015-10-23 11:00:15 -06001107 image_memory_barrier.oldLayout = old_image_layout;
1108 image_memory_barrier.newLayout = new_image_layout;
1109 image_memory_barrier.image = image;
1110 image_memory_barrier.subresourceRange.aspectMask = aspectMask;
1111 image_memory_barrier.subresourceRange.baseMipLevel = 0;
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001112 image_memory_barrier.subresourceRange.levelCount = 1;
Tony Barbourbd094ce2015-10-23 11:00:15 -06001113 image_memory_barrier.subresourceRange.baseArrayLayer = 0;
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001114 image_memory_barrier.subresourceRange.layerCount = 1;
Tony Barbourbd094ce2015-10-23 11:00:15 -06001115
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001116 if (new_image_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
Tony Barbourbd094ce2015-10-23 11:00:15 -06001117 /* Make sure anything that was copying from this image has completed */
Chia-I Wua4594202015-10-27 19:54:37 +08001118 image_memory_barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
Tony Barbourbd094ce2015-10-23 11:00:15 -06001119 }
1120
1121 if (new_image_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
1122 /* Make sure any Copy or CPU writes to image are flushed */
Chia-I Wua4594202015-10-27 19:54:37 +08001123 image_memory_barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT;
Tony Barbourbd094ce2015-10-23 11:00:15 -06001124 }
1125
1126 VkImageMemoryBarrier *pmemory_barrier = &image_memory_barrier;
1127
1128 VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
1129 VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
1130
Chia-I Wu53534662015-10-26 17:08:33 +08001131 vkCmdPipelineBarrier(m_cmdbuf.handle(), src_stages, dest_stages, 0, 1, (const void * const*)&pmemory_barrier);
Tony Barbourbd094ce2015-10-23 11:00:15 -06001132
1133 err = vkEndCommandBuffer(m_cmdbuf.handle());
1134 assert(!err);
1135
Chia-I Wu3432a0c2015-10-27 18:04:07 +08001136 const VkCommandBuffer cmd_bufs[] = { m_cmdbuf.handle() };
Tony Barbourbd094ce2015-10-23 11:00:15 -06001137 VkFence nullFence = { VK_NULL_HANDLE };
Courtney Goeltzenleuchter806c7002015-10-27 11:22:14 -06001138 VkSubmitInfo submit_info;
Chia-I Wuf9be13c2015-10-26 20:37:06 +08001139 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1140 submit_info.pNext = NULL;
Chia-I Wud50a7d72015-10-26 20:48:51 +08001141 submit_info.waitSemaphoreCount = 0;
Courtney Goeltzenleuchter806c7002015-10-27 11:22:14 -06001142 submit_info.pWaitSemaphores = NULL;
Chia-I Wud50a7d72015-10-26 20:48:51 +08001143 submit_info.commandBufferCount = 1;
Courtney Goeltzenleuchter806c7002015-10-27 11:22:14 -06001144 submit_info.pCommandBuffers = cmd_bufs;
Chia-I Wud50a7d72015-10-26 20:48:51 +08001145 submit_info.signalSemaphoreCount = 0;
Courtney Goeltzenleuchter806c7002015-10-27 11:22:14 -06001146 submit_info.pSignalSemaphores = NULL;
1147
Courtney Goeltzenleuchter646b9072015-10-20 18:04:07 -06001148 err = vkQueueSubmit(m_queue.handle(), 1, &submit_info, nullFence);
Tony Barbourbd094ce2015-10-23 11:00:15 -06001149 assert(!err);
1150
1151 err = vkQueueWaitIdle(m_queue.handle());
1152 assert(!err);
1153
1154}
Tony Barbour96db8822015-02-25 12:28:39 -07001155
Jon Ashburn07daee72015-05-21 18:13:33 -06001156void TestFrameworkVkPresent::InitPresentFramework(std::list<VkTestImageRecord> &imagesIn, VkInstance inst)
Tony Barbour96db8822015-02-25 12:28:39 -07001157{
Ian Elliottc11750d2015-10-30 13:24:12 -06001158 m_instance = inst;
Ian Elliott7e40db92015-08-21 15:09:33 -06001159 GET_INSTANCE_PROC_ADDR(inst, GetPhysicalDeviceSurfaceSupportKHR);
Ian Elliottc11750d2015-10-30 13:24:12 -06001160 GET_INSTANCE_PROC_ADDR(inst, GetPhysicalDeviceSurfaceCapabilitiesKHR);
1161 GET_INSTANCE_PROC_ADDR(inst, GetPhysicalDeviceSurfaceFormatsKHR);
1162 GET_INSTANCE_PROC_ADDR(inst, GetPhysicalDeviceSurfacePresentModesKHR);
Tony Barbour2d6d54e2015-12-03 16:05:11 -07001163 GET_INSTANCE_PROC_ADDR(inst, DestroySurfaceKHR);
Ian Elliott7e40db92015-08-21 15:09:33 -06001164 GET_DEVICE_PROC_ADDR(m_device.handle(), CreateSwapchainKHR);
1165 GET_DEVICE_PROC_ADDR(m_device.handle(), CreateSwapchainKHR);
1166 GET_DEVICE_PROC_ADDR(m_device.handle(), DestroySwapchainKHR);
1167 GET_DEVICE_PROC_ADDR(m_device.handle(), GetSwapchainImagesKHR);
1168 GET_DEVICE_PROC_ADDR(m_device.handle(), AcquireNextImageKHR);
1169 GET_DEVICE_PROC_ADDR(m_device.handle(), QueuePresentKHR);
Jon Ashburn07daee72015-05-21 18:13:33 -06001170
Tony Barbour96db8822015-02-25 12:28:39 -07001171 m_images = imagesIn;
1172}
1173
Tony Barbour3d69c9e2015-05-20 16:53:31 -06001174#ifdef _WIN32
1175void TestFrameworkVkPresent::CreateMyWindow()
1176{
1177 WNDCLASSEX win_class;
1178 // const ::testing::TestInfo* const test_info =
1179 // ::testing::UnitTest::GetInstance()->current_test_info();
1180 m_connection = GetModuleHandle(NULL);
1181
1182 for (std::list<VkTestImageRecord>::const_iterator it = m_images.begin();
1183 it != m_images.end(); it++) {
1184 if (m_width < it->m_width)
1185 m_width = it->m_width;
1186 if (m_height < it->m_height)
1187 m_height = it->m_height;
1188 }
1189 // Initialize the window class structure:
1190 win_class.cbSize = sizeof(WNDCLASSEX);
1191 win_class.style = CS_HREDRAW | CS_VREDRAW;
1192 win_class.lpfnWndProc = (WNDPROC) &TestFrameworkVkPresent::WndProc;
1193 win_class.cbClsExtra = 0;
1194 win_class.cbWndExtra = 0;
1195 win_class.hInstance = m_connection; // hInstance
1196 win_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
1197 win_class.hCursor = LoadCursor(NULL, IDC_ARROW);
1198 win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
1199 win_class.lpszMenuName = NULL;
1200 win_class.lpszClassName = "Test";
1201 win_class.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
1202 // Register window class:
1203 if (!RegisterClassEx(&win_class)) {
1204 // It didn't work, so try to give a useful error:
1205 printf("Unexpected error trying to start the application!\n");
1206 fflush(stdout);
1207 exit(1);
1208 }
1209 // Create window with the registered class:
Cody Northrop39582252015-08-05 15:39:31 -06001210 RECT wr = { 0, 0, m_width, m_height };
1211 AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
Tony Barbour3d69c9e2015-05-20 16:53:31 -06001212 m_window = CreateWindowEx(0,
1213 "Test", // class name
1214 "Test", // app name
1215 WS_OVERLAPPEDWINDOW | // window style
1216 WS_VISIBLE |
1217 WS_SYSMENU,
1218 100,100, // x/y coords
Cody Northrop39582252015-08-05 15:39:31 -06001219 wr.right - wr.left, // width
1220 wr.bottom - wr.top, // height
Tony Barbour3d69c9e2015-05-20 16:53:31 -06001221 NULL, // handle to parent
1222 NULL, // handle to menu
1223 m_connection, // hInstance
1224 NULL); // no extra parameters
1225
1226 if (!m_window) {
1227 // It didn't work, so try to give a useful error:
1228 DWORD error = GetLastError();
1229 char message[120];
1230 sprintf(message, "Cannot create a window in which to draw!\n GetLastError = %d", error);
1231 MessageBox(NULL, message, "Error", MB_OK);
1232 exit(1);
1233 }
Tony-LunarG399dfca2015-05-19 14:08:26 -06001234 // Put our this pointer into the window's user data so our WndProc can use it when it starts.
1235 SetWindowLongPtr(m_window, GWLP_USERDATA, (LONG_PTR) this);
Tony Barbour3d69c9e2015-05-20 16:53:31 -06001236}
1237#else
Tony Barbour6918cd52015-04-09 12:58:51 -06001238void TestFrameworkVkPresent::CreateMyWindow()
Tony Barbour96db8822015-02-25 12:28:39 -07001239{
Chia-I Wuf8693382015-04-16 22:02:10 +08001240 const xcb_setup_t *setup;
1241 xcb_screen_iterator_t iter;
1242 int scr;
Tony Barbour96db8822015-02-25 12:28:39 -07001243 uint32_t value_mask, value_list[32];
1244
Chia-I Wuf8693382015-04-16 22:02:10 +08001245 m_connection = xcb_connect(NULL, &scr);
1246
1247 setup = xcb_get_setup(m_connection);
1248 iter = xcb_setup_roots_iterator(setup);
1249 while (scr-- > 0)
1250 xcb_screen_next(&iter);
1251
1252 m_screen = iter.data;
1253
1254 for (std::list<VkTestImageRecord>::const_iterator it = m_images.begin();
1255 it != m_images.end(); it++) {
1256 if (m_width < it->m_width)
1257 m_width = it->m_width;
1258 if (m_height < it->m_height)
1259 m_height = it->m_height;
1260 }
1261
1262 m_window = xcb_generate_id(m_connection);
Tony Barbour96db8822015-02-25 12:28:39 -07001263
1264 value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
Chia-I Wuf8693382015-04-16 22:02:10 +08001265 value_list[0] = m_screen->black_pixel;
Tony Barbour96db8822015-02-25 12:28:39 -07001266 value_list[1] = XCB_EVENT_MASK_KEY_RELEASE |
1267 XCB_EVENT_MASK_EXPOSURE |
1268 XCB_EVENT_MASK_STRUCTURE_NOTIFY;
1269
Chia-I Wuf8693382015-04-16 22:02:10 +08001270 xcb_create_window(m_connection,
Tony Barbour96db8822015-02-25 12:28:39 -07001271 XCB_COPY_FROM_PARENT,
Chia-I Wuf8693382015-04-16 22:02:10 +08001272 m_window, m_screen->root,
Tony Barbour96db8822015-02-25 12:28:39 -07001273 0, 0, m_width, m_height, 0,
1274 XCB_WINDOW_CLASS_INPUT_OUTPUT,
Chia-I Wuf8693382015-04-16 22:02:10 +08001275 m_screen->root_visual,
Tony Barbour96db8822015-02-25 12:28:39 -07001276 value_mask, value_list);
1277
1278 /* Magic code that will send notification when window is destroyed */
Chia-I Wuf8693382015-04-16 22:02:10 +08001279 xcb_intern_atom_cookie_t cookie = xcb_intern_atom(m_connection, 1, 12,
Tony Barbour96db8822015-02-25 12:28:39 -07001280 "WM_PROTOCOLS");
Chia-I Wuf8693382015-04-16 22:02:10 +08001281 xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(m_connection, cookie, 0);
Tony Barbour96db8822015-02-25 12:28:39 -07001282
Chia-I Wuf8693382015-04-16 22:02:10 +08001283 xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(m_connection, 0, 16, "WM_DELETE_WINDOW");
1284 m_atom_wm_delete_window = xcb_intern_atom_reply(m_connection, cookie2, 0);
Tony Barbour96db8822015-02-25 12:28:39 -07001285
Chia-I Wuf8693382015-04-16 22:02:10 +08001286 xcb_change_property(m_connection, XCB_PROP_MODE_REPLACE,
Tony Barbour96db8822015-02-25 12:28:39 -07001287 m_window, (*reply).atom, 4, 32, 1,
1288 &(*m_atom_wm_delete_window).atom);
1289 free(reply);
1290
Chia-I Wuf8693382015-04-16 22:02:10 +08001291 xcb_map_window(m_connection, m_window);
Tony Barbour96db8822015-02-25 12:28:39 -07001292}
Tony Barbour3d69c9e2015-05-20 16:53:31 -06001293#endif
Tony Barbour96db8822015-02-25 12:28:39 -07001294
Tony Barbour6918cd52015-04-09 12:58:51 -06001295void TestFrameworkVkPresent::TearDown()
Tony Barbour96db8822015-02-25 12:28:39 -07001296{
Ian Elliottc11750d2015-10-30 13:24:12 -06001297 m_fpDestroySwapchainKHR(m_device.handle(), m_swap_chain, NULL);
Tony Barbour9226a822015-10-23 10:58:56 -06001298
1299 for (uint32_t i = 0; i < m_swapchainImageCount; i++) {
Chia-I Wuf7458c52015-10-26 21:10:41 +08001300 vkDestroyImageView(m_device.handle(), m_buffers[i].view, NULL);
Tony Barbour9226a822015-10-23 10:58:56 -06001301 }
Tony Barbour3d69c9e2015-05-20 16:53:31 -06001302#ifndef _WIN32
Chia-I Wuf8693382015-04-16 22:02:10 +08001303 xcb_destroy_window(m_connection, m_window);
1304 xcb_disconnect(m_connection);
Tony Barbour3d69c9e2015-05-20 16:53:31 -06001305#endif
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001306}
1307
Tony Barboure1837292015-12-07 13:46:11 -07001308void TestFrameworkVkPresent::DestroyMyWindow()
Tony Barbour2d6d54e2015-12-03 16:05:11 -07001309{
1310#ifndef _WIN32
1311 xcb_destroy_window(m_connection, m_window);
1312 xcb_disconnect(m_connection);
1313#else
1314 DestroyWindow(m_window);
1315#endif
1316}
1317
Tony Barbour6918cd52015-04-09 12:58:51 -06001318void VkTestFramework::Finish()
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001319{
1320 if (m_images.size() == 0) return;
1321
Chia-I Wuf8693382015-04-16 22:02:10 +08001322 vk_testing::Environment env;
1323 env.SetUp();
Tony Barbour96db8822015-02-25 12:28:39 -07001324 {
Chia-I Wuf8693382015-04-16 22:02:10 +08001325 TestFrameworkVkPresent vkPresent(env.default_device());
Tony Barbour96db8822015-02-25 12:28:39 -07001326
Jon Ashburn07daee72015-05-21 18:13:33 -06001327 vkPresent.InitPresentFramework(m_images, env.get_instance());
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001328 vkPresent.CreateMyWindow();
Ian Elliott7e40db92015-08-21 15:09:33 -06001329 vkPresent.CreateSwapchain();
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001330 vkPresent.Run();
1331 vkPresent.TearDown();
Tony Barbour96db8822015-02-25 12:28:39 -07001332 }
Chia-I Wuf8693382015-04-16 22:02:10 +08001333 env.TearDown();
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001334}
1335
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001336//
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001337// These are the default resources for TBuiltInResources, used for both
1338// - parsing this string for the case where the user didn't supply one
1339// - dumping out a template for user construction of a config file
1340//
1341static const char* DefaultConfig =
1342 "MaxLights 32\n"
1343 "MaxClipPlanes 6\n"
1344 "MaxTextureUnits 32\n"
1345 "MaxTextureCoords 32\n"
1346 "MaxVertexAttribs 64\n"
1347 "MaxVertexUniformComponents 4096\n"
1348 "MaxVaryingFloats 64\n"
1349 "MaxVertexTextureImageUnits 32\n"
1350 "MaxCombinedTextureImageUnits 80\n"
1351 "MaxTextureImageUnits 32\n"
1352 "MaxFragmentUniformComponents 4096\n"
1353 "MaxDrawBuffers 32\n"
1354 "MaxVertexUniformVectors 128\n"
1355 "MaxVaryingVectors 8\n"
1356 "MaxFragmentUniformVectors 16\n"
1357 "MaxVertexOutputVectors 16\n"
1358 "MaxFragmentInputVectors 15\n"
1359 "MinProgramTexelOffset -8\n"
1360 "MaxProgramTexelOffset 7\n"
1361 "MaxClipDistances 8\n"
1362 "MaxComputeWorkGroupCountX 65535\n"
1363 "MaxComputeWorkGroupCountY 65535\n"
1364 "MaxComputeWorkGroupCountZ 65535\n"
1365 "MaxComputeWorkGroupSizeX 1024\n"
1366 "MaxComputeWorkGroupSizeY 1024\n"
1367 "MaxComputeWorkGroupSizeZ 64\n"
1368 "MaxComputeUniformComponents 1024\n"
1369 "MaxComputeTextureImageUnits 16\n"
1370 "MaxComputeImageUniforms 8\n"
1371 "MaxComputeAtomicCounters 8\n"
1372 "MaxComputeAtomicCounterBuffers 1\n"
1373 "MaxVaryingComponents 60\n"
1374 "MaxVertexOutputComponents 64\n"
1375 "MaxGeometryInputComponents 64\n"
1376 "MaxGeometryOutputComponents 128\n"
1377 "MaxFragmentInputComponents 128\n"
1378 "MaxImageUnits 8\n"
1379 "MaxCombinedImageUnitsAndFragmentOutputs 8\n"
1380 "MaxCombinedShaderOutputResources 8\n"
1381 "MaxImageSamples 0\n"
1382 "MaxVertexImageUniforms 0\n"
1383 "MaxTessControlImageUniforms 0\n"
1384 "MaxTessEvaluationImageUniforms 0\n"
1385 "MaxGeometryImageUniforms 0\n"
1386 "MaxFragmentImageUniforms 8\n"
1387 "MaxCombinedImageUniforms 8\n"
1388 "MaxGeometryTextureImageUnits 16\n"
1389 "MaxGeometryOutputVertices 256\n"
1390 "MaxGeometryTotalOutputComponents 1024\n"
1391 "MaxGeometryUniformComponents 1024\n"
1392 "MaxGeometryVaryingComponents 64\n"
1393 "MaxTessControlInputComponents 128\n"
1394 "MaxTessControlOutputComponents 128\n"
1395 "MaxTessControlTextureImageUnits 16\n"
1396 "MaxTessControlUniformComponents 1024\n"
1397 "MaxTessControlTotalOutputComponents 4096\n"
1398 "MaxTessEvaluationInputComponents 128\n"
1399 "MaxTessEvaluationOutputComponents 128\n"
1400 "MaxTessEvaluationTextureImageUnits 16\n"
1401 "MaxTessEvaluationUniformComponents 1024\n"
1402 "MaxTessPatchComponents 120\n"
1403 "MaxPatchVertices 32\n"
1404 "MaxTessGenLevel 64\n"
1405 "MaxViewports 16\n"
1406 "MaxVertexAtomicCounters 0\n"
1407 "MaxTessControlAtomicCounters 0\n"
1408 "MaxTessEvaluationAtomicCounters 0\n"
1409 "MaxGeometryAtomicCounters 0\n"
1410 "MaxFragmentAtomicCounters 8\n"
1411 "MaxCombinedAtomicCounters 8\n"
1412 "MaxAtomicCounterBindings 1\n"
1413 "MaxVertexAtomicCounterBuffers 0\n"
1414 "MaxTessControlAtomicCounterBuffers 0\n"
1415 "MaxTessEvaluationAtomicCounterBuffers 0\n"
1416 "MaxGeometryAtomicCounterBuffers 0\n"
1417 "MaxFragmentAtomicCounterBuffers 1\n"
1418 "MaxCombinedAtomicCounterBuffers 1\n"
1419 "MaxAtomicCounterBufferSize 16384\n"
1420 "MaxTransformFeedbackBuffers 4\n"
1421 "MaxTransformFeedbackInterleavedComponents 64\n"
1422 "MaxCullDistances 8\n"
1423 "MaxCombinedClipAndCullDistances 8\n"
1424 "MaxSamples 4\n"
1425
1426 "nonInductiveForLoops 1\n"
1427 "whileLoops 1\n"
1428 "doWhileLoops 1\n"
1429 "generalUniformIndexing 1\n"
1430 "generalAttributeMatrixVectorIndexing 1\n"
1431 "generalVaryingIndexing 1\n"
1432 "generalSamplerIndexing 1\n"
1433 "generalVariableIndexing 1\n"
1434 "generalConstantMatrixVectorIndexing 1\n"
1435 ;
1436
1437//
1438// *.conf => this is a config file that can set limits/resources
1439//
Tony Barbour6918cd52015-04-09 12:58:51 -06001440bool VkTestFramework::SetConfigFile(const std::string& name)
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001441{
1442 if (name.size() < 5)
1443 return false;
1444
1445 if (name.compare(name.size() - 5, 5, ".conf") == 0) {
1446 ConfigFile = name;
1447 return true;
1448 }
1449
1450 return false;
1451}
1452
1453//
1454// Parse either a .conf file provided by the user or the default string above.
1455//
Tony Barbour6918cd52015-04-09 12:58:51 -06001456void VkTestFramework::ProcessConfigFile()
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001457{
1458 char** configStrings = 0;
1459 char* config = 0;
1460 if (ConfigFile.size() > 0) {
1461 configStrings = ReadFileData(ConfigFile.c_str());
1462 if (configStrings)
1463 config = *configStrings;
1464 else {
1465 printf("Error opening configuration file; will instead use the default configuration\n");
1466 }
1467 }
1468
1469 if (config == 0) {
Courtney Goeltzenleuchterc7def922015-09-24 17:05:05 -06001470 config = (char *) alloca(strlen(DefaultConfig) + 1);
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001471 strcpy(config, DefaultConfig);
1472 }
1473
1474 const char* delims = " \t\n\r";
1475 const char* token = strtok(config, delims);
1476 while (token) {
1477 const char* valueStr = strtok(0, delims);
1478 if (valueStr == 0 || ! (valueStr[0] == '-' || (valueStr[0] >= '0' && valueStr[0] <= '9'))) {
1479 printf("Error: '%s' bad .conf file. Each name must be followed by one number.\n", valueStr ? valueStr : "");
1480 return;
1481 }
1482 int value = atoi(valueStr);
1483
1484 if (strcmp(token, "MaxLights") == 0)
1485 Resources.maxLights = value;
1486 else if (strcmp(token, "MaxClipPlanes") == 0)
1487 Resources.maxClipPlanes = value;
1488 else if (strcmp(token, "MaxTextureUnits") == 0)
1489 Resources.maxTextureUnits = value;
1490 else if (strcmp(token, "MaxTextureCoords") == 0)
1491 Resources.maxTextureCoords = value;
1492 else if (strcmp(token, "MaxVertexAttribs") == 0)
1493 Resources.maxVertexAttribs = value;
1494 else if (strcmp(token, "MaxVertexUniformComponents") == 0)
1495 Resources.maxVertexUniformComponents = value;
1496 else if (strcmp(token, "MaxVaryingFloats") == 0)
1497 Resources.maxVaryingFloats = value;
1498 else if (strcmp(token, "MaxVertexTextureImageUnits") == 0)
1499 Resources.maxVertexTextureImageUnits = value;
1500 else if (strcmp(token, "MaxCombinedTextureImageUnits") == 0)
1501 Resources.maxCombinedTextureImageUnits = value;
1502 else if (strcmp(token, "MaxTextureImageUnits") == 0)
1503 Resources.maxTextureImageUnits = value;
1504 else if (strcmp(token, "MaxFragmentUniformComponents") == 0)
1505 Resources.maxFragmentUniformComponents = value;
1506 else if (strcmp(token, "MaxDrawBuffers") == 0)
1507 Resources.maxDrawBuffers = value;
1508 else if (strcmp(token, "MaxVertexUniformVectors") == 0)
1509 Resources.maxVertexUniformVectors = value;
1510 else if (strcmp(token, "MaxVaryingVectors") == 0)
1511 Resources.maxVaryingVectors = value;
1512 else if (strcmp(token, "MaxFragmentUniformVectors") == 0)
1513 Resources.maxFragmentUniformVectors = value;
1514 else if (strcmp(token, "MaxVertexOutputVectors") == 0)
1515 Resources.maxVertexOutputVectors = value;
1516 else if (strcmp(token, "MaxFragmentInputVectors") == 0)
1517 Resources.maxFragmentInputVectors = value;
1518 else if (strcmp(token, "MinProgramTexelOffset") == 0)
1519 Resources.minProgramTexelOffset = value;
1520 else if (strcmp(token, "MaxProgramTexelOffset") == 0)
1521 Resources.maxProgramTexelOffset = value;
1522 else if (strcmp(token, "MaxClipDistances") == 0)
1523 Resources.maxClipDistances = value;
1524 else if (strcmp(token, "MaxComputeWorkGroupCountX") == 0)
1525 Resources.maxComputeWorkGroupCountX = value;
1526 else if (strcmp(token, "MaxComputeWorkGroupCountY") == 0)
1527 Resources.maxComputeWorkGroupCountY = value;
1528 else if (strcmp(token, "MaxComputeWorkGroupCountZ") == 0)
1529 Resources.maxComputeWorkGroupCountZ = value;
1530 else if (strcmp(token, "MaxComputeWorkGroupSizeX") == 0)
1531 Resources.maxComputeWorkGroupSizeX = value;
1532 else if (strcmp(token, "MaxComputeWorkGroupSizeY") == 0)
1533 Resources.maxComputeWorkGroupSizeY = value;
1534 else if (strcmp(token, "MaxComputeWorkGroupSizeZ") == 0)
1535 Resources.maxComputeWorkGroupSizeZ = value;
1536 else if (strcmp(token, "MaxComputeUniformComponents") == 0)
1537 Resources.maxComputeUniformComponents = value;
1538 else if (strcmp(token, "MaxComputeTextureImageUnits") == 0)
1539 Resources.maxComputeTextureImageUnits = value;
1540 else if (strcmp(token, "MaxComputeImageUniforms") == 0)
1541 Resources.maxComputeImageUniforms = value;
1542 else if (strcmp(token, "MaxComputeAtomicCounters") == 0)
1543 Resources.maxComputeAtomicCounters = value;
1544 else if (strcmp(token, "MaxComputeAtomicCounterBuffers") == 0)
1545 Resources.maxComputeAtomicCounterBuffers = value;
1546 else if (strcmp(token, "MaxVaryingComponents") == 0)
1547 Resources.maxVaryingComponents = value;
1548 else if (strcmp(token, "MaxVertexOutputComponents") == 0)
1549 Resources.maxVertexOutputComponents = value;
1550 else if (strcmp(token, "MaxGeometryInputComponents") == 0)
1551 Resources.maxGeometryInputComponents = value;
1552 else if (strcmp(token, "MaxGeometryOutputComponents") == 0)
1553 Resources.maxGeometryOutputComponents = value;
1554 else if (strcmp(token, "MaxFragmentInputComponents") == 0)
1555 Resources.maxFragmentInputComponents = value;
1556 else if (strcmp(token, "MaxImageUnits") == 0)
1557 Resources.maxImageUnits = value;
1558 else if (strcmp(token, "MaxCombinedImageUnitsAndFragmentOutputs") == 0)
1559 Resources.maxCombinedImageUnitsAndFragmentOutputs = value;
1560 else if (strcmp(token, "MaxCombinedShaderOutputResources") == 0)
1561 Resources.maxCombinedShaderOutputResources = value;
1562 else if (strcmp(token, "MaxImageSamples") == 0)
1563 Resources.maxImageSamples = value;
1564 else if (strcmp(token, "MaxVertexImageUniforms") == 0)
1565 Resources.maxVertexImageUniforms = value;
1566 else if (strcmp(token, "MaxTessControlImageUniforms") == 0)
1567 Resources.maxTessControlImageUniforms = value;
1568 else if (strcmp(token, "MaxTessEvaluationImageUniforms") == 0)
1569 Resources.maxTessEvaluationImageUniforms = value;
1570 else if (strcmp(token, "MaxGeometryImageUniforms") == 0)
1571 Resources.maxGeometryImageUniforms = value;
1572 else if (strcmp(token, "MaxFragmentImageUniforms") == 0)
1573 Resources.maxFragmentImageUniforms = value;
1574 else if (strcmp(token, "MaxCombinedImageUniforms") == 0)
1575 Resources.maxCombinedImageUniforms = value;
1576 else if (strcmp(token, "MaxGeometryTextureImageUnits") == 0)
1577 Resources.maxGeometryTextureImageUnits = value;
1578 else if (strcmp(token, "MaxGeometryOutputVertices") == 0)
1579 Resources.maxGeometryOutputVertices = value;
1580 else if (strcmp(token, "MaxGeometryTotalOutputComponents") == 0)
1581 Resources.maxGeometryTotalOutputComponents = value;
1582 else if (strcmp(token, "MaxGeometryUniformComponents") == 0)
1583 Resources.maxGeometryUniformComponents = value;
1584 else if (strcmp(token, "MaxGeometryVaryingComponents") == 0)
1585 Resources.maxGeometryVaryingComponents = value;
1586 else if (strcmp(token, "MaxTessControlInputComponents") == 0)
1587 Resources.maxTessControlInputComponents = value;
1588 else if (strcmp(token, "MaxTessControlOutputComponents") == 0)
1589 Resources.maxTessControlOutputComponents = value;
1590 else if (strcmp(token, "MaxTessControlTextureImageUnits") == 0)
1591 Resources.maxTessControlTextureImageUnits = value;
1592 else if (strcmp(token, "MaxTessControlUniformComponents") == 0)
1593 Resources.maxTessControlUniformComponents = value;
1594 else if (strcmp(token, "MaxTessControlTotalOutputComponents") == 0)
1595 Resources.maxTessControlTotalOutputComponents = value;
1596 else if (strcmp(token, "MaxTessEvaluationInputComponents") == 0)
1597 Resources.maxTessEvaluationInputComponents = value;
1598 else if (strcmp(token, "MaxTessEvaluationOutputComponents") == 0)
1599 Resources.maxTessEvaluationOutputComponents = value;
1600 else if (strcmp(token, "MaxTessEvaluationTextureImageUnits") == 0)
1601 Resources.maxTessEvaluationTextureImageUnits = value;
1602 else if (strcmp(token, "MaxTessEvaluationUniformComponents") == 0)
1603 Resources.maxTessEvaluationUniformComponents = value;
1604 else if (strcmp(token, "MaxTessPatchComponents") == 0)
1605 Resources.maxTessPatchComponents = value;
1606 else if (strcmp(token, "MaxPatchVertices") == 0)
1607 Resources.maxPatchVertices = value;
1608 else if (strcmp(token, "MaxTessGenLevel") == 0)
1609 Resources.maxTessGenLevel = value;
1610 else if (strcmp(token, "MaxViewports") == 0)
1611 Resources.maxViewports = value;
1612 else if (strcmp(token, "MaxVertexAtomicCounters") == 0)
1613 Resources.maxVertexAtomicCounters = value;
1614 else if (strcmp(token, "MaxTessControlAtomicCounters") == 0)
1615 Resources.maxTessControlAtomicCounters = value;
1616 else if (strcmp(token, "MaxTessEvaluationAtomicCounters") == 0)
1617 Resources.maxTessEvaluationAtomicCounters = value;
1618 else if (strcmp(token, "MaxGeometryAtomicCounters") == 0)
1619 Resources.maxGeometryAtomicCounters = value;
1620 else if (strcmp(token, "MaxFragmentAtomicCounters") == 0)
1621 Resources.maxFragmentAtomicCounters = value;
1622 else if (strcmp(token, "MaxCombinedAtomicCounters") == 0)
1623 Resources.maxCombinedAtomicCounters = value;
1624 else if (strcmp(token, "MaxAtomicCounterBindings") == 0)
1625 Resources.maxAtomicCounterBindings = value;
1626 else if (strcmp(token, "MaxVertexAtomicCounterBuffers") == 0)
1627 Resources.maxVertexAtomicCounterBuffers = value;
1628 else if (strcmp(token, "MaxTessControlAtomicCounterBuffers") == 0)
1629 Resources.maxTessControlAtomicCounterBuffers = value;
1630 else if (strcmp(token, "MaxTessEvaluationAtomicCounterBuffers") == 0)
1631 Resources.maxTessEvaluationAtomicCounterBuffers = value;
1632 else if (strcmp(token, "MaxGeometryAtomicCounterBuffers") == 0)
1633 Resources.maxGeometryAtomicCounterBuffers = value;
1634 else if (strcmp(token, "MaxFragmentAtomicCounterBuffers") == 0)
1635 Resources.maxFragmentAtomicCounterBuffers = value;
1636 else if (strcmp(token, "MaxCombinedAtomicCounterBuffers") == 0)
1637 Resources.maxCombinedAtomicCounterBuffers = value;
1638 else if (strcmp(token, "MaxAtomicCounterBufferSize") == 0)
1639 Resources.maxAtomicCounterBufferSize = value;
1640 else if (strcmp(token, "MaxTransformFeedbackBuffers") == 0)
1641 Resources.maxTransformFeedbackBuffers = value;
1642 else if (strcmp(token, "MaxTransformFeedbackInterleavedComponents") == 0)
1643 Resources.maxTransformFeedbackInterleavedComponents = value;
1644 else if (strcmp(token, "MaxCullDistances") == 0)
1645 Resources.maxCullDistances = value;
1646 else if (strcmp(token, "MaxCombinedClipAndCullDistances") == 0)
1647 Resources.maxCombinedClipAndCullDistances = value;
1648 else if (strcmp(token, "MaxSamples") == 0)
1649 Resources.maxSamples = value;
1650
1651 else if (strcmp(token, "nonInductiveForLoops") == 0)
1652 Resources.limits.nonInductiveForLoops = (value != 0);
1653 else if (strcmp(token, "whileLoops") == 0)
1654 Resources.limits.whileLoops = (value != 0);
1655 else if (strcmp(token, "doWhileLoops") == 0)
1656 Resources.limits.doWhileLoops = (value != 0);
1657 else if (strcmp(token, "generalUniformIndexing") == 0)
1658 Resources.limits.generalUniformIndexing = (value != 0);
1659 else if (strcmp(token, "generalAttributeMatrixVectorIndexing") == 0)
1660 Resources.limits.generalAttributeMatrixVectorIndexing = (value != 0);
1661 else if (strcmp(token, "generalVaryingIndexing") == 0)
1662 Resources.limits.generalVaryingIndexing = (value != 0);
1663 else if (strcmp(token, "generalSamplerIndexing") == 0)
1664 Resources.limits.generalSamplerIndexing = (value != 0);
1665 else if (strcmp(token, "generalVariableIndexing") == 0)
1666 Resources.limits.generalVariableIndexing = (value != 0);
1667 else if (strcmp(token, "generalConstantMatrixVectorIndexing") == 0)
1668 Resources.limits.generalConstantMatrixVectorIndexing = (value != 0);
1669 else
1670 printf("Warning: unrecognized limit (%s) in configuration file.\n", token);
1671
1672 token = strtok(0, delims);
1673 }
1674 if (configStrings)
1675 FreeFileData(configStrings);
1676}
1677
Tony Barbour6918cd52015-04-09 12:58:51 -06001678void VkTestFramework::SetMessageOptions(EShMessages& messages)
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001679{
1680 if (m_compile_options & EOptionRelaxedErrors)
1681 messages = (EShMessages)(messages | EShMsgRelaxedErrors);
1682 if (m_compile_options & EOptionIntermediate)
1683 messages = (EShMessages)(messages | EShMsgAST);
1684 if (m_compile_options & EOptionSuppressWarnings)
1685 messages = (EShMessages)(messages | EShMsgSuppressWarnings);
1686}
1687
1688//
1689// Malloc a string of sufficient size and read a string into it.
1690//
Tony Barbour6918cd52015-04-09 12:58:51 -06001691char** VkTestFramework::ReadFileData(const char* fileName)
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001692{
1693 FILE *in;
1694 #if defined(_WIN32) && defined(__GNUC__)
1695 in = fopen(fileName, "r");
1696 int errorCode = in ? 0 : 1;
1697 #else
1698 int errorCode = fopen_s(&in, fileName, "r");
1699 #endif
1700
1701 char *fdata;
1702 int count = 0;
1703 const int maxSourceStrings = 5;
1704 char** return_data = (char**)malloc(sizeof(char *) * (maxSourceStrings+1));
1705
1706 if (errorCode) {
1707 printf("Error: unable to open input file: %s\n", fileName);
1708 return 0;
1709 }
1710
1711 while (fgetc(in) != EOF)
1712 count++;
1713
1714 fseek(in, 0, SEEK_SET);
1715
1716 if (!(fdata = (char*)malloc(count+2))) {
1717 printf("Error allocating memory\n");
1718 return 0;
1719 }
1720 if (fread(fdata,1,count, in)!=count) {
1721 printf("Error reading input file: %s\n", fileName);
1722 return 0;
1723 }
1724 fdata[count] = '\0';
1725 fclose(in);
1726 if (count == 0) {
1727 return_data[0]=(char*)malloc(count+2);
1728 return_data[0][0]='\0';
1729 m_num_shader_strings = 0;
1730 return return_data;
1731 } else
1732 m_num_shader_strings = 1;
1733
1734 int len = (int)(ceil)((float)count/(float)m_num_shader_strings);
1735 int ptr_len=0,i=0;
1736 while(count>0){
1737 return_data[i]=(char*)malloc(len+2);
1738 memcpy(return_data[i],fdata+ptr_len,len);
1739 return_data[i][len]='\0';
1740 count-=(len);
1741 ptr_len+=(len);
1742 if(count<len){
1743 if(count==0){
1744 m_num_shader_strings=(i+1);
1745 break;
1746 }
1747 len = count;
1748 }
1749 ++i;
1750 }
1751 return return_data;
1752}
1753
Tony Barbour6918cd52015-04-09 12:58:51 -06001754void VkTestFramework::FreeFileData(char** data)
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001755{
1756 for(int i=0;i<m_num_shader_strings;i++)
1757 free(data[i]);
1758}
1759
1760//
1761// Deduce the language from the filename. Files must end in one of the
1762// following extensions:
1763//
1764// .vert = vertex
1765// .tesc = tessellation control
1766// .tese = tessellation evaluation
1767// .geom = geometry
1768// .frag = fragment
1769// .comp = compute
1770//
Tony Barbour6918cd52015-04-09 12:58:51 -06001771EShLanguage VkTestFramework::FindLanguage(const std::string& name)
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001772{
1773 size_t ext = name.rfind('.');
1774 if (ext == std::string::npos) {
1775 return EShLangVertex;
1776 }
1777
1778 std::string suffix = name.substr(ext + 1, std::string::npos);
1779 if (suffix == "vert")
1780 return EShLangVertex;
1781 else if (suffix == "tesc")
1782 return EShLangTessControl;
1783 else if (suffix == "tese")
1784 return EShLangTessEvaluation;
1785 else if (suffix == "geom")
1786 return EShLangGeometry;
1787 else if (suffix == "frag")
1788 return EShLangFragment;
1789 else if (suffix == "comp")
1790 return EShLangCompute;
1791
1792 return EShLangVertex;
1793}
1794
1795//
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001796// Convert VK shader type to compiler's
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001797//
Courtney Goeltzenleuchterd2635502015-10-21 17:08:06 -06001798EShLanguage VkTestFramework::FindLanguage(const VkShaderStageFlagBits shader_type)
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001799{
1800 switch (shader_type) {
Courtney Goeltzenleuchterd2635502015-10-21 17:08:06 -06001801 case VK_SHADER_STAGE_VERTEX_BIT:
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001802 return EShLangVertex;
1803
Courtney Goeltzenleuchterd2635502015-10-21 17:08:06 -06001804 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001805 return EShLangTessControl;
1806
Courtney Goeltzenleuchterd2635502015-10-21 17:08:06 -06001807 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001808 return EShLangTessEvaluation;
1809
Courtney Goeltzenleuchterd2635502015-10-21 17:08:06 -06001810 case VK_SHADER_STAGE_GEOMETRY_BIT:
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001811 return EShLangGeometry;
1812
Courtney Goeltzenleuchterd2635502015-10-21 17:08:06 -06001813 case VK_SHADER_STAGE_FRAGMENT_BIT:
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001814 return EShLangFragment;
1815
Courtney Goeltzenleuchterd2635502015-10-21 17:08:06 -06001816 case VK_SHADER_STAGE_COMPUTE_BIT:
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001817 return EShLangCompute;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001818
Chia-I Wub4c2aa42014-12-15 23:50:11 +08001819 default:
1820 return EShLangVertex;
1821 }
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001822}
1823
1824
1825//
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -06001826// Compile a given string containing GLSL into SPV for use by VK
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001827// Return value of false means an error was encountered.
1828//
Courtney Goeltzenleuchterd2635502015-10-21 17:08:06 -06001829bool VkTestFramework::GLSLtoSPV(const VkShaderStageFlagBits shader_type,
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001830 const char *pshader,
Cody Northrop5a95b472015-06-03 13:01:54 -06001831 std::vector<unsigned int> &spirv)
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001832{
Courtney Goeltzenleuchterc7def922015-09-24 17:05:05 -06001833 glslang::TProgram program;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001834 const char *shaderStrings[1];
1835
1836 // TODO: Do we want to load a special config file depending on the
1837 // shader source? Optional name maybe?
1838 // SetConfigFile(fileName);
1839
1840 ProcessConfigFile();
1841
1842 EShMessages messages = EShMsgDefault;
1843 SetMessageOptions(messages);
1844
1845 EShLanguage stage = FindLanguage(shader_type);
1846 glslang::TShader* shader = new glslang::TShader(stage);
1847
1848 shaderStrings[0] = pshader;
1849 shader->setStrings(shaderStrings, 1);
1850
1851 if (! shader->parse(&Resources, (m_compile_options & EOptionDefaultDesktop) ? 110 : 100, false, messages)) {
1852
Cody Northrop195d6622014-11-03 12:54:37 -07001853 if (! (m_compile_options & EOptionSuppressInfolog)) {
1854 puts(shader->getInfoLog());
1855 puts(shader->getInfoDebugLog());
1856 }
1857
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001858 return false; // something didn't work
1859 }
1860
1861 program.addShader(shader);
1862
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001863
1864 //
1865 // Program-level processing...
1866 //
1867
Cody Northrop195d6622014-11-03 12:54:37 -07001868 if (! program.link(messages)) {
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001869
Cody Northrop195d6622014-11-03 12:54:37 -07001870 if (! (m_compile_options & EOptionSuppressInfolog)) {
1871 puts(shader->getInfoLog());
1872 puts(shader->getInfoDebugLog());
1873 }
1874
1875 return false;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001876 }
1877
1878 if (m_compile_options & EOptionDumpReflection) {
1879 program.buildReflection();
1880 program.dumpReflection();
1881 }
1882
Cody Northrop5a95b472015-06-03 13:01:54 -06001883 glslang::GlslangToSpv(*program.getIntermediate(stage), spirv);
1884
1885 //
1886 // Test the different modes of SPIR-V modification
1887 //
1888 if (this->m_canonicalize_spv) {
1889 spv::spirvbin_t(0).remap(spirv, spv::spirvbin_t::ALL_BUT_STRIP);
1890 }
1891
1892 if (this->m_strip_spv) {
1893 spv::spirvbin_t(0).remap(spirv, spv::spirvbin_t::STRIP);
1894 }
1895
1896 if (this->m_do_everything_spv) {
1897 spv::spirvbin_t(0).remap(spirv, spv::spirvbin_t::DO_EVERYTHING);
1898 }
1899
Courtney Goeltzenleuchterc7def922015-09-24 17:05:05 -06001900 delete shader;
Courtney Goeltzenleuchter9818f782014-10-03 09:53:32 -06001901
1902 return true;
1903}
1904
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001905
1906
Tony Barbour6918cd52015-04-09 12:58:51 -06001907VkTestImageRecord::VkTestImageRecord() : // Constructor
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001908 m_width( 0 ),
1909 m_height( 0 ),
Chia-I Wu837f9952014-12-15 23:29:34 +08001910 m_data( NULL ),
1911 m_data_size( 0 )
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001912{
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001913}
1914
Tony Barbour6918cd52015-04-09 12:58:51 -06001915VkTestImageRecord::~VkTestImageRecord()
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001916{
1917
1918}
1919
Tony Barbour6918cd52015-04-09 12:58:51 -06001920VkTestImageRecord::VkTestImageRecord(const VkTestImageRecord &copyin) // Copy constructor to handle pass by value.
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001921{
1922 m_title = copyin.m_title;
1923 m_width = copyin.m_width;
1924 m_height = copyin.m_height;
1925 m_data_size = copyin.m_data_size;
1926 m_data = copyin.m_data; // TODO: Do we need to copy the data or is pointer okay?
1927}
1928
Tony Barbour6918cd52015-04-09 12:58:51 -06001929ostream &operator<<(ostream &output, const VkTestImageRecord &VkTestImageRecord)
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001930{
Tony Barbour6918cd52015-04-09 12:58:51 -06001931 output << VkTestImageRecord.m_title << " (" << VkTestImageRecord.m_width <<
1932 "," << VkTestImageRecord.m_height << ")" << endl;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001933 return output;
1934}
1935
Tony Barbour6918cd52015-04-09 12:58:51 -06001936VkTestImageRecord& VkTestImageRecord::operator=(const VkTestImageRecord &rhs)
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001937{
1938 m_title = rhs.m_title;
1939 m_width = rhs.m_width;
1940 m_height = rhs.m_height;
1941 m_data_size = rhs.m_data_size;
1942 m_data = rhs.m_data;
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001943 return *this;
1944}
1945
Tony Barbour6918cd52015-04-09 12:58:51 -06001946int VkTestImageRecord::operator==(const VkTestImageRecord &rhs) const
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001947{
1948 if( this->m_data != rhs.m_data) return 0;
1949 return 1;
1950}
1951
1952// This function is required for built-in STL list functions like sort
Tony Barbour6918cd52015-04-09 12:58:51 -06001953int VkTestImageRecord::operator<(const VkTestImageRecord &rhs) const
Courtney Goeltzenleuchter30e9dc42014-09-04 16:24:19 -06001954{
1955 if( this->m_data_size < rhs.m_data_size ) return 1;
1956 return 0;
1957}
1958