blob: 8097487553cc42c9c0e5410d43688cdcc2e5ea80 [file] [log] [blame]
Chia-I Wuf5caeb02014-10-25 12:11:27 +08001/*
Ian Elliott7595eee2015-04-28 10:33:11 -06002 * Vulkan
3 *
4 * Copyright (C) 2014-2015 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24/*
Chia-I Wuf5caeb02014-10-25 12:11:27 +080025 * Draw a textured triangle with depth testing. This is written against Intel
26 * ICD. It does not do state transition nor object memory binding like it
27 * should. It also does no error checking.
28 */
29
Chia-I Wuc19795a2014-09-13 11:12:55 +080030#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#include <stdbool.h>
34#include <assert.h>
35
Ian Elliotte14e9f92015-04-16 15:23:05 -060036#ifdef _WIN32
37#pragma comment(linker, "/subsystem:windows")
38#include <windows.h>
39#define APP_NAME_STR_LEN 80
40#else // _WIN32
Chia-I Wuc19795a2014-09-13 11:12:55 +080041#include <xcb/xcb.h>
Ian Elliotte14e9f92015-04-16 15:23:05 -060042#endif // _WIN32
43
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060044#include <vulkan.h>
Chia-I Wu5b66aa52015-04-16 22:02:10 +080045#include <vk_wsi_lunarg.h>
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -060046#include "vk_debug_report_lunarg.h"
Chia-I Wuc19795a2014-09-13 11:12:55 +080047
Cody Northropd4e020a2015-03-17 14:54:35 -060048#include "icd-spv.h"
Courtney Goeltzenleuchter3f2606d2014-10-13 17:51:58 -060049
Chia-I Wuc19795a2014-09-13 11:12:55 +080050#define DEMO_BUFFER_COUNT 2
Chia-I Wub043fe32014-10-06 15:30:33 +080051#define DEMO_TEXTURE_COUNT 1
Courtney Goeltzenleuchterf5cdad02015-03-31 16:36:30 -060052#define VERTEX_BUFFER_BIND_ID 0
Ian Elliott4e19ed02015-04-28 10:52:52 -060053#define APP_SHORT_NAME "tri"
54#define APP_LONG_NAME "The Vulkan Triangle Demo Program"
Chia-I Wuc19795a2014-09-13 11:12:55 +080055
Tony Barbour22a30862015-04-22 09:02:32 -060056#if defined(NDEBUG) && defined(__GNUC__)
57#define U_ASSERT_ONLY __attribute__((unused))
58#else
59#define U_ASSERT_ONLY
60#endif
61
Ian Elliottcaa9f272015-04-28 11:35:02 -060062#ifdef _WIN32
63#define ERR_EXIT(err_msg, err_class) \
64 do { \
65 MessageBox(NULL, err_msg, err_class, MB_OK); \
66 exit(1); \
67 } while (0)
68
69// NOTE: If the following values (copied from "loader_platform.h") change, they
70// need to change here as well:
71#define LAYER_NAMES_ENV "VK_LAYER_NAMES"
72#define LAYER_NAMES_REGISTRY_VALUE "VK_LAYER_NAMES"
73#else // _WIN32
74
75#define ERR_EXIT(err_msg, err_class) \
76 do { \
77 printf(err_msg); \
78 fflush(stdout); \
79 exit(1); \
80 } while (0)
81#endif // _WIN32
Tony Barbour22a30862015-04-22 09:02:32 -060082
Ian Elliott1b6de092015-06-22 15:07:49 -060083#define GET_DEVICE_PROC_ADDR(dev, entrypoint) \
84{ \
85 demo->fp##entrypoint = vkGetDeviceProcAddr(dev, "vk"#entrypoint); \
86 if (demo->fp##entrypoint == NULL) { \
87 ERR_EXIT("vkGetDeviceProcAddr failed to find vk"#entrypoint, \
88 "vkGetDeviceProcAddr Failure"); \
89 } \
90}
91
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -060092struct texture_object {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060093 VkSampler sampler;
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -070094
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060095 VkImage image;
96 VkImageLayout imageLayout;
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -060097
Mark Lobodzinski23182612015-05-29 09:32:35 -050098 VkDeviceMemory mem;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060099 VkImageView view;
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700100 int32_t tex_width, tex_height;
101};
102
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600103void dbgFunc(
Tony Barbourde4124d2015-07-03 10:33:54 -0600104 VkFlags msgFlags,
105 VkDbgObjectType objType,
106 uint64_t srcObject,
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600107 size_t location,
108 int32_t msgCode,
109 const char* pLayerPrefix,
110 const char* pMsg,
111 void* pUserData)
112{
113 char *message = (char *) malloc(strlen(pMsg)+100);
114
115 assert (message);
116
117 if (msgFlags & VK_DBG_REPORT_ERROR_BIT) {
118 sprintf(message,"ERROR: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
119 } else if (msgFlags & VK_DBG_REPORT_WARN_BIT) {
120 sprintf(message,"WARNING: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
121 } else {
122 return;
123 }
124
125#ifdef _WIN32
126 MessageBox(NULL, message, "Alert", MB_OK);
127#else
128 printf("%s\n",message);
129 fflush(stdout);
130#endif
131 free(message);
132}
133
Chia-I Wuc19795a2014-09-13 11:12:55 +0800134struct demo {
Ian Elliotte14e9f92015-04-16 15:23:05 -0600135#ifdef _WIN32
136#define APP_NAME_STR_LEN 80
137 HINSTANCE connection; // hInstance - Windows Instance
138 char name[APP_NAME_STR_LEN]; // Name to put on the window/icon
139 HWND window; // hWnd - window handle
140#else // _WIN32
Chia-I Wuc19795a2014-09-13 11:12:55 +0800141 xcb_connection_t *connection;
142 xcb_screen_t *screen;
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800143 xcb_window_t window;
144 xcb_intern_atom_reply_t *atom_wm_delete_window;
Ian Elliotte14e9f92015-04-16 15:23:05 -0600145#endif // _WIN32
Jon Ashburn8a399e92015-04-24 09:46:24 -0700146 bool prepared;
Ian Elliotte14e9f92015-04-16 15:23:05 -0600147 bool use_staging_buffer;
Cody Northrop75db0322015-05-28 11:27:16 -0600148 bool use_glsl;
Chia-I Wuc19795a2014-09-13 11:12:55 +0800149
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600150 VkInstance inst;
Tony Barbour8205d902015-04-16 15:59:00 -0600151 VkPhysicalDevice gpu;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600152 VkDevice device;
153 VkQueue queue;
Tony Barbour426b9052015-06-24 16:06:58 -0600154 VkPhysicalDeviceProperties gpu_props;
Tony Barbour8205d902015-04-16 15:59:00 -0600155 VkPhysicalDeviceQueueProperties *queue_props;
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700156 uint32_t graphics_queue_node_index;
Chia-I Wuc19795a2014-09-13 11:12:55 +0800157
158 int width, height;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600159 VkFormat format;
Chia-I Wuc19795a2014-09-13 11:12:55 +0800160
Jon Ashburncedc15f2015-05-21 18:13:33 -0600161 PFN_vkCreateSwapChainWSI fpCreateSwapChainWSI;
162 PFN_vkDestroySwapChainWSI fpDestroySwapChainWSI;
163 PFN_vkGetSwapChainInfoWSI fpGetSwapChainInfoWSI;
164 PFN_vkQueuePresentWSI fpQueuePresentWSI;
165
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800166 VkSwapChainWSI swap_chain;
Chia-I Wuc19795a2014-09-13 11:12:55 +0800167 struct {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600168 VkImage image;
Tony Barbour8205d902015-04-16 15:59:00 -0600169 VkDeviceMemory mem;
Chia-I Wuc19795a2014-09-13 11:12:55 +0800170
Chia-I Wuc278df82015-07-07 11:50:03 +0800171 VkAttachmentView view;
Chia-I Wuc19795a2014-09-13 11:12:55 +0800172 } buffers[DEMO_BUFFER_COUNT];
173
Chia-I Wub043fe32014-10-06 15:30:33 +0800174 struct {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600175 VkFormat format;
Chia-I Wu9ae87c92014-10-07 14:15:01 +0800176
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600177 VkImage image;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500178 VkDeviceMemory mem;
Chia-I Wuc278df82015-07-07 11:50:03 +0800179 VkAttachmentView view;
Chia-I Wu9ae87c92014-10-07 14:15:01 +0800180 } depth;
181
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600182 struct texture_object textures[DEMO_TEXTURE_COUNT];
Chia-I Wub043fe32014-10-06 15:30:33 +0800183
Chia-I Wu99621bc2014-10-08 11:52:22 +0800184 struct {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600185 VkBuffer buf;
Mark Lobodzinski23182612015-05-29 09:32:35 -0500186 VkDeviceMemory mem;
Chia-I Wu8d29d022014-10-08 12:14:39 +0800187
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600188 VkPipelineVertexInputStateCreateInfo vi;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600189 VkVertexInputBindingDescription vi_bindings[1];
190 VkVertexInputAttributeDescription vi_attrs[2];
Chia-I Wu99621bc2014-10-08 11:52:22 +0800191 } vertices;
192
Courtney Goeltzenleuchter633f9c52015-04-30 10:58:33 -0600193 VkCmdBuffer setup_cmd; // Command Buffer for initialization commands
194 VkCmdBuffer draw_cmd; // Command Buffer for drawing commands
Mark Lobodzinski556f7212015-04-17 14:11:39 -0500195 VkPipelineLayout pipeline_layout;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600196 VkDescriptorSetLayout desc_layout;
Jon Ashburn0d60d272015-07-09 15:02:25 -0600197 VkPipelineCache pipelineCache;
Chia-I Wu76cd4222015-07-08 13:34:24 +0800198 VkRenderPass render_pass;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600199 VkPipeline pipeline;
Chia-I Wuc19795a2014-09-13 11:12:55 +0800200
Tony Barbourde4124d2015-07-03 10:33:54 -0600201 VkDynamicViewportState viewport;
202 VkDynamicRasterState raster;
203 VkDynamicColorBlendState color_blend;
204 VkDynamicDepthStencilState depth_stencil;
Chia-I Wuc19795a2014-09-13 11:12:55 +0800205
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600206 VkDescriptorPool desc_pool;
207 VkDescriptorSet desc_set;
Chia-I Wuf8385062015-01-04 16:27:24 +0800208
Chia-I Wu76cd4222015-07-08 13:34:24 +0800209 VkFramebuffer framebuffers[DEMO_BUFFER_COUNT];
210
Mark Lobodzinski72346292015-07-02 16:49:40 -0600211 VkPhysicalDeviceMemoryProperties memory_properties;
212
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600213 bool validate;
214 PFN_vkDbgCreateMsgCallback dbgCreateMsgCallback;
215 VkDbgMsgCallback msg_callback;
216
Chia-I Wuc19795a2014-09-13 11:12:55 +0800217 bool quit;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600218 uint32_t current_buffer;
Chia-I Wuc19795a2014-09-13 11:12:55 +0800219};
220
Mark Lobodzinski72346292015-07-02 16:49:40 -0600221static VkResult memory_type_from_properties(struct demo *demo, uint32_t typeBits, VkFlags properties, uint32_t *typeIndex)
222{
223 // Search memtypes to find first index with those properties
224 for (uint32_t i = 0; i < 32; i++) {
225 if ((typeBits & 1) == 1) {
226 // Type is available, does it match user properties?
227 if ((demo->memory_properties.memoryTypes[i].propertyFlags & properties) == properties) {
228 *typeIndex = i;
229 return VK_SUCCESS;
230 }
231 }
232 typeBits >>= 1;
233 }
234 // No memory types matched, return failure
235 return VK_UNSUPPORTED;
236}
237
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600238static void demo_flush_init_cmd(struct demo *demo)
239{
Tony Barbour22a30862015-04-22 09:02:32 -0600240 VkResult U_ASSERT_ONLY err;
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600241
Courtney Goeltzenleuchter633f9c52015-04-30 10:58:33 -0600242 if (demo->setup_cmd == VK_NULL_HANDLE)
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600243 return;
244
Courtney Goeltzenleuchter633f9c52015-04-30 10:58:33 -0600245 err = vkEndCommandBuffer(demo->setup_cmd);
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600246 assert(!err);
247
Courtney Goeltzenleuchter633f9c52015-04-30 10:58:33 -0600248 const VkCmdBuffer cmd_bufs[] = { demo->setup_cmd };
Tony Barbourde4124d2015-07-03 10:33:54 -0600249 VkFence nullFence = {VK_NULL_HANDLE};
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600250
Tony Barbourde4124d2015-07-03 10:33:54 -0600251 err = vkQueueSubmit(demo->queue, 1, cmd_bufs, nullFence);
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600252 assert(!err);
253
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600254 err = vkQueueWaitIdle(demo->queue);
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600255 assert(!err);
256
Tony Barbourde4124d2015-07-03 10:33:54 -0600257 vkDestroyCommandBuffer(demo->device, demo->setup_cmd);
Courtney Goeltzenleuchter633f9c52015-04-30 10:58:33 -0600258 demo->setup_cmd = VK_NULL_HANDLE;
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600259}
260
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600261static void demo_set_image_layout(
262 struct demo *demo,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600263 VkImage image,
malnasse4b8ba4d2015-06-03 17:28:38 -0400264 VkImageAspect aspect,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600265 VkImageLayout old_image_layout,
266 VkImageLayout new_image_layout)
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600267{
Tony Barbour22a30862015-04-22 09:02:32 -0600268 VkResult U_ASSERT_ONLY err;
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600269
Courtney Goeltzenleuchter633f9c52015-04-30 10:58:33 -0600270 if (demo->setup_cmd == VK_NULL_HANDLE) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600271 const VkCmdBufferCreateInfo cmd = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600272 .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600273 .pNext = NULL,
274 .queueNodeIndex = demo->graphics_queue_node_index,
Chia-I Wu88eaa3b2015-06-26 15:34:39 +0800275 .level = VK_CMD_BUFFER_LEVEL_PRIMARY,
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600276 .flags = 0,
277 };
278
Courtney Goeltzenleuchter633f9c52015-04-30 10:58:33 -0600279 err = vkCreateCommandBuffer(demo->device, &cmd, &demo->setup_cmd);
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600280 assert(!err);
281
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600282 VkCmdBufferBeginInfo cmd_buf_info = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600283 .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600284 .pNext = NULL,
Tony Barbour8205d902015-04-16 15:59:00 -0600285 .flags = VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT |
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600286 VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT,
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600287 };
Courtney Goeltzenleuchter633f9c52015-04-30 10:58:33 -0600288 err = vkBeginCommandBuffer(demo->setup_cmd, &cmd_buf_info);
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600289 }
290
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600291 VkImageMemoryBarrier image_memory_barrier = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600292 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600293 .pNext = NULL,
294 .outputMask = 0,
295 .inputMask = 0,
296 .oldLayout = old_image_layout,
297 .newLayout = new_image_layout,
298 .image = image,
malnasse4b8ba4d2015-06-03 17:28:38 -0400299 .subresourceRange = { aspect, 0, 1, 0, 0 }
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600300 };
301
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600302 if (new_image_layout == VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL) {
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600303 /* Make sure anything that was copying from this image has completed */
Courtney Goeltzenleuchterad870812015-04-15 15:29:59 -0600304 image_memory_barrier.inputMask = VK_MEMORY_INPUT_TRANSFER_BIT;
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600305 }
306
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600307 if (new_image_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600308 /* Make sure any Copy or CPU writes to image are flushed */
Courtney Goeltzenleuchtera569a502015-04-29 17:16:21 -0600309 image_memory_barrier.outputMask = VK_MEMORY_OUTPUT_TRANSFER_BIT | VK_MEMORY_OUTPUT_HOST_WRITE_BIT;
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600310 }
311
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600312 VkImageMemoryBarrier *pmemory_barrier = &image_memory_barrier;
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600313
Tony Barbourc2e987e2015-06-29 16:20:35 -0600314 VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
315 VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600316
Tony Barbourc2e987e2015-06-29 16:20:35 -0600317 vkCmdPipelineBarrier(demo->setup_cmd, src_stages, dest_stages, false, 1, (const void **)&pmemory_barrier);
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600318}
319
Chia-I Wuc19795a2014-09-13 11:12:55 +0800320static void demo_draw_build_cmd(struct demo *demo)
321{
Chia-I Wu76cd4222015-07-08 13:34:24 +0800322 const VkCmdBufferBeginInfo cmd_buf_info = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600323 .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,
Courtney Goeltzenleuchtere3b0f3a2015-04-03 15:25:24 -0600324 .pNext = NULL,
Tony Barbour8205d902015-04-16 15:59:00 -0600325 .flags = VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT |
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600326 VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT,
Jon Ashburn53d27af2014-12-31 17:08:35 -0700327 };
Chia-I Wuc278df82015-07-07 11:50:03 +0800328 const VkClearValue clear_values[2] = {
329 [0] = { .color.f32 = { 0.2f, 0.2f, 0.2f, 0.2f } },
330 [1] = { .ds = { 0.9f, 0 } },
331 };
332 const VkRenderPassBeginInfo rp_begin = {
333 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
334 .pNext = NULL,
Chia-I Wu76cd4222015-07-08 13:34:24 +0800335 .renderPass = demo->render_pass,
336 .framebuffer = demo->framebuffers[demo->current_buffer],
Chia-I Wuc278df82015-07-07 11:50:03 +0800337 .renderArea.offset.x = 0,
338 .renderArea.offset.y = 0,
339 .renderArea.extent.width = demo->width,
340 .renderArea.extent.height = demo->height,
341 .attachmentCount = 2,
342 .pAttachmentClearValues = clear_values,
Jon Ashburn3325d6b2015-01-02 18:24:05 -0700343 };
Chia-I Wu76cd4222015-07-08 13:34:24 +0800344 VkResult U_ASSERT_ONLY err;
Chia-I Wuc19795a2014-09-13 11:12:55 +0800345
Courtney Goeltzenleuchter633f9c52015-04-30 10:58:33 -0600346 err = vkBeginCommandBuffer(demo->draw_cmd, &cmd_buf_info);
Chia-I Wuc19795a2014-09-13 11:12:55 +0800347 assert(!err);
348
Chia-I Wuc278df82015-07-07 11:50:03 +0800349 vkCmdBeginRenderPass(demo->draw_cmd, &rp_begin, VK_RENDER_PASS_CONTENTS_INLINE);
Courtney Goeltzenleuchter633f9c52015-04-30 10:58:33 -0600350 vkCmdBindPipeline(demo->draw_cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
Chia-I Wuc19795a2014-09-13 11:12:55 +0800351 demo->pipeline);
Mark Lobodzinskia65c4632015-06-15 13:21:21 -0600352 vkCmdBindDescriptorSets(demo->draw_cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, demo->pipeline_layout,
Cody Northrop1a01b1d2015-04-16 13:41:56 -0600353 0, 1, & demo->desc_set, 0, NULL);
Chia-I Wuc19795a2014-09-13 11:12:55 +0800354
Tony Barbourde4124d2015-07-03 10:33:54 -0600355 vkCmdBindDynamicViewportState(demo->draw_cmd, demo->viewport);
356 vkCmdBindDynamicRasterState(demo->draw_cmd, demo->raster);
357 vkCmdBindDynamicColorBlendState(demo->draw_cmd, demo->color_blend);
358 vkCmdBindDynamicDepthStencilState(demo->draw_cmd, demo->depth_stencil);
Chia-I Wuc19795a2014-09-13 11:12:55 +0800359
Tony Barbour8205d902015-04-16 15:59:00 -0600360 VkDeviceSize offsets[1] = {0};
Courtney Goeltzenleuchter633f9c52015-04-30 10:58:33 -0600361 vkCmdBindVertexBuffers(demo->draw_cmd, VERTEX_BUFFER_BIND_ID, 1, &demo->vertices.buf, offsets);
Chia-I Wu3b04af52014-11-08 10:48:20 +0800362
Courtney Goeltzenleuchter633f9c52015-04-30 10:58:33 -0600363 vkCmdDraw(demo->draw_cmd, 0, 3, 0, 1);
Chia-I Wu88eaa3b2015-06-26 15:34:39 +0800364 vkCmdEndRenderPass(demo->draw_cmd);
Chia-I Wuc19795a2014-09-13 11:12:55 +0800365
Courtney Goeltzenleuchter633f9c52015-04-30 10:58:33 -0600366 err = vkEndCommandBuffer(demo->draw_cmd);
Chia-I Wuc19795a2014-09-13 11:12:55 +0800367 assert(!err);
368}
369
370static void demo_draw(struct demo *demo)
371{
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800372 const VkPresentInfoWSI present = {
373 .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_WSI,
374 .pNext = NULL,
375 .image = demo->buffers[demo->current_buffer].image,
376 .flipInterval = 0,
Chia-I Wuc19795a2014-09-13 11:12:55 +0800377 };
Tony Barbour22a30862015-04-22 09:02:32 -0600378 VkResult U_ASSERT_ONLY err;
Chia-I Wuc19795a2014-09-13 11:12:55 +0800379
380 demo_draw_build_cmd(demo);
Tony Barbourde4124d2015-07-03 10:33:54 -0600381 VkFence nullFence = { VK_NULL_HANDLE };
Chia-I Wuc19795a2014-09-13 11:12:55 +0800382
Tony Barbourde4124d2015-07-03 10:33:54 -0600383 err = vkQueueSubmit(demo->queue, 1, &demo->draw_cmd, nullFence);
Chia-I Wuc19795a2014-09-13 11:12:55 +0800384 assert(!err);
385
Jon Ashburncedc15f2015-05-21 18:13:33 -0600386 err = demo->fpQueuePresentWSI(demo->queue, &present);
Chia-I Wuc19795a2014-09-13 11:12:55 +0800387 assert(!err);
388
389 demo->current_buffer = (demo->current_buffer + 1) % DEMO_BUFFER_COUNT;
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800390
391 err = vkQueueWaitIdle(demo->queue);
392 assert(err == VK_SUCCESS);
Chia-I Wuc19795a2014-09-13 11:12:55 +0800393}
394
395static void demo_prepare_buffers(struct demo *demo)
396{
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800397 const VkSwapChainCreateInfoWSI swap_chain = {
398 .sType = VK_STRUCTURE_TYPE_SWAP_CHAIN_CREATE_INFO_WSI,
399 .pNext = NULL,
400 .pNativeWindowSystemHandle = demo->connection,
401 .pNativeWindowHandle = (void *) (intptr_t) demo->window,
Ian Elliott32536f92015-04-21 16:41:02 -0600402 .displayCount = 1,
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800403 .imageCount = DEMO_BUFFER_COUNT,
404 .imageFormat = demo->format,
405 .imageExtent = {
Chia-I Wuc19795a2014-09-13 11:12:55 +0800406 .width = demo->width,
407 .height = demo->height,
408 },
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800409 .imageArraySize = 1,
410 .imageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
Chia-I Wuc19795a2014-09-13 11:12:55 +0800411 };
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800412 VkSwapChainImageInfoWSI images[DEMO_BUFFER_COUNT];
413 size_t images_size = sizeof(images);
Tony Barbour22a30862015-04-22 09:02:32 -0600414 VkResult U_ASSERT_ONLY err;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600415 uint32_t i;
Chia-I Wuc19795a2014-09-13 11:12:55 +0800416
Jon Ashburncedc15f2015-05-21 18:13:33 -0600417 err = demo->fpCreateSwapChainWSI(demo->device, &swap_chain, &demo->swap_chain);
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800418 assert(!err);
419
Jon Ashburncedc15f2015-05-21 18:13:33 -0600420 err = demo->fpGetSwapChainInfoWSI(demo->swap_chain,
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800421 VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI,
422 &images_size, images);
423 assert(!err && images_size == sizeof(images));
424
Chia-I Wuc19795a2014-09-13 11:12:55 +0800425 for (i = 0; i < DEMO_BUFFER_COUNT; i++) {
Chia-I Wuc278df82015-07-07 11:50:03 +0800426 VkAttachmentViewCreateInfo color_attachment_view = {
427 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
Chia-I Wuc19795a2014-09-13 11:12:55 +0800428 .pNext = NULL,
429 .format = demo->format,
430 .mipLevel = 0,
431 .baseArraySlice = 0,
432 .arraySize = 1,
433 };
434
Chia-I Wu5b66aa52015-04-16 22:02:10 +0800435 demo->buffers[i].image = images[i].image;
436 demo->buffers[i].mem = images[i].memory;
Mark Lobodzinski97dcd042015-04-16 08:52:00 -0500437
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600438 demo_set_image_layout(demo, demo->buffers[i].image,
malnasse4b8ba4d2015-06-03 17:28:38 -0400439 VK_IMAGE_ASPECT_COLOR,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600440 VK_IMAGE_LAYOUT_UNDEFINED,
441 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600442
Chia-I Wuc19795a2014-09-13 11:12:55 +0800443 color_attachment_view.image = demo->buffers[i].image;
444
Chia-I Wuc278df82015-07-07 11:50:03 +0800445 err = vkCreateAttachmentView(demo->device,
Chia-I Wuc19795a2014-09-13 11:12:55 +0800446 &color_attachment_view, &demo->buffers[i].view);
447 assert(!err);
448 }
Piers Daniell886be472015-02-23 16:23:13 -0700449
450 demo->current_buffer = 0;
Chia-I Wuc19795a2014-09-13 11:12:55 +0800451}
452
Chia-I Wu9ae87c92014-10-07 14:15:01 +0800453static void demo_prepare_depth(struct demo *demo)
454{
Tony Barbour8205d902015-04-16 15:59:00 -0600455 const VkFormat depth_format = VK_FORMAT_D16_UNORM;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600456 const VkImageCreateInfo image = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600457 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
Chia-I Wu9ae87c92014-10-07 14:15:01 +0800458 .pNext = NULL,
Tony Barbour8205d902015-04-16 15:59:00 -0600459 .imageType = VK_IMAGE_TYPE_2D,
Chia-I Wu9ae87c92014-10-07 14:15:01 +0800460 .format = depth_format,
461 .extent = { demo->width, demo->height, 1 },
462 .mipLevels = 1,
463 .arraySize = 1,
464 .samples = 1,
Tony Barbour8205d902015-04-16 15:59:00 -0600465 .tiling = VK_IMAGE_TILING_OPTIMAL,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600466 .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_BIT,
Chia-I Wu9ae87c92014-10-07 14:15:01 +0800467 .flags = 0,
468 };
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600469 VkMemoryAllocInfo mem_alloc = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600470 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
Mark Lobodzinski97dcd042015-04-16 08:52:00 -0500471 .pNext = NULL,
Chia-I Wu9ae87c92014-10-07 14:15:01 +0800472 .allocationSize = 0,
Mark Lobodzinski72346292015-07-02 16:49:40 -0600473 .memoryTypeIndex = 0,
Chia-I Wu9ae87c92014-10-07 14:15:01 +0800474 };
Chia-I Wuc278df82015-07-07 11:50:03 +0800475 VkAttachmentViewCreateInfo view = {
476 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
Chia-I Wu9ae87c92014-10-07 14:15:01 +0800477 .pNext = NULL,
Tony Barbourde4124d2015-07-03 10:33:54 -0600478 .image.handle = VK_NULL_HANDLE,
Chia-I Wu9ae87c92014-10-07 14:15:01 +0800479 .mipLevel = 0,
480 .baseArraySlice = 0,
481 .arraySize = 1,
482 .flags = 0,
483 };
Jon Ashburna9ae3832015-01-16 09:37:43 -0700484
Mark Lobodzinski23182612015-05-29 09:32:35 -0500485 VkMemoryRequirements mem_reqs;
Tony Barbour22a30862015-04-22 09:02:32 -0600486 VkResult U_ASSERT_ONLY err;
Chia-I Wu9ae87c92014-10-07 14:15:01 +0800487
488 demo->depth.format = depth_format;
489
490 /* create image */
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600491 err = vkCreateImage(demo->device, &image,
Chia-I Wu9ae87c92014-10-07 14:15:01 +0800492 &demo->depth.image);
493 assert(!err);
494
Mark Lobodzinski72346292015-07-02 16:49:40 -0600495 /* get memory requirements for this object */
Tony Barbourde4124d2015-07-03 10:33:54 -0600496 err = vkGetImageMemoryRequirements(demo->device, demo->depth.image,
497 &mem_reqs);
Mark Lobodzinski72346292015-07-02 16:49:40 -0600498
499 /* select memory size and type */
Mark Lobodzinski23182612015-05-29 09:32:35 -0500500 mem_alloc.allocationSize = mem_reqs.size;
Mark Lobodzinski72346292015-07-02 16:49:40 -0600501 err = memory_type_from_properties(demo,
502 mem_reqs.memoryTypeBits,
503 VK_MEMORY_PROPERTY_DEVICE_ONLY,
504 &mem_alloc.memoryTypeIndex);
505 assert(!err);
Chia-I Wu9ae87c92014-10-07 14:15:01 +0800506
Mark Lobodzinski23182612015-05-29 09:32:35 -0500507 /* allocate memory */
508 err = vkAllocMemory(demo->device, &mem_alloc, &demo->depth.mem);
509 assert(!err);
Chia-I Wu9ae87c92014-10-07 14:15:01 +0800510
Mark Lobodzinski23182612015-05-29 09:32:35 -0500511 /* bind memory */
Tony Barbourde4124d2015-07-03 10:33:54 -0600512 err = vkBindImageMemory(demo->device, demo->depth.image,
513 demo->depth.mem, 0);
Mark Lobodzinski23182612015-05-29 09:32:35 -0500514 assert(!err);
Chia-I Wu9ae87c92014-10-07 14:15:01 +0800515
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600516 demo_set_image_layout(demo, demo->depth.image,
malnasse4b8ba4d2015-06-03 17:28:38 -0400517 VK_IMAGE_ASPECT_DEPTH,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600518 VK_IMAGE_LAYOUT_UNDEFINED,
519 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600520
Chia-I Wu9ae87c92014-10-07 14:15:01 +0800521 /* create image view */
522 view.image = demo->depth.image;
Chia-I Wuc278df82015-07-07 11:50:03 +0800523 err = vkCreateAttachmentView(demo->device, &view, &demo->depth.view);
Chia-I Wu9ae87c92014-10-07 14:15:01 +0800524 assert(!err);
Chia-I Wu9ae87c92014-10-07 14:15:01 +0800525}
526
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700527static void demo_prepare_texture_image(struct demo *demo,
528 const uint32_t *tex_colors,
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600529 struct texture_object *tex_obj,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600530 VkImageTiling tiling,
Courtney Goeltzenleuchtercb67a322015-04-21 09:31:23 -0600531 VkImageUsageFlags usage,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600532 VkFlags mem_props)
Chia-I Wub043fe32014-10-06 15:30:33 +0800533{
Tony Barbour8205d902015-04-16 15:59:00 -0600534 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600535 const int32_t tex_width = 2;
536 const int32_t tex_height = 2;
Tony Barbour22a30862015-04-22 09:02:32 -0600537 VkResult U_ASSERT_ONLY err;
Chia-I Wub043fe32014-10-06 15:30:33 +0800538
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600539 tex_obj->tex_width = tex_width;
540 tex_obj->tex_height = tex_height;
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700541
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600542 const VkImageCreateInfo image_create_info = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600543 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
Courtney Goeltzenleuchter3226a6f2015-02-11 18:17:22 -0700544 .pNext = NULL,
Tony Barbour8205d902015-04-16 15:59:00 -0600545 .imageType = VK_IMAGE_TYPE_2D,
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700546 .format = tex_format,
547 .extent = { tex_width, tex_height, 1 },
548 .mipLevels = 1,
549 .arraySize = 1,
550 .samples = 1,
551 .tiling = tiling,
Courtney Goeltzenleuchtercb67a322015-04-21 09:31:23 -0600552 .usage = usage,
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700553 .flags = 0,
554 };
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600555 VkMemoryAllocInfo mem_alloc = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600556 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
Mark Lobodzinski97dcd042015-04-16 08:52:00 -0500557 .pNext = NULL,
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700558 .allocationSize = 0,
Mark Lobodzinski72346292015-07-02 16:49:40 -0600559 .memoryTypeIndex = 0,
Courtney Goeltzenleuchter3226a6f2015-02-11 18:17:22 -0700560 };
561
Mark Lobodzinski23182612015-05-29 09:32:35 -0500562 VkMemoryRequirements mem_reqs;
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700563
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600564 err = vkCreateImage(demo->device, &image_create_info,
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600565 &tex_obj->image);
Courtney Goeltzenleuchter3226a6f2015-02-11 18:17:22 -0700566 assert(!err);
567
Tony Barbourde4124d2015-07-03 10:33:54 -0600568 err = vkGetImageMemoryRequirements(demo->device, tex_obj->image, &mem_reqs);
Mark Lobodzinski72346292015-07-02 16:49:40 -0600569
570 mem_alloc.allocationSize = mem_reqs.size;
571 err = memory_type_from_properties(demo, mem_reqs.memoryTypeBits, mem_props, &mem_alloc.memoryTypeIndex);
572 assert(!err);
Courtney Goeltzenleuchter3226a6f2015-02-11 18:17:22 -0700573
Mark Lobodzinski23182612015-05-29 09:32:35 -0500574 /* allocate memory */
575 err = vkAllocMemory(demo->device, &mem_alloc, &tex_obj->mem);
576 assert(!err);
Courtney Goeltzenleuchter3226a6f2015-02-11 18:17:22 -0700577
Mark Lobodzinski23182612015-05-29 09:32:35 -0500578 /* bind memory */
Tony Barbourde4124d2015-07-03 10:33:54 -0600579 err = vkBindImageMemory(demo->device, tex_obj->image,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500580 tex_obj->mem, 0);
581 assert(!err);
Courtney Goeltzenleuchter3226a6f2015-02-11 18:17:22 -0700582
Tony Barbour8205d902015-04-16 15:59:00 -0600583 if (mem_props & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600584 const VkImageSubresource subres = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600585 .aspect = VK_IMAGE_ASPECT_COLOR,
Courtney Goeltzenleuchter3226a6f2015-02-11 18:17:22 -0700586 .mipLevel = 0,
587 .arraySlice = 0,
588 };
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600589 VkSubresourceLayout layout;
Courtney Goeltzenleuchter3226a6f2015-02-11 18:17:22 -0700590 void *data;
591 int32_t x, y;
592
Tony Barbour426b9052015-06-24 16:06:58 -0600593 err = vkGetImageSubresourceLayout(demo->device, tex_obj->image, &subres, &layout);
594 assert(!err);
Courtney Goeltzenleuchter3226a6f2015-02-11 18:17:22 -0700595
Mark Lobodzinski23182612015-05-29 09:32:35 -0500596 err = vkMapMemory(demo->device, tex_obj->mem, 0, 0, 0, &data);
Courtney Goeltzenleuchter3226a6f2015-02-11 18:17:22 -0700597 assert(!err);
598
599 for (y = 0; y < tex_height; y++) {
600 uint32_t *row = (uint32_t *) ((char *) data + layout.rowPitch * y);
601 for (x = 0; x < tex_width; x++)
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700602 row[x] = tex_colors[(x & 1) ^ (y & 1)];
Courtney Goeltzenleuchter3226a6f2015-02-11 18:17:22 -0700603 }
604
Mark Lobodzinski23182612015-05-29 09:32:35 -0500605 err = vkUnmapMemory(demo->device, tex_obj->mem);
Courtney Goeltzenleuchter3226a6f2015-02-11 18:17:22 -0700606 assert(!err);
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700607 }
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600608
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600609 tex_obj->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600610 demo_set_image_layout(demo, tex_obj->image,
malnasse4b8ba4d2015-06-03 17:28:38 -0400611 VK_IMAGE_ASPECT_COLOR,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600612 VK_IMAGE_LAYOUT_UNDEFINED,
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600613 tex_obj->imageLayout);
614 /* setting the image layout does not reference the actual memory so no need to add a mem ref */
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700615}
616
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500617static void demo_destroy_texture_image(struct demo *demo, struct texture_object *tex_obj)
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700618{
619 /* clean up staging resources */
Tony Barbourde4124d2015-07-03 10:33:54 -0600620 vkDestroyImage(demo->device, tex_obj->image);
Courtney Goeltzenleuchtera063d9b2015-06-10 16:16:22 -0600621 vkFreeMemory(demo->device, tex_obj->mem);
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700622}
623
624static void demo_prepare_textures(struct demo *demo)
625{
Tony Barbour8205d902015-04-16 15:59:00 -0600626 const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600627 VkFormatProperties props;
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700628 const uint32_t tex_colors[DEMO_TEXTURE_COUNT][2] = {
629 { 0xffff0000, 0xff00ff00 },
630 };
Tony Barbour22a30862015-04-22 09:02:32 -0600631 VkResult U_ASSERT_ONLY err;
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700632 uint32_t i;
633
Chris Forbesd7576302015-06-21 22:55:02 +1200634 err = vkGetPhysicalDeviceFormatInfo(demo->gpu, tex_format, &props);
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700635 assert(!err);
636
637 for (i = 0; i < DEMO_TEXTURE_COUNT; i++) {
Tony Barbour8205d902015-04-16 15:59:00 -0600638 if ((props.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) && !demo->use_staging_buffer) {
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700639 /* Device can texture using linear textures */
640 demo_prepare_texture_image(demo, tex_colors[i], &demo->textures[i],
Courtney Goeltzenleuchtercb67a322015-04-21 09:31:23 -0600641 VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
Tony Barbour8205d902015-04-16 15:59:00 -0600642 } else if (props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT){
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700643 /* Must use staging buffer to copy linear texture to optimized */
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600644 struct texture_object staging_texture;
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700645
646 memset(&staging_texture, 0, sizeof(staging_texture));
647 demo_prepare_texture_image(demo, tex_colors[i], &staging_texture,
Courtney Goeltzenleuchtercb67a322015-04-21 09:31:23 -0600648 VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700649
650 demo_prepare_texture_image(demo, tex_colors[i], &demo->textures[i],
Courtney Goeltzenleuchtercb67a322015-04-21 09:31:23 -0600651 VK_IMAGE_TILING_OPTIMAL,
652 (VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),
653 VK_MEMORY_PROPERTY_DEVICE_ONLY);
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700654
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600655 demo_set_image_layout(demo, staging_texture.image,
malnasse4b8ba4d2015-06-03 17:28:38 -0400656 VK_IMAGE_ASPECT_COLOR,
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600657 staging_texture.imageLayout,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600658 VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL);
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700659
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600660 demo_set_image_layout(demo, demo->textures[i].image,
malnasse4b8ba4d2015-06-03 17:28:38 -0400661 VK_IMAGE_ASPECT_COLOR,
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600662 demo->textures[i].imageLayout,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600663 VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL);
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700664
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600665 VkImageCopy copy_region = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600666 .srcSubresource = { VK_IMAGE_ASPECT_COLOR, 0, 0 },
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700667 .srcOffset = { 0, 0, 0 },
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600668 .destSubresource = { VK_IMAGE_ASPECT_COLOR, 0, 0 },
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700669 .destOffset = { 0, 0, 0 },
670 .extent = { staging_texture.tex_width, staging_texture.tex_height, 1 },
671 };
Courtney Goeltzenleuchter633f9c52015-04-30 10:58:33 -0600672 vkCmdCopyImage(demo->setup_cmd,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600673 staging_texture.image, VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL,
674 demo->textures[i].image, VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL,
Courtney Goeltzenleuchter51cbf302015-03-25 11:25:10 -0600675 1, &copy_region);
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700676
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600677 demo_set_image_layout(demo, demo->textures[i].image,
malnasse4b8ba4d2015-06-03 17:28:38 -0400678 VK_IMAGE_ASPECT_COLOR,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600679 VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL,
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600680 demo->textures[i].imageLayout);
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700681
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -0600682 demo_flush_init_cmd(demo);
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700683
Courtney Goeltzenleuchter876629f2015-04-21 09:30:03 -0600684 demo_destroy_texture_image(demo, &staging_texture);
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700685 } else {
Tony Barbour8205d902015-04-16 15:59:00 -0600686 /* Can't support VK_FORMAT_B8G8R8A8_UNORM !? */
Piers Daniell886be472015-02-23 16:23:13 -0700687 assert(!"No support for B8G8R8A8_UNORM as texture image format");
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700688 }
Courtney Goeltzenleuchter3226a6f2015-02-11 18:17:22 -0700689
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600690 const VkSamplerCreateInfo sampler = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600691 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
Chia-I Wub043fe32014-10-06 15:30:33 +0800692 .pNext = NULL,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600693 .magFilter = VK_TEX_FILTER_NEAREST,
694 .minFilter = VK_TEX_FILTER_NEAREST,
Tony Barbour8205d902015-04-16 15:59:00 -0600695 .mipMode = VK_TEX_MIPMAP_MODE_BASE,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600696 .addressU = VK_TEX_ADDRESS_WRAP,
697 .addressV = VK_TEX_ADDRESS_WRAP,
698 .addressW = VK_TEX_ADDRESS_WRAP,
Chia-I Wub043fe32014-10-06 15:30:33 +0800699 .mipLodBias = 0.0f,
Courtney Goeltzenleuchterbc9c8162015-02-13 18:20:24 -0700700 .maxAnisotropy = 1,
Tony Barbour8205d902015-04-16 15:59:00 -0600701 .compareOp = VK_COMPARE_OP_NEVER,
Chia-I Wub043fe32014-10-06 15:30:33 +0800702 .minLod = 0.0f,
703 .maxLod = 0.0f,
Tony Barbour2c4e7c72015-06-25 16:56:44 -0600704 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
Chia-I Wub043fe32014-10-06 15:30:33 +0800705 };
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600706 VkImageViewCreateInfo view = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600707 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
Chia-I Wub043fe32014-10-06 15:30:33 +0800708 .pNext = NULL,
Tony Barbourde4124d2015-07-03 10:33:54 -0600709 .image.handle = VK_NULL_HANDLE,
Tony Barbour8205d902015-04-16 15:59:00 -0600710 .viewType = VK_IMAGE_VIEW_TYPE_2D,
Courtney Goeltzenleuchter372e13c2015-02-13 17:52:46 -0700711 .format = tex_format,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600712 .channels = { VK_CHANNEL_SWIZZLE_R,
713 VK_CHANNEL_SWIZZLE_G,
714 VK_CHANNEL_SWIZZLE_B,
715 VK_CHANNEL_SWIZZLE_A, },
716 .subresourceRange = { VK_IMAGE_ASPECT_COLOR, 0, 1, 0, 1 },
Chia-I Wub043fe32014-10-06 15:30:33 +0800717 };
Jon Ashburna9ae3832015-01-16 09:37:43 -0700718
Chia-I Wub043fe32014-10-06 15:30:33 +0800719 /* create sampler */
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600720 err = vkCreateSampler(demo->device, &sampler,
Chia-I Wub043fe32014-10-06 15:30:33 +0800721 &demo->textures[i].sampler);
722 assert(!err);
723
Chia-I Wub043fe32014-10-06 15:30:33 +0800724 /* create image view */
725 view.image = demo->textures[i].image;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600726 err = vkCreateImageView(demo->device, &view,
Courtney Goeltzenleuchter3226a6f2015-02-11 18:17:22 -0700727 &demo->textures[i].view);
Chia-I Wub043fe32014-10-06 15:30:33 +0800728 assert(!err);
Chia-I Wub043fe32014-10-06 15:30:33 +0800729 }
730}
731
Chia-I Wu99621bc2014-10-08 11:52:22 +0800732static void demo_prepare_vertices(struct demo *demo)
733{
734 const float vb[3][5] = {
735 /* position texcoord */
Chia-I Wue2504cb2015-04-22 14:20:52 +0800736 { -1.0f, -1.0f, 0.2f, 0.0f, 0.0f },
737 { 1.0f, -1.0f, 0.25f, 1.0f, 0.0f },
Chia-I Wu99621bc2014-10-08 11:52:22 +0800738 { 0.0f, 1.0f, 1.0f, 0.5f, 1.0f },
739 };
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600740 const VkBufferCreateInfo buf_info = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600741 .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
Chia-I Wu714df452015-01-01 07:55:04 +0800742 .pNext = NULL,
743 .size = sizeof(vb),
Courtney Goeltzenleuchterad870812015-04-15 15:29:59 -0600744 .usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
Chia-I Wu714df452015-01-01 07:55:04 +0800745 .flags = 0,
746 };
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600747 VkMemoryAllocInfo mem_alloc = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600748 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
Mark Lobodzinski97dcd042015-04-16 08:52:00 -0500749 .pNext = NULL,
Chia-I Wu714df452015-01-01 07:55:04 +0800750 .allocationSize = 0,
Mark Lobodzinski72346292015-07-02 16:49:40 -0600751 .memoryTypeIndex = 0,
Chia-I Wu99621bc2014-10-08 11:52:22 +0800752 };
Mark Lobodzinski23182612015-05-29 09:32:35 -0500753 VkMemoryRequirements mem_reqs;
Tony Barbour22a30862015-04-22 09:02:32 -0600754 VkResult U_ASSERT_ONLY err;
Chia-I Wu99621bc2014-10-08 11:52:22 +0800755 void *data;
756
757 memset(&demo->vertices, 0, sizeof(demo->vertices));
758
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600759 err = vkCreateBuffer(demo->device, &buf_info, &demo->vertices.buf);
Chia-I Wu714df452015-01-01 07:55:04 +0800760 assert(!err);
761
Tony Barbourde4124d2015-07-03 10:33:54 -0600762 err = vkGetBufferMemoryRequirements(demo->device,
763 demo->vertices.buf, &mem_reqs);
Chia-I Wu714df452015-01-01 07:55:04 +0800764
Mark Lobodzinski72346292015-07-02 16:49:40 -0600765 mem_alloc.allocationSize = mem_reqs.size;
766 err = memory_type_from_properties(demo,
767 mem_reqs.memoryTypeBits,
768 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
769 &mem_alloc.memoryTypeIndex);
770 assert(!err);
Chia-I Wu99621bc2014-10-08 11:52:22 +0800771
Mark Lobodzinski23182612015-05-29 09:32:35 -0500772 err = vkAllocMemory(demo->device, &mem_alloc, &demo->vertices.mem);
773 assert(!err);
Chia-I Wu99621bc2014-10-08 11:52:22 +0800774
Mark Lobodzinski23182612015-05-29 09:32:35 -0500775 err = vkMapMemory(demo->device, demo->vertices.mem, 0, 0, 0, &data);
776 assert(!err);
Chia-I Wu99621bc2014-10-08 11:52:22 +0800777
Mark Lobodzinski23182612015-05-29 09:32:35 -0500778 memcpy(data, vb, sizeof(vb));
Chia-I Wu99621bc2014-10-08 11:52:22 +0800779
Mark Lobodzinski23182612015-05-29 09:32:35 -0500780 err = vkUnmapMemory(demo->device, demo->vertices.mem);
781 assert(!err);
782
Tony Barbourde4124d2015-07-03 10:33:54 -0600783 err = vkBindBufferMemory(demo->device, demo->vertices.buf,
Mark Lobodzinski23182612015-05-29 09:32:35 -0500784 demo->vertices.mem, 0);
785 assert(!err);
Chia-I Wu714df452015-01-01 07:55:04 +0800786
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -0600787 demo->vertices.vi.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
Chia-I Wu8d29d022014-10-08 12:14:39 +0800788 demo->vertices.vi.pNext = NULL;
789 demo->vertices.vi.bindingCount = 1;
790 demo->vertices.vi.pVertexBindingDescriptions = demo->vertices.vi_bindings;
791 demo->vertices.vi.attributeCount = 2;
792 demo->vertices.vi.pVertexAttributeDescriptions = demo->vertices.vi_attrs;
793
Courtney Goeltzenleuchterf5cdad02015-03-31 16:36:30 -0600794 demo->vertices.vi_bindings[0].binding = VERTEX_BUFFER_BIND_ID;
Chia-I Wu8d29d022014-10-08 12:14:39 +0800795 demo->vertices.vi_bindings[0].strideInBytes = sizeof(vb[0]);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600796 demo->vertices.vi_bindings[0].stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX;
Chia-I Wu8d29d022014-10-08 12:14:39 +0800797
Courtney Goeltzenleuchterf5cdad02015-03-31 16:36:30 -0600798 demo->vertices.vi_attrs[0].binding = VERTEX_BUFFER_BIND_ID;
799 demo->vertices.vi_attrs[0].location = 0;
Tony Barbour8205d902015-04-16 15:59:00 -0600800 demo->vertices.vi_attrs[0].format = VK_FORMAT_R32G32B32_SFLOAT;
Chia-I Wu8d29d022014-10-08 12:14:39 +0800801 demo->vertices.vi_attrs[0].offsetInBytes = 0;
802
Courtney Goeltzenleuchterf5cdad02015-03-31 16:36:30 -0600803 demo->vertices.vi_attrs[1].binding = VERTEX_BUFFER_BIND_ID;
804 demo->vertices.vi_attrs[1].location = 1;
Tony Barbour8205d902015-04-16 15:59:00 -0600805 demo->vertices.vi_attrs[1].format = VK_FORMAT_R32G32_SFLOAT;
Chia-I Wu8d29d022014-10-08 12:14:39 +0800806 demo->vertices.vi_attrs[1].offsetInBytes = sizeof(float) * 3;
Chia-I Wu99621bc2014-10-08 11:52:22 +0800807}
808
Chia-I Wuf8385062015-01-04 16:27:24 +0800809static void demo_prepare_descriptor_layout(struct demo *demo)
Chia-I Wub043fe32014-10-06 15:30:33 +0800810{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600811 const VkDescriptorSetLayoutBinding layout_binding = {
Courtney Goeltzenleuchterad870812015-04-15 15:29:59 -0600812 .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
Chia-I Wud3114a22015-05-25 16:22:52 +0800813 .arraySize = DEMO_TEXTURE_COUNT,
Tony Barbour8205d902015-04-16 15:59:00 -0600814 .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
Chia-I Wu310eece2015-03-27 12:56:09 +0800815 .pImmutableSamplers = NULL,
Chia-I Wub043fe32014-10-06 15:30:33 +0800816 };
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600817 const VkDescriptorSetLayoutCreateInfo descriptor_layout = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600818 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
Chia-I Wufc9d9132015-03-26 15:04:41 +0800819 .pNext = NULL,
820 .count = 1,
821 .pBinding = &layout_binding,
822 };
Tony Barbour22a30862015-04-22 09:02:32 -0600823 VkResult U_ASSERT_ONLY err;
Chia-I Wub043fe32014-10-06 15:30:33 +0800824
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600825 err = vkCreateDescriptorSetLayout(demo->device,
Chia-I Wu7732cb22015-03-26 15:27:55 +0800826 &descriptor_layout, &demo->desc_layout);
827 assert(!err);
828
Mark Lobodzinski556f7212015-04-17 14:11:39 -0500829 const VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = {
830 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
831 .pNext = NULL,
832 .descriptorSetCount = 1,
833 .pSetLayouts = &demo->desc_layout,
834 };
835
836 err = vkCreatePipelineLayout(demo->device,
837 &pPipelineLayoutCreateInfo,
838 &demo->pipeline_layout);
Chia-I Wub043fe32014-10-06 15:30:33 +0800839 assert(!err);
Chia-I Wub043fe32014-10-06 15:30:33 +0800840}
841
Chia-I Wu76cd4222015-07-08 13:34:24 +0800842static void demo_prepare_render_pass(struct demo *demo)
843{
Chia-I Wuc278df82015-07-07 11:50:03 +0800844 const VkAttachmentDescription attachments[2] = {
845 [0] = {
846 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION,
847 .pNext = NULL,
848 .format = demo->format,
849 .samples = 1,
850 .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
851 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
852 .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
853 .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
854 .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
855 .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
856 },
857 [1] = {
858 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION,
859 .pNext = NULL,
860 .format = demo->depth.format,
861 .samples = 1,
862 .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
863 .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
864 .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
865 .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
866 .initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
867 .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
868 },
Chia-I Wu76cd4222015-07-08 13:34:24 +0800869 };
Chia-I Wuc278df82015-07-07 11:50:03 +0800870 const VkAttachmentReference color_reference = {
871 .attachment = 0,
872 .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
873 };
874 const VkSubpassDescription subpass = {
875 .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION,
876 .pNext = NULL,
877 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
878 .flags = 0,
879 .inputCount = 0,
880 .inputAttachments = NULL,
881 .colorCount = 1,
882 .colorAttachments = &color_reference,
883 .resolveAttachments = NULL,
884 .depthStencilAttachment = {
885 .attachment = 1,
886 .layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
887 },
888 .preserveCount = 0,
889 .preserveAttachments = NULL,
890 };
Chia-I Wu76cd4222015-07-08 13:34:24 +0800891 const VkRenderPassCreateInfo rp_info = {
892 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
893 .pNext = NULL,
Chia-I Wuc278df82015-07-07 11:50:03 +0800894 .attachmentCount = 2,
895 .pAttachments = attachments,
896 .subpassCount = 1,
897 .pSubpasses = &subpass,
898 .dependencyCount = 0,
899 .pDependencies = NULL,
Chia-I Wu76cd4222015-07-08 13:34:24 +0800900 };
Chia-I Wuc278df82015-07-07 11:50:03 +0800901 VkResult U_ASSERT_ONLY err;
Chia-I Wu76cd4222015-07-08 13:34:24 +0800902
903 err = vkCreateRenderPass(demo->device, &rp_info, &demo->render_pass);
904 assert(!err);
905}
906
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600907static VkShader demo_prepare_shader(struct demo *demo,
Tony Barbour8205d902015-04-16 15:59:00 -0600908 VkShaderStage stage,
Chia-I Wuc19795a2014-09-13 11:12:55 +0800909 const void *code,
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600910 size_t size)
Chia-I Wuc19795a2014-09-13 11:12:55 +0800911{
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -0600912 VkShaderModuleCreateInfo moduleCreateInfo;
913 VkShaderCreateInfo shaderCreateInfo;
914 VkShaderModule shaderModule;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600915 VkShader shader;
916 VkResult err;
Chia-I Wuc19795a2014-09-13 11:12:55 +0800917
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -0600918
919 moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
920 moduleCreateInfo.pNext = NULL;
921
922 shaderCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO;
923 shaderCreateInfo.pNext = NULL;
Courtney Goeltzenleuchter3f2606d2014-10-13 17:51:58 -0600924
Cody Northrop75db0322015-05-28 11:27:16 -0600925 if (!demo->use_glsl) {
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -0600926 moduleCreateInfo.codeSize = size;
927 moduleCreateInfo.pCode = code;
928 moduleCreateInfo.flags = 0;
929 err = vkCreateShaderModule(demo->device, &moduleCreateInfo, &shaderModule);
930 if (err) {
931 free((void *) moduleCreateInfo.pCode);
932 }
Courtney Goeltzenleuchter3f2606d2014-10-13 17:51:58 -0600933
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -0600934 shaderCreateInfo.flags = 0;
935 shaderCreateInfo.module = shaderModule;
936 err = vkCreateShader(demo->device, &shaderCreateInfo, &shader);
Cody Northrop75db0322015-05-28 11:27:16 -0600937 } else {
938 // Create fake SPV structure to feed GLSL
939 // to the driver "under the covers"
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -0600940 moduleCreateInfo.codeSize = 3 * sizeof(uint32_t) + size + 1;
941 moduleCreateInfo.pCode = malloc(moduleCreateInfo.codeSize);
942 moduleCreateInfo.flags = 0;
Courtney Goeltzenleuchter3f2606d2014-10-13 17:51:58 -0600943
Cody Northrop75db0322015-05-28 11:27:16 -0600944 /* try version 0 first: VkShaderStage followed by GLSL */
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -0600945 ((uint32_t *) moduleCreateInfo.pCode)[0] = ICD_SPV_MAGIC;
946 ((uint32_t *) moduleCreateInfo.pCode)[1] = 0;
947 ((uint32_t *) moduleCreateInfo.pCode)[2] = stage;
948 memcpy(((uint32_t *) moduleCreateInfo.pCode + 3), code, size + 1);
Cody Northrop75db0322015-05-28 11:27:16 -0600949
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -0600950 err = vkCreateShaderModule(demo->device, &moduleCreateInfo, &shaderModule);
Cody Northrop75db0322015-05-28 11:27:16 -0600951 if (err) {
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -0600952 free((void *) moduleCreateInfo.pCode);
Cody Northrop75db0322015-05-28 11:27:16 -0600953 }
Chia-I Wuc19795a2014-09-13 11:12:55 +0800954
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -0600955 shaderCreateInfo.flags = 0;
956 shaderCreateInfo.module = shaderModule;
957 err = vkCreateShader(demo->device, &shaderCreateInfo, &shader);
958 }
Chia-I Wuc19795a2014-09-13 11:12:55 +0800959 return shader;
960}
961
Cody Northrop75db0322015-05-28 11:27:16 -0600962char *demo_read_spv(const char *filename, size_t *psize)
963{
964 long int size;
965 void *shader_code;
966
967 FILE *fp = fopen(filename, "rb");
968 if (!fp) return NULL;
969
970 fseek(fp, 0L, SEEK_END);
971 size = ftell(fp);
972
973 fseek(fp, 0L, SEEK_SET);
974
975 shader_code = malloc(size);
976 fread(shader_code, size, 1, fp);
977
978 *psize = size;
979
980 return shader_code;
981}
982
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600983static VkShader demo_prepare_vs(struct demo *demo)
Chia-I Wuc19795a2014-09-13 11:12:55 +0800984{
Cody Northrop75db0322015-05-28 11:27:16 -0600985 if (!demo->use_glsl) {
986 void *vertShaderCode;
987 size_t size;
988
989 vertShaderCode = demo_read_spv("tri-vert.spv", &size);
990
991 return demo_prepare_shader(demo, VK_SHADER_STAGE_VERTEX,
992 vertShaderCode, size);
993 } else {
994 static const char *vertShaderText =
Mark Lobodzinskiba4d2f02015-04-06 15:24:40 -0500995 "#version 140\n"
Courtney Goeltzenleuchterf5cdad02015-03-31 16:36:30 -0600996 "#extension GL_ARB_separate_shader_objects : enable\n"
997 "#extension GL_ARB_shading_language_420pack : enable\n"
998 "layout (location = 0) in vec4 pos;\n"
999 "layout (location = 1) in vec2 attr;\n"
Chia-I Wuf5caeb02014-10-25 12:11:27 +08001000 "out vec2 texcoord;\n"
Courtney Goeltzenleuchter3f2606d2014-10-13 17:51:58 -06001001 "void main() {\n"
Chia-I Wuf5caeb02014-10-25 12:11:27 +08001002 " texcoord = attr;\n"
1003 " gl_Position = pos;\n"
Courtney Goeltzenleuchter3f2606d2014-10-13 17:51:58 -06001004 "}\n";
Courtney Goeltzenleuchteref7301b2014-09-17 13:17:12 -06001005
Cody Northrop75db0322015-05-28 11:27:16 -06001006 return demo_prepare_shader(demo, VK_SHADER_STAGE_VERTEX,
1007 (const void *) vertShaderText,
1008 strlen(vertShaderText));
1009 }
Chia-I Wuc19795a2014-09-13 11:12:55 +08001010}
1011
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001012static VkShader demo_prepare_fs(struct demo *demo)
Chia-I Wuc19795a2014-09-13 11:12:55 +08001013{
Cody Northrop75db0322015-05-28 11:27:16 -06001014 if (!demo->use_glsl) {
1015 void *fragShaderCode;
1016 size_t size;
Courtney Goeltzenleuchteref7301b2014-09-17 13:17:12 -06001017
Cody Northrop75db0322015-05-28 11:27:16 -06001018 fragShaderCode = demo_read_spv("tri-frag.spv", &size);
1019
1020 return demo_prepare_shader(demo, VK_SHADER_STAGE_FRAGMENT,
1021 fragShaderCode, size);
1022 } else {
1023 static const char *fragShaderText =
1024 "#version 140\n"
1025 "#extension GL_ARB_separate_shader_objects : enable\n"
1026 "#extension GL_ARB_shading_language_420pack : enable\n"
1027 "layout (binding = 0) uniform sampler2D tex;\n"
1028 "layout (location = 0) in vec2 texcoord;\n"
1029 "layout (location = 0) out vec4 uFragColor;\n"
1030 "void main() {\n"
1031 " uFragColor = texture(tex, texcoord);\n"
1032 "}\n";
1033
1034 return demo_prepare_shader(demo, VK_SHADER_STAGE_FRAGMENT,
1035 (const void *) fragShaderText,
1036 strlen(fragShaderText));
1037 }
Chia-I Wuc19795a2014-09-13 11:12:55 +08001038}
1039
1040static void demo_prepare_pipeline(struct demo *demo)
1041{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001042 VkGraphicsPipelineCreateInfo pipeline;
Jon Ashburn0d60d272015-07-09 15:02:25 -06001043 VkPipelineCacheCreateInfo pipelineCache;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001044
1045 VkPipelineVertexInputStateCreateInfo vi;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001046 VkPipelineIaStateCreateInfo ia;
1047 VkPipelineRsStateCreateInfo rs;
1048 VkPipelineCbStateCreateInfo cb;
1049 VkPipelineDsStateCreateInfo ds;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001050 VkPipelineVpStateCreateInfo vp;
1051 VkPipelineMsStateCreateInfo ms;
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001052
Tony Barbour22a30862015-04-22 09:02:32 -06001053 VkResult U_ASSERT_ONLY err;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001054
1055 memset(&pipeline, 0, sizeof(pipeline));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001056 pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
Mark Lobodzinski556f7212015-04-17 14:11:39 -05001057 pipeline.layout = demo->pipeline_layout;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001058
Chia-I Wu8d29d022014-10-08 12:14:39 +08001059 vi = demo->vertices.vi;
1060
Chia-I Wuc19795a2014-09-13 11:12:55 +08001061 memset(&ia, 0, sizeof(ia));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001062 ia.sType = VK_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO;
Tony Barbour8205d902015-04-16 15:59:00 -06001063 ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001064
1065 memset(&rs, 0, sizeof(rs));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001066 rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO;
Tony Barbour8205d902015-04-16 15:59:00 -06001067 rs.fillMode = VK_FILL_MODE_SOLID;
Chia-I Wuc414ba82015-04-22 15:44:24 +08001068 rs.cullMode = VK_CULL_MODE_BACK;
1069 rs.frontFace = VK_FRONT_FACE_CW;
Chia-I Wue2504cb2015-04-22 14:20:52 +08001070 rs.depthClipEnable = VK_TRUE;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001071
1072 memset(&cb, 0, sizeof(cb));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001073 cb.sType = VK_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001074 VkPipelineCbAttachmentState att_state[1];
Tony Barbourfa6cac72015-01-16 14:27:35 -07001075 memset(att_state, 0, sizeof(att_state));
Tony Barbourfa6cac72015-01-16 14:27:35 -07001076 att_state[0].channelWriteMask = 0xf;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001077 att_state[0].blendEnable = VK_FALSE;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001078 cb.attachmentCount = 1;
1079 cb.pAttachments = att_state;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001080
Tony Barbourfa6cac72015-01-16 14:27:35 -07001081 memset(&vp, 0, sizeof(vp));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001082 vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VP_STATE_CREATE_INFO;
Tony Barbour8205d902015-04-16 15:59:00 -06001083 vp.viewportCount = 1;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001084 vp.clipOrigin = VK_COORDINATE_ORIGIN_UPPER_LEFT;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001085
1086 memset(&ds, 0, sizeof(ds));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001087 ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001088 ds.depthTestEnable = VK_TRUE;
1089 ds.depthWriteEnable = VK_TRUE;
Tony Barbour8205d902015-04-16 15:59:00 -06001090 ds.depthCompareOp = VK_COMPARE_OP_LESS_EQUAL;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001091 ds.depthBoundsEnable = VK_FALSE;
1092 ds.back.stencilFailOp = VK_STENCIL_OP_KEEP;
1093 ds.back.stencilPassOp = VK_STENCIL_OP_KEEP;
Tony Barbour8205d902015-04-16 15:59:00 -06001094 ds.back.stencilCompareOp = VK_COMPARE_OP_ALWAYS;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001095 ds.stencilTestEnable = VK_FALSE;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001096 ds.front = ds.back;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001097
Tony Barbourfa6cac72015-01-16 14:27:35 -07001098 memset(&ms, 0, sizeof(ms));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001099 ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001100 ms.sampleMask = 1;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001101 ms.multisampleEnable = VK_FALSE;
Tony Barboure094edf2015-06-26 10:18:34 -06001102 ms.rasterSamples = 1;
Chia-I Wub043fe32014-10-06 15:30:33 +08001103
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001104 // Two stages: vs and fs
1105 pipeline.stageCount = 2;
1106 VkPipelineShaderStageCreateInfo shaderStages[2];
1107 memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
1108
1109 shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
1110 shaderStages[0].stage = VK_SHADER_STAGE_VERTEX;
1111 shaderStages[0].shader = demo_prepare_vs(demo);
1112 shaderStages[0].linkConstBufferCount = 0;
1113
1114 shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
1115 shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT;
1116 shaderStages[1].shader = demo_prepare_fs(demo);
1117
1118 pipeline.pVertexInputState = &vi;
1119 pipeline.pIaState = &ia;
1120 pipeline.pRsState = &rs;
1121 pipeline.pCbState = &cb;
1122 pipeline.pMsState = &ms;
1123 pipeline.pVpState = &vp;
1124 pipeline.pDsState = &ds;
1125 pipeline.pStages = shaderStages;
Chia-I Wuc278df82015-07-07 11:50:03 +08001126 pipeline.renderPass = demo->render_pass;
1127 pipeline.subpass = 0;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001128
Jon Ashburn0d60d272015-07-09 15:02:25 -06001129 memset(&pipelineCache, 0, sizeof(pipelineCache));
1130 pipelineCache.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
1131
1132 err = vkCreatePipelineCache(demo->device, &pipelineCache, &demo->pipelineCache);
1133 assert(!err);
1134 err = vkCreateGraphicsPipelines(demo->device, demo->pipelineCache, 1, &pipeline, &demo->pipeline);
Chia-I Wuc19795a2014-09-13 11:12:55 +08001135 assert(!err);
1136
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001137 for (uint32_t i = 0; i < pipeline.stageCount; i++) {
Tony Barbourde4124d2015-07-03 10:33:54 -06001138 vkDestroyShader(demo->device, shaderStages[i].shader);
Mark Lobodzinski0e0fb5c2015-06-23 15:11:57 -06001139 }
Chia-I Wuc19795a2014-09-13 11:12:55 +08001140}
1141
1142static void demo_prepare_dynamic_states(struct demo *demo)
1143{
Tony Barbourde4124d2015-07-03 10:33:54 -06001144 VkDynamicViewportStateCreateInfo viewport_create;
1145 VkDynamicRasterStateCreateInfo raster;
1146 VkDynamicColorBlendStateCreateInfo color_blend;
1147 VkDynamicDepthStencilStateCreateInfo depth_stencil;
Tony Barbour22a30862015-04-22 09:02:32 -06001148 VkResult U_ASSERT_ONLY err;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001149
Tony Barbourfa6cac72015-01-16 14:27:35 -07001150 memset(&viewport_create, 0, sizeof(viewport_create));
Tony Barbourde4124d2015-07-03 10:33:54 -06001151 viewport_create.sType = VK_STRUCTURE_TYPE_DYNAMIC_VIEWPORT_STATE_CREATE_INFO;
Courtney Goeltzenleuchterc6e32f92015-02-11 14:13:34 -07001152 viewport_create.viewportAndScissorCount = 1;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001153 VkViewport viewport;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001154 memset(&viewport, 0, sizeof(viewport));
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001155 viewport.height = (float) demo->height;
Courtney Goeltzenleuchterc6e32f92015-02-11 14:13:34 -07001156 viewport.width = (float) demo->width;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001157 viewport.minDepth = (float) 0.0f;
1158 viewport.maxDepth = (float) 1.0f;
Piers Daniell886be472015-02-23 16:23:13 -07001159 viewport_create.pViewports = &viewport;
Chris Forbes2951d7d2015-06-22 17:21:59 +12001160 VkRect2D scissor;
Piers Daniell886be472015-02-23 16:23:13 -07001161 memset(&scissor, 0, sizeof(scissor));
Courtney Goeltzenleuchterc6e32f92015-02-11 14:13:34 -07001162 scissor.extent.width = demo->width;
1163 scissor.extent.height = demo->height;
1164 scissor.offset.x = 0;
1165 scissor.offset.y = 0;
Courtney Goeltzenleuchterc6e32f92015-02-11 14:13:34 -07001166 viewport_create.pScissors = &scissor;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001167
1168 memset(&raster, 0, sizeof(raster));
Tony Barbourde4124d2015-07-03 10:33:54 -06001169 raster.sType = VK_STRUCTURE_TYPE_DYNAMIC_RASTER_STATE_CREATE_INFO;
Piers Daniell886be472015-02-23 16:23:13 -07001170 raster.lineWidth = 1.0;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001171
1172 memset(&color_blend, 0, sizeof(color_blend));
Tony Barbourde4124d2015-07-03 10:33:54 -06001173 color_blend.sType = VK_STRUCTURE_TYPE_DYNAMIC_COLOR_BLEND_STATE_CREATE_INFO;
Piers Daniell886be472015-02-23 16:23:13 -07001174 color_blend.blendConst[0] = 1.0f;
1175 color_blend.blendConst[1] = 1.0f;
1176 color_blend.blendConst[2] = 1.0f;
1177 color_blend.blendConst[3] = 1.0f;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001178
1179 memset(&depth_stencil, 0, sizeof(depth_stencil));
Tony Barbourde4124d2015-07-03 10:33:54 -06001180 depth_stencil.sType = VK_STRUCTURE_TYPE_DYNAMIC_DEPTH_STENCIL_STATE_CREATE_INFO;
Mark Lobodzinski4405fbf2015-06-12 11:14:17 -06001181 depth_stencil.minDepthBounds = 0.0f;
1182 depth_stencil.maxDepthBounds = 1.0f;
Tony Barbourfa6cac72015-01-16 14:27:35 -07001183 depth_stencil.stencilBackRef = 0;
1184 depth_stencil.stencilFrontRef = 0;
1185 depth_stencil.stencilReadMask = 0xff;
1186 depth_stencil.stencilWriteMask = 0xff;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001187
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001188 err = vkCreateDynamicViewportState(demo->device, &viewport_create, &demo->viewport);
Chia-I Wuc19795a2014-09-13 11:12:55 +08001189 assert(!err);
1190
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001191 err = vkCreateDynamicRasterState(demo->device, &raster, &demo->raster);
Chia-I Wuc19795a2014-09-13 11:12:55 +08001192 assert(!err);
1193
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001194 err = vkCreateDynamicColorBlendState(demo->device,
Chia-I Wuc19795a2014-09-13 11:12:55 +08001195 &color_blend, &demo->color_blend);
1196 assert(!err);
1197
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001198 err = vkCreateDynamicDepthStencilState(demo->device,
Chia-I Wuc19795a2014-09-13 11:12:55 +08001199 &depth_stencil, &demo->depth_stencil);
1200 assert(!err);
1201}
1202
Chia-I Wu8d24b3b2015-03-26 13:14:16 +08001203static void demo_prepare_descriptor_pool(struct demo *demo)
Chia-I Wuf8385062015-01-04 16:27:24 +08001204{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001205 const VkDescriptorTypeCount type_count = {
Courtney Goeltzenleuchterad870812015-04-15 15:29:59 -06001206 .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
Chia-I Wuf8385062015-01-04 16:27:24 +08001207 .count = DEMO_TEXTURE_COUNT,
1208 };
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001209 const VkDescriptorPoolCreateInfo descriptor_pool = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001210 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
Chia-I Wuf8385062015-01-04 16:27:24 +08001211 .pNext = NULL,
1212 .count = 1,
1213 .pTypeCount = &type_count,
1214 };
Tony Barbour22a30862015-04-22 09:02:32 -06001215 VkResult U_ASSERT_ONLY err;
Chia-I Wuf8385062015-01-04 16:27:24 +08001216
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001217 err = vkCreateDescriptorPool(demo->device,
1218 VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1,
Chia-I Wu8d24b3b2015-03-26 13:14:16 +08001219 &descriptor_pool, &demo->desc_pool);
Chia-I Wuf8385062015-01-04 16:27:24 +08001220 assert(!err);
1221}
1222
1223static void demo_prepare_descriptor_set(struct demo *demo)
1224{
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001225 VkDescriptorInfo tex_descs[DEMO_TEXTURE_COUNT];
1226 VkWriteDescriptorSet write;
Tony Barbour22a30862015-04-22 09:02:32 -06001227 VkResult U_ASSERT_ONLY err;
Chia-I Wuf8385062015-01-04 16:27:24 +08001228 uint32_t count;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001229 uint32_t i;
Chia-I Wuf8385062015-01-04 16:27:24 +08001230
Mike Stroyan230e6252015-04-17 12:36:38 -06001231 err = vkAllocDescriptorSets(demo->device, demo->desc_pool,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001232 VK_DESCRIPTOR_SET_USAGE_STATIC,
Chia-I Wuf8385062015-01-04 16:27:24 +08001233 1, &demo->desc_layout,
1234 &demo->desc_set, &count);
1235 assert(!err && count == 1);
1236
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +08001237 memset(&tex_descs, 0, sizeof(tex_descs));
1238 for (i = 0; i < DEMO_TEXTURE_COUNT; i++) {
1239 tex_descs[i].sampler = demo->textures[i].sampler;
1240 tex_descs[i].imageView = demo->textures[i].view;
1241 tex_descs[i].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
1242 }
1243
1244 memset(&write, 0, sizeof(write));
1245 write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1246 write.destSet = demo->desc_set;
1247 write.count = DEMO_TEXTURE_COUNT;
1248 write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1249 write.pDescriptors = tex_descs;
1250
1251 err = vkUpdateDescriptorSets(demo->device, 1, &write, 0, NULL);
1252 assert(!err);
Chia-I Wuf8385062015-01-04 16:27:24 +08001253}
1254
Chia-I Wu76cd4222015-07-08 13:34:24 +08001255static void demo_prepare_framebuffers(struct demo *demo)
1256{
Chia-I Wuc278df82015-07-07 11:50:03 +08001257 VkAttachmentBindInfo attachments[2] = {
1258 [0] = {
Tony Barbourde4124d2015-07-03 10:33:54 -06001259 .view.handle = VK_NULL_HANDLE,
Chia-I Wuc278df82015-07-07 11:50:03 +08001260 .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1261 },
1262 [1] = {
1263 .view = demo->depth.view,
1264 .layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1265 },
Chia-I Wu76cd4222015-07-08 13:34:24 +08001266 };
1267 const VkFramebufferCreateInfo fb_info = {
1268 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
1269 .pNext = NULL,
Chia-I Wuc278df82015-07-07 11:50:03 +08001270 .renderPass = demo->render_pass,
1271 .attachmentCount = 2,
1272 .pAttachments = attachments,
Chia-I Wu76cd4222015-07-08 13:34:24 +08001273 .width = demo->width,
1274 .height = demo->height,
1275 .layers = 1,
1276 };
1277 VkResult U_ASSERT_ONLY err;
1278 uint32_t i;
1279
1280 for (i = 0; i < DEMO_BUFFER_COUNT; i++) {
Chia-I Wuc278df82015-07-07 11:50:03 +08001281 attachments[0].view = demo->buffers[i].view;
Chia-I Wu76cd4222015-07-08 13:34:24 +08001282 err = vkCreateFramebuffer(demo->device, &fb_info, &demo->framebuffers[i]);
1283 assert(!err);
1284 }
1285}
1286
Chia-I Wuc19795a2014-09-13 11:12:55 +08001287static void demo_prepare(struct demo *demo)
1288{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001289 const VkCmdBufferCreateInfo cmd = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001290 .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
Chia-I Wuc19795a2014-09-13 11:12:55 +08001291 .pNext = NULL,
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -07001292 .queueNodeIndex = demo->graphics_queue_node_index,
Chia-I Wu88eaa3b2015-06-26 15:34:39 +08001293 .level = VK_CMD_BUFFER_LEVEL_PRIMARY,
Chia-I Wuc19795a2014-09-13 11:12:55 +08001294 .flags = 0,
1295 };
Tony Barbour22a30862015-04-22 09:02:32 -06001296 VkResult U_ASSERT_ONLY err;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001297
Courtney Goeltzenleuchter633f9c52015-04-30 10:58:33 -06001298 err = vkCreateCommandBuffer(demo->device, &cmd, &demo->draw_cmd);
1299 assert(!err);
1300
Chia-I Wuc19795a2014-09-13 11:12:55 +08001301 demo_prepare_buffers(demo);
Chia-I Wu9ae87c92014-10-07 14:15:01 +08001302 demo_prepare_depth(demo);
Chia-I Wub043fe32014-10-06 15:30:33 +08001303 demo_prepare_textures(demo);
Chia-I Wu99621bc2014-10-08 11:52:22 +08001304 demo_prepare_vertices(demo);
Chia-I Wuf8385062015-01-04 16:27:24 +08001305 demo_prepare_descriptor_layout(demo);
Chia-I Wu76cd4222015-07-08 13:34:24 +08001306 demo_prepare_render_pass(demo);
Chia-I Wuc19795a2014-09-13 11:12:55 +08001307 demo_prepare_pipeline(demo);
1308 demo_prepare_dynamic_states(demo);
1309
Chia-I Wu8d24b3b2015-03-26 13:14:16 +08001310 demo_prepare_descriptor_pool(demo);
Chia-I Wuf8385062015-01-04 16:27:24 +08001311 demo_prepare_descriptor_set(demo);
Chia-I Wu76cd4222015-07-08 13:34:24 +08001312
1313 demo_prepare_framebuffers(demo);
1314
Courtney Goeltzenleuchter633f9c52015-04-30 10:58:33 -06001315 demo->prepared = true;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001316}
1317
Ian Elliotte14e9f92015-04-16 15:23:05 -06001318#ifdef _WIN32
1319static void demo_run(struct demo *demo)
1320{
Courtney Goeltzenleuchter633f9c52015-04-30 10:58:33 -06001321 if (!demo->prepared)
1322 return;
Ian Elliotte14e9f92015-04-16 15:23:05 -06001323 demo_draw(demo);
1324}
1325
1326// On MS-Windows, make this a global, so it's available to WndProc()
1327struct demo demo;
1328
1329// MS-Windows event handling function:
1330LRESULT CALLBACK WndProc(HWND hWnd,
1331 UINT uMsg,
1332 WPARAM wParam,
1333 LPARAM lParam)
1334{
Ian Elliott4e19ed02015-04-28 10:52:52 -06001335 char tmp_str[] = APP_LONG_NAME;
Ian Elliotte14e9f92015-04-16 15:23:05 -06001336
1337 switch(uMsg)
1338 {
1339 case WM_CREATE:
1340 return 0;
1341 case WM_CLOSE:
1342 PostQuitMessage(0);
1343 return 0;
1344 case WM_PAINT:
1345 demo_run(&demo);
1346 return 0;
1347 default:
1348 break;
1349 }
1350 return (DefWindowProc(hWnd, uMsg, wParam, lParam));
1351}
1352
1353static void demo_create_window(struct demo *demo)
1354{
1355 WNDCLASSEX win_class;
1356
1357 // Initialize the window class structure:
1358 win_class.cbSize = sizeof(WNDCLASSEX);
1359 win_class.style = CS_HREDRAW | CS_VREDRAW;
1360 win_class.lpfnWndProc = WndProc;
1361 win_class.cbClsExtra = 0;
1362 win_class.cbWndExtra = 0;
1363 win_class.hInstance = demo->connection; // hInstance
1364 win_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
1365 win_class.hCursor = LoadCursor(NULL, IDC_ARROW);
1366 win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
1367 win_class.lpszMenuName = NULL;
1368 win_class.lpszClassName = demo->name;
1369 win_class.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
1370 // Register window class:
1371 if (!RegisterClassEx(&win_class)) {
1372 // It didn't work, so try to give a useful error:
1373 printf("Unexpected error trying to start the application!\n");
1374 fflush(stdout);
1375 exit(1);
1376 }
1377 // Create window with the registered class:
Mike Stroyan7eef5742015-06-15 14:19:19 -06001378 RECT wr = { 0, 0, demo->width, demo->height };
1379 AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
Ian Elliotte14e9f92015-04-16 15:23:05 -06001380 demo->window = CreateWindowEx(0,
1381 demo->name, // class name
1382 demo->name, // app name
1383 WS_OVERLAPPEDWINDOW | // window style
1384 WS_VISIBLE |
1385 WS_SYSMENU,
1386 100,100, // x/y coords
Mike Stroyan7eef5742015-06-15 14:19:19 -06001387 wr.right-wr.left, // width
1388 wr.bottom-wr.top, // height
Ian Elliotte14e9f92015-04-16 15:23:05 -06001389 NULL, // handle to parent
1390 NULL, // handle to menu
1391 demo->connection, // hInstance
1392 NULL); // no extra parameters
1393 if (!demo->window) {
1394 // It didn't work, so try to give a useful error:
1395 printf("Cannot create a window in which to draw!\n");
1396 fflush(stdout);
1397 exit(1);
1398 }
1399}
1400#else // _WIN32
1401
Chia-I Wuc19795a2014-09-13 11:12:55 +08001402static void demo_handle_event(struct demo *demo,
1403 const xcb_generic_event_t *event)
1404{
1405 switch (event->response_type & 0x7f) {
1406 case XCB_EXPOSE:
1407 demo_draw(demo);
1408 break;
Courtney Goeltzenleuchterca698052014-11-07 15:17:03 -07001409 case XCB_CLIENT_MESSAGE:
1410 if((*(xcb_client_message_event_t*)event).data.data32[0] ==
1411 (*demo->atom_wm_delete_window).atom) {
1412 demo->quit = true;
1413 }
1414 break;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001415 case XCB_KEY_RELEASE:
1416 {
1417 const xcb_key_release_event_t *key =
1418 (const xcb_key_release_event_t *) event;
1419
1420 if (key->detail == 0x9)
1421 demo->quit = true;
1422 }
1423 break;
Courtney Goeltzenleuchterca698052014-11-07 15:17:03 -07001424 case XCB_DESTROY_NOTIFY:
1425 demo->quit = true;
1426 break;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001427 default:
1428 break;
1429 }
1430}
1431
1432static void demo_run(struct demo *demo)
1433{
1434 xcb_flush(demo->connection);
1435
1436 while (!demo->quit) {
1437 xcb_generic_event_t *event;
1438
1439 event = xcb_wait_for_event(demo->connection);
1440 if (event) {
1441 demo_handle_event(demo, event);
1442 free(event);
1443 }
1444 }
1445}
1446
1447static void demo_create_window(struct demo *demo)
1448{
1449 uint32_t value_mask, value_list[32];
1450
1451 demo->window = xcb_generate_id(demo->connection);
1452
1453 value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
1454 value_list[0] = demo->screen->black_pixel;
1455 value_list[1] = XCB_EVENT_MASK_KEY_RELEASE |
Courtney Goeltzenleuchterca698052014-11-07 15:17:03 -07001456 XCB_EVENT_MASK_EXPOSURE |
1457 XCB_EVENT_MASK_STRUCTURE_NOTIFY;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001458
1459 xcb_create_window(demo->connection,
1460 XCB_COPY_FROM_PARENT,
1461 demo->window, demo->screen->root,
1462 0, 0, demo->width, demo->height, 0,
1463 XCB_WINDOW_CLASS_INPUT_OUTPUT,
1464 demo->screen->root_visual,
1465 value_mask, value_list);
1466
Courtney Goeltzenleuchterca698052014-11-07 15:17:03 -07001467 /* Magic code that will send notification when window is destroyed */
1468 xcb_intern_atom_cookie_t cookie = xcb_intern_atom(demo->connection, 1, 12,
1469 "WM_PROTOCOLS");
1470 xcb_intern_atom_reply_t* reply = xcb_intern_atom_reply(demo->connection, cookie, 0);
1471
1472 xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(demo->connection, 0, 16, "WM_DELETE_WINDOW");
1473 demo->atom_wm_delete_window = xcb_intern_atom_reply(demo->connection, cookie2, 0);
1474
1475 xcb_change_property(demo->connection, XCB_PROP_MODE_REPLACE,
1476 demo->window, (*reply).atom, 4, 32, 1,
1477 &(*demo->atom_wm_delete_window).atom);
1478 free(reply);
1479
Chia-I Wuc19795a2014-09-13 11:12:55 +08001480 xcb_map_window(demo->connection, demo->window);
1481}
Ian Elliotte14e9f92015-04-16 15:23:05 -06001482#endif // _WIN32
Chia-I Wuc19795a2014-09-13 11:12:55 +08001483
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001484static void demo_init_vk(struct demo *demo)
Chia-I Wuc19795a2014-09-13 11:12:55 +08001485{
Tobin Ehlis3536b442015-04-16 18:04:57 -06001486 VkResult err;
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001487 char *extension_names[64];
1488 char *layer_names[64];
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001489 VkExtensionProperties *instance_extensions;
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001490 VkLayerProperties *instance_layers;
1491 VkLayerProperties *device_layers;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001492 uint32_t instance_extension_count = 0;
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001493 uint32_t instance_layer_count = 0;
1494 uint32_t enabled_extension_count = 0;
1495 uint32_t enabled_layer_count = 0;
1496
1497 /* Look for validation layers */
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -06001498 VkBool32 validation_found = 0;
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001499 err = vkGetGlobalLayerProperties(&instance_layer_count, NULL);
Tobin Ehlis3536b442015-04-16 18:04:57 -06001500 assert(!err);
1501
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001502 memset(layer_names, 0, sizeof(layer_names));
1503 instance_layers = malloc(sizeof(VkLayerProperties) * instance_layer_count);
1504 err = vkGetGlobalLayerProperties(&instance_layer_count, instance_layers);
1505 assert(!err);
1506 for (uint32_t i = 0; i < instance_layer_count; i++) {
1507 if (!validation_found && demo->validate && !strcmp("Validation", instance_layers[i].layerName)) {
1508 layer_names[enabled_layer_count++] = "Validation";
1509 validation_found = 1;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001510 }
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001511 assert(enabled_layer_count < 64);
1512 }
1513 if (demo->validate && !validation_found) {
1514 ERR_EXIT("vkGetGlobalLayerProperties failed to find any "
1515 "\"Validation\" layers.\n\n"
1516 "Please look at the Getting Started guide for additional "
1517 "information.\n",
1518 "vkCreateInstance Failure");
1519 }
1520
1521 err = vkGetGlobalExtensionProperties(NULL, &instance_extension_count, NULL);
1522 assert(!err);
1523
Courtney Goeltzenleuchter1f41f542015-07-09 11:44:38 -06001524 VkBool32 WSIextFound = 0;
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001525 memset(extension_names, 0, sizeof(extension_names));
1526 instance_extensions = malloc(sizeof(VkExtensionProperties) * instance_extension_count);
1527 err = vkGetGlobalExtensionProperties(NULL, &instance_extension_count, instance_extensions);
1528 assert(!err);
1529 for (uint32_t i = 0; i < instance_extension_count; i++) {
1530 if (!strcmp(VK_WSI_LUNARG_EXTENSION_NAME, instance_extensions[i].extName)) {
1531 WSIextFound = 1;
1532 extension_names[enabled_extension_count++] = VK_WSI_LUNARG_EXTENSION_NAME;
1533 }
1534 if (!strcmp(DEBUG_REPORT_EXTENSION_NAME, instance_extensions[i].extName)) {
1535 if (demo->validate) {
1536 extension_names[enabled_extension_count++] = DEBUG_REPORT_EXTENSION_NAME;
1537 }
1538 }
1539 assert(enabled_extension_count < 64);
Tobin Ehlis3536b442015-04-16 18:04:57 -06001540 }
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -06001541 if (!WSIextFound) {
Tony Barbour426b9052015-06-24 16:06:58 -06001542 ERR_EXIT("vkGetGlobalExtensionProperties failed to find the "
Ian Elliott3b375cf2015-04-28 13:22:33 -06001543 "\"VK_WSI_LunarG\" extension.\n\nDo you have a compatible "
1544 "Vulkan installable client driver (ICD) installed?\nPlease "
1545 "look at the Getting Started guide for additional "
1546 "information.\n",
1547 "vkCreateInstance Failure");
1548 }
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -06001549 const VkApplicationInfo app = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001550 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
Chia-I Wuc19795a2014-09-13 11:12:55 +08001551 .pNext = NULL,
Ian Elliott4e19ed02015-04-28 10:52:52 -06001552 .pAppName = APP_SHORT_NAME,
Chia-I Wuc19795a2014-09-13 11:12:55 +08001553 .appVersion = 0,
Ian Elliott4e19ed02015-04-28 10:52:52 -06001554 .pEngineName = APP_SHORT_NAME,
Chia-I Wuc19795a2014-09-13 11:12:55 +08001555 .engineVersion = 0,
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001556 .apiVersion = VK_API_VERSION,
Chia-I Wuc19795a2014-09-13 11:12:55 +08001557 };
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001558 VkInstanceCreateInfo inst_info = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001559 .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
Jon Ashburn29669a42015-04-04 14:52:07 -06001560 .pNext = NULL,
1561 .pAppInfo = &app,
1562 .pAllocCb = NULL,
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001563 .layerCount = enabled_layer_count,
1564 .ppEnabledLayerNames = (const char *const*) layer_names,
1565 .extensionCount = enabled_extension_count,
1566 .ppEnabledExtensionNames = (const char *const*) extension_names,
Jon Ashburn29669a42015-04-04 14:52:07 -06001567 };
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -06001568 const VkDeviceQueueCreateInfo queue = {
Chia-I Wuc19795a2014-09-13 11:12:55 +08001569 .queueNodeIndex = 0,
1570 .queueCount = 1,
1571 };
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001572
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -06001573 uint32_t gpu_count;
1574 uint32_t i;
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -07001575 uint32_t queue_count;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001576
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001577 err = vkCreateInstance(&inst_info, &demo->inst);
Ian Elliottcaa9f272015-04-28 11:35:02 -06001578 if (err == VK_ERROR_INCOMPATIBLE_DRIVER) {
1579 ERR_EXIT("Cannot find a compatible Vulkan installable client driver "
Ian Elliott3b375cf2015-04-28 13:22:33 -06001580 "(ICD).\n\nPlease look at the Getting Started guide for "
Ian Elliottcaa9f272015-04-28 11:35:02 -06001581 "additional information.\n",
1582 "vkCreateInstance Failure");
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001583 } else if (err == VK_ERROR_INVALID_EXTENSION) {
1584 ERR_EXIT("Cannot find a specified extension library"
1585 ".\nMake sure your layers path is set appropriately\n",
1586 "vkCreateInstance Failure");
Ian Elliottcaa9f272015-04-28 11:35:02 -06001587 } else if (err) {
Ian Elliott3b375cf2015-04-28 13:22:33 -06001588 ERR_EXIT("vkCreateInstance failed.\n\nDo you have a compatible Vulkan "
1589 "installable client driver (ICD) installed?\nPlease look at "
Ian Elliottcaa9f272015-04-28 11:35:02 -06001590 "the Getting Started guide for additional information.\n",
1591 "vkCreateInstance Failure");
Ian Elliottdfe55f72015-04-03 15:24:55 -06001592 }
Jon Ashburn29669a42015-04-04 14:52:07 -06001593
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001594 free(instance_layers);
1595 free(instance_extensions);
1596
Jon Ashburn07b309a2015-04-15 11:31:12 -06001597 gpu_count = 1;
1598 err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, &demo->gpu);
Chia-I Wuc19795a2014-09-13 11:12:55 +08001599 assert(!err && gpu_count == 1);
1600
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001601 /* Look for validation layers */
1602 validation_found = 0;
1603 enabled_layer_count = 0;
1604 uint32_t device_layer_count = 0;
1605 err = vkGetPhysicalDeviceLayerProperties(demo->gpu, &device_layer_count, NULL);
1606 assert(!err);
1607
1608 memset(layer_names, 0, sizeof(layer_names));
1609 device_layers = malloc(sizeof(VkLayerProperties) * device_layer_count);
1610 err = vkGetPhysicalDeviceLayerProperties(demo->gpu, &device_layer_count, device_layers);
1611 assert(!err);
1612 for (uint32_t i = 0; i < device_layer_count; i++) {
1613 if (!validation_found && demo->validate &&
1614 !strcmp("Validation", device_layers[i].layerName)) {
1615 layer_names[enabled_layer_count++] = "Validation";
1616 validation_found = 1;
1617 }
1618 assert(enabled_layer_count < 64);
1619 }
1620 if (demo->validate && !validation_found) {
1621 ERR_EXIT("vkGetGlobalLayerProperties failed to find any "
1622 "\"Validation\" layers.\n\n"
1623 "Please look at the Getting Started guide for additional "
1624 "information.\n",
1625 "vkCreateInstance Failure");
1626 }
1627
1628 /* Don't need any device extensions */
1629 /* TODO: WSI device extension will go here eventually */
1630
1631 VkDeviceCreateInfo device = {
1632 .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
1633 .pNext = NULL,
1634 .queueRecordCount = 1,
1635 .pRequestedQueues = &queue,
1636 .layerCount = enabled_layer_count,
1637 .ppEnabledLayerNames = (const char*const*) layer_names,
1638 .extensionCount = 0,
1639 .ppEnabledExtensionNames = NULL,
1640 .flags = 0,
1641 };
1642
1643 if (demo->validate) {
Tony Barbourde4124d2015-07-03 10:33:54 -06001644 demo->dbgCreateMsgCallback = vkGetInstanceProcAddr(demo->inst, "vkDbgCreateMsgCallback");
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001645 if (!demo->dbgCreateMsgCallback) {
1646 ERR_EXIT("GetProcAddr: Unable to find vkDbgCreateMsgCallback\n",
1647 "vkGetProcAddr Failure");
1648 }
1649 err = demo->dbgCreateMsgCallback(
1650 demo->inst,
1651 VK_DBG_REPORT_ERROR_BIT | VK_DBG_REPORT_WARN_BIT,
1652 dbgFunc, NULL,
1653 &demo->msg_callback);
1654 switch (err) {
1655 case VK_SUCCESS:
1656 break;
1657 case VK_ERROR_INVALID_POINTER:
1658 ERR_EXIT("dbgCreateMsgCallback: Invalid pointer\n",
1659 "dbgCreateMsgCallback Failure");
1660 break;
1661 case VK_ERROR_OUT_OF_HOST_MEMORY:
1662 ERR_EXIT("dbgCreateMsgCallback: out of host memory\n",
1663 "dbgCreateMsgCallback Failure");
1664 break;
1665 default:
1666 ERR_EXIT("dbgCreateMsgCallback: unknown failure\n",
1667 "dbgCreateMsgCallback Failure");
1668 break;
1669 }
1670 }
1671
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001672 err = vkCreateDevice(demo->gpu, &device, &demo->device);
Chia-I Wuc19795a2014-09-13 11:12:55 +08001673 assert(!err);
1674
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001675 free(device_layers);
1676
Ian Elliott1b6de092015-06-22 15:07:49 -06001677 GET_DEVICE_PROC_ADDR(demo->device, CreateSwapChainWSI);
1678 GET_DEVICE_PROC_ADDR(demo->device, CreateSwapChainWSI);
1679 GET_DEVICE_PROC_ADDR(demo->device, DestroySwapChainWSI);
1680 GET_DEVICE_PROC_ADDR(demo->device, GetSwapChainInfoWSI);
1681 GET_DEVICE_PROC_ADDR(demo->device, QueuePresentWSI);
1682
Tony Barbour426b9052015-06-24 16:06:58 -06001683 err = vkGetPhysicalDeviceProperties(demo->gpu, &demo->gpu_props);
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -06001684 assert(!err);
1685
Tony Barbour426b9052015-06-24 16:06:58 -06001686 err = vkGetPhysicalDeviceQueueCount(demo->gpu, &queue_count);
Courtney Goeltzenleuchterbfccf412015-03-25 13:36:41 -06001687 assert(!err);
1688
Tony Barbour426b9052015-06-24 16:06:58 -06001689 demo->queue_props = (VkPhysicalDeviceQueueProperties *) malloc(queue_count * sizeof(VkPhysicalDeviceQueueProperties));
1690 err = vkGetPhysicalDeviceQueueProperties(demo->gpu, queue_count, demo->queue_props);
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -07001691 assert(!err);
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -07001692 assert(queue_count >= 1);
1693
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -06001694 // Graphics queue and MemMgr queue can be separate.
1695 // TODO: Add support for separate queues, including synchronization,
1696 // and appropriate tracking for QueueSubmit
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -07001697 for (i = 0; i < queue_count; i++) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001698 if (demo->queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -07001699 break;
1700 }
1701 assert(i < queue_count);
1702 demo->graphics_queue_node_index = i;
1703
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001704 err = vkGetDeviceQueue(demo->device, demo->graphics_queue_node_index,
Chia-I Wuc19795a2014-09-13 11:12:55 +08001705 0, &demo->queue);
1706 assert(!err);
Ian Elliott32536f92015-04-21 16:41:02 -06001707
Jon Ashburnba4a1952015-06-16 12:44:51 -06001708 // for now hardcode format till get WSI support
1709 demo->format = VK_FORMAT_B8G8R8A8_UNORM;
Ian Elliott32536f92015-04-21 16:41:02 -06001710
Mark Lobodzinski72346292015-07-02 16:49:40 -06001711 // Get Memory information and properties
1712 err = vkGetPhysicalDeviceMemoryProperties(demo->gpu, &demo->memory_properties);
1713 assert(!err);
Chia-I Wuc19795a2014-09-13 11:12:55 +08001714}
1715
1716static void demo_init_connection(struct demo *demo)
1717{
Ian Elliotte14e9f92015-04-16 15:23:05 -06001718#ifndef _WIN32
Chia-I Wuc19795a2014-09-13 11:12:55 +08001719 const xcb_setup_t *setup;
1720 xcb_screen_iterator_t iter;
1721 int scr;
1722
1723 demo->connection = xcb_connect(NULL, &scr);
Ian Elliottdfe55f72015-04-03 15:24:55 -06001724 if (demo->connection == NULL) {
1725 printf("Cannot find a compatible Vulkan installable client driver "
1726 "(ICD).\nExiting ...\n");
1727 fflush(stdout);
1728 exit(1);
1729 }
Chia-I Wuc19795a2014-09-13 11:12:55 +08001730
1731 setup = xcb_get_setup(demo->connection);
1732 iter = xcb_setup_roots_iterator(setup);
1733 while (scr-- > 0)
1734 xcb_screen_next(&iter);
1735
1736 demo->screen = iter.data;
Ian Elliotte14e9f92015-04-16 15:23:05 -06001737#endif // _WIN32
Chia-I Wuc19795a2014-09-13 11:12:55 +08001738}
1739
Ian Elliotte14e9f92015-04-16 15:23:05 -06001740#ifdef _WIN32
1741static void demo_init(struct demo *demo, HINSTANCE hInstance, LPSTR pCmdLine)
1742#else // _WIN32
Courtney Goeltzenleuchterf113a952015-02-25 11:46:58 -07001743static void demo_init(struct demo *demo, const int argc, const char *argv[])
Ian Elliotte14e9f92015-04-16 15:23:05 -06001744#endif // _WIN32
Chia-I Wuc19795a2014-09-13 11:12:55 +08001745{
Ian Elliotte14e9f92015-04-16 15:23:05 -06001746 bool argv_error = false;
1747
Chia-I Wuc19795a2014-09-13 11:12:55 +08001748 memset(demo, 0, sizeof(*demo));
1749
Ian Elliotte14e9f92015-04-16 15:23:05 -06001750#ifdef _WIN32
1751 demo->connection = hInstance;
Ian Elliott4e19ed02015-04-28 10:52:52 -06001752 strncpy(demo->name, APP_SHORT_NAME, APP_NAME_STR_LEN);
Ian Elliotte14e9f92015-04-16 15:23:05 -06001753
1754 if (strncmp(pCmdLine, "--use_staging", strlen("--use_staging")) == 0)
1755 demo->use_staging_buffer = true;
Cody Northrop75db0322015-05-28 11:27:16 -06001756 else if (strncmp(pCmdLine, "--use_glsl", strlen("--use_glsl")) == 0)
1757 demo->use_glsl = true;
Ian Elliotte14e9f92015-04-16 15:23:05 -06001758 else if (strlen(pCmdLine) != 0) {
1759 fprintf(stderr, "Do not recognize argument \"%s\".\n", pCmdLine);
1760 argv_error = true;
1761 }
1762#else // _WIN32
Courtney Goeltzenleuchterf113a952015-02-25 11:46:58 -07001763 for (int i = 0; i < argc; i++) {
1764 if (strncmp(argv[i], "--use_staging", strlen("--use_staging")) == 0)
1765 demo->use_staging_buffer = true;
Cody Northrop75db0322015-05-28 11:27:16 -06001766 else if (strncmp(argv[i], "--use_glsl", strlen("--use_glsl")) == 0)
1767 demo->use_glsl = true;
Courtney Goeltzenleuchterf113a952015-02-25 11:46:58 -07001768 }
Ian Elliotte14e9f92015-04-16 15:23:05 -06001769#endif // _WIN32
1770 if (argv_error) {
Ian Elliott4e19ed02015-04-28 10:52:52 -06001771 fprintf(stderr, "Usage:\n %s [--use_staging]\n", APP_SHORT_NAME);
Ian Elliotte14e9f92015-04-16 15:23:05 -06001772 fflush(stderr);
1773 exit(1);
1774 }
Courtney Goeltzenleuchterf113a952015-02-25 11:46:58 -07001775
Chia-I Wuc19795a2014-09-13 11:12:55 +08001776 demo_init_connection(demo);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001777 demo_init_vk(demo);
Chia-I Wuc19795a2014-09-13 11:12:55 +08001778
1779 demo->width = 300;
1780 demo->height = 300;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001781}
1782
1783static void demo_cleanup(struct demo *demo)
1784{
Mark Lobodzinski23182612015-05-29 09:32:35 -05001785 uint32_t i;
Chia-I Wuc19795a2014-09-13 11:12:55 +08001786
Tony Barbourde4124d2015-07-03 10:33:54 -06001787 for (i = 0; i < DEMO_BUFFER_COUNT; i++) {
1788 vkDestroyFramebuffer(demo->device, demo->framebuffers[i]);
1789 }
Tony Barbourb857d312015-07-10 10:50:45 -06001790 vkFreeDescriptorSets(demo->device, demo->desc_pool, 1, &demo->desc_set);
Tony Barbourde4124d2015-07-03 10:33:54 -06001791 vkDestroyDescriptorPool(demo->device, demo->desc_pool);
Chia-I Wuf8385062015-01-04 16:27:24 +08001792
Courtney Goeltzenleuchter633f9c52015-04-30 10:58:33 -06001793 if (demo->setup_cmd) {
Tony Barbourde4124d2015-07-03 10:33:54 -06001794 vkDestroyCommandBuffer(demo->device, demo->setup_cmd);
Courtney Goeltzenleuchter633f9c52015-04-30 10:58:33 -06001795 }
Tony Barbourde4124d2015-07-03 10:33:54 -06001796 vkDestroyCommandBuffer(demo->device, demo->draw_cmd);
Chia-I Wuc19795a2014-09-13 11:12:55 +08001797
Tony Barbourde4124d2015-07-03 10:33:54 -06001798 vkDestroyDynamicViewportState(demo->device, demo->viewport);
1799 vkDestroyDynamicRasterState(demo->device, demo->raster);
1800 vkDestroyDynamicColorBlendState(demo->device, demo->color_blend);
1801 vkDestroyDynamicDepthStencilState(demo->device, demo->depth_stencil);
Chia-I Wuc19795a2014-09-13 11:12:55 +08001802
Tony Barbourde4124d2015-07-03 10:33:54 -06001803 vkDestroyPipeline(demo->device, demo->pipeline);
1804 vkDestroyRenderPass(demo->device, demo->render_pass);
1805 vkDestroyPipelineLayout(demo->device, demo->pipeline_layout);
1806 vkDestroyDescriptorSetLayout(demo->device, demo->desc_layout);
Chia-I Wub043fe32014-10-06 15:30:33 +08001807
Tony Barbourde4124d2015-07-03 10:33:54 -06001808 vkDestroyBuffer(demo->device, demo->vertices.buf);
Mark Lobodzinski23182612015-05-29 09:32:35 -05001809 vkFreeMemory(demo->device, demo->vertices.mem);
Chia-I Wu99621bc2014-10-08 11:52:22 +08001810
Chia-I Wub043fe32014-10-06 15:30:33 +08001811 for (i = 0; i < DEMO_TEXTURE_COUNT; i++) {
Tony Barbourde4124d2015-07-03 10:33:54 -06001812 vkDestroyImageView(demo->device, demo->textures[i].view);
1813 vkDestroyImage(demo->device, demo->textures[i].image);
Mark Lobodzinski23182612015-05-29 09:32:35 -05001814 vkFreeMemory(demo->device, demo->textures[i].mem);
Tony Barbourde4124d2015-07-03 10:33:54 -06001815 vkDestroySampler(demo->device, demo->textures[i].sampler);
Chia-I Wub043fe32014-10-06 15:30:33 +08001816 }
1817
Chia-I Wuc19795a2014-09-13 11:12:55 +08001818 for (i = 0; i < DEMO_BUFFER_COUNT; i++) {
Tony Barbourde4124d2015-07-03 10:33:54 -06001819 vkDestroyAttachmentView(demo->device, demo->buffers[i].view);
Chia-I Wuc19795a2014-09-13 11:12:55 +08001820 }
Tony Barbourde4124d2015-07-03 10:33:54 -06001821
1822 vkDestroyAttachmentView(demo->device, demo->depth.view);
1823 vkDestroyImage(demo->device, demo->depth.image);
1824 vkFreeMemory(demo->device, demo->depth.mem);
1825
Jon Ashburncedc15f2015-05-21 18:13:33 -06001826 demo->fpDestroySwapChainWSI(demo->swap_chain);
Chia-I Wuc19795a2014-09-13 11:12:55 +08001827
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001828 vkDestroyDevice(demo->device);
1829 vkDestroyInstance(demo->inst);
Chia-I Wuc19795a2014-09-13 11:12:55 +08001830
Ian Elliotte14e9f92015-04-16 15:23:05 -06001831#ifndef _WIN32
Chia-I Wuc19795a2014-09-13 11:12:55 +08001832 xcb_destroy_window(demo->connection, demo->window);
1833 xcb_disconnect(demo->connection);
Ian Elliotte14e9f92015-04-16 15:23:05 -06001834#endif // _WIN32
Chia-I Wuc19795a2014-09-13 11:12:55 +08001835}
1836
Ian Elliotte14e9f92015-04-16 15:23:05 -06001837#ifdef _WIN32
1838int APIENTRY WinMain(HINSTANCE hInstance,
1839 HINSTANCE hPrevInstance,
1840 LPSTR pCmdLine,
1841 int nCmdShow)
1842{
1843 MSG msg; // message
1844 bool done; // flag saying when app is complete
1845
1846 demo_init(&demo, hInstance, pCmdLine);
1847 demo_create_window(&demo);
1848
1849 demo_prepare(&demo);
1850
1851 done = false; //initialize loop condition variable
1852 /* main message loop*/
1853 while(!done)
1854 {
Ian Elliott421107f2015-04-28 15:50:36 -06001855 PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
Ian Elliotte14e9f92015-04-16 15:23:05 -06001856 if (msg.message == WM_QUIT) //check for a quit message
1857 {
1858 done = true; //if found, quit app
1859 }
1860 else
1861 {
1862 /* Translate and dispatch to event queue*/
1863 TranslateMessage(&msg);
1864 DispatchMessage(&msg);
1865 }
1866 }
1867
1868 demo_cleanup(&demo);
1869
Tony Barboura938abb2015-04-22 11:36:22 -06001870 return (int) msg.wParam;
Ian Elliotte14e9f92015-04-16 15:23:05 -06001871}
1872#else // _WIN32
Courtney Goeltzenleuchterf113a952015-02-25 11:46:58 -07001873int main(const int argc, const char *argv[])
Chia-I Wuc19795a2014-09-13 11:12:55 +08001874{
1875 struct demo demo;
1876
Courtney Goeltzenleuchterf113a952015-02-25 11:46:58 -07001877 demo_init(&demo, argc, argv);
Chia-I Wu5b66aa52015-04-16 22:02:10 +08001878 demo_create_window(&demo);
Chia-I Wuc19795a2014-09-13 11:12:55 +08001879
1880 demo_prepare(&demo);
Chia-I Wuc19795a2014-09-13 11:12:55 +08001881 demo_run(&demo);
1882
1883 demo_cleanup(&demo);
1884
Chia-I Wuc19795a2014-09-13 11:12:55 +08001885 return 0;
1886}
Ian Elliotte14e9f92015-04-16 15:23:05 -06001887#endif // _WIN32