blob: 2acb1623c559571b7be07772c5685d9e96d10fa8 [file] [log] [blame]
Karl Schultz6addd812016-02-02 17:17:23 -07001/*
2 * Copyright (c) 2015-2016 The Khronos Group Inc.
3 * Copyright (c) 2015-2016 Valve Corporation
4 * Copyright (c) 2015-2016 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and/or associated documentation files (the "Materials"), to
8 * deal in the Materials without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Materials, and to permit persons to whom the Materials are
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice(s) and this permission notice shall be included in
14 * all copies or substantial portions of the Materials.
15 *
Karl Schultz6addd812016-02-02 17:17:23 -070016 * THE MATERIALS ARE 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.
19 *
20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
23 * USE OR OTHER DEALINGS IN THE MATERIALS.
24 *
25 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
26 * Author: Tony Barbour <tony@LunarG.com>
27 */
Chia-I Wuf1e2e992014-12-27 14:12:52 +080028
29#include <iostream>
30#include <string.h> // memset(), memcmp()
Courtney Goeltzenleuchter992fb4f2015-04-19 19:07:33 -060031#include <assert.h>
Tony Barbour67e99152015-07-10 14:10:27 -060032#include <stdarg.h>
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060033#include "vktestbinding.h"
Chia-I Wuf1e2e992014-12-27 14:12:52 +080034
35namespace {
Chia-I Wuf1e2e992014-12-27 14:12:52 +080036
Karl Schultz6addd812016-02-02 17:17:23 -070037#define NON_DISPATCHABLE_HANDLE_INIT(create_func, dev, ...) \
38 do { \
39 handle_type handle; \
40 if (EXPECT(create_func(dev.handle(), __VA_ARGS__, NULL, &handle) == \
41 VK_SUCCESS)) \
42 NonDispHandle::init(dev.handle(), handle); \
Chia-I Wuf8f074f2015-07-03 10:58:57 +080043 } while (0)
44
Karl Schultz6addd812016-02-02 17:17:23 -070045#define NON_DISPATCHABLE_HANDLE_DTOR(cls, destroy_func) \
46 cls::~cls() { \
47 if (initialized()) \
48 destroy_func(device(), handle(), NULL); \
Chia-I Wud9e8e822015-07-03 11:45:55 +080049 }
50
Chia-I Wuf1e2e992014-12-27 14:12:52 +080051#define STRINGIFY(x) #x
Karl Schultz6addd812016-02-02 17:17:23 -070052#define EXPECT(expr) \
53 ((expr) ? true : expect_failure(STRINGIFY(expr), __FILE__, __LINE__, \
54 __FUNCTION__))
Chia-I Wuf1e2e992014-12-27 14:12:52 +080055
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060056vk_testing::ErrorCallback error_callback;
Chia-I Wuf1e2e992014-12-27 14:12:52 +080057
Karl Schultz6addd812016-02-02 17:17:23 -070058bool expect_failure(const char *expr, const char *file, unsigned int line,
59 const char *function) {
Chia-I Wuf1e2e992014-12-27 14:12:52 +080060 if (error_callback) {
61 error_callback(expr, file, line, function);
62 } else {
Karl Schultz6addd812016-02-02 17:17:23 -070063 std::cerr << file << ":" << line << ": " << function
64 << ": Expectation `" << expr << "' failed.\n";
Chia-I Wuf1e2e992014-12-27 14:12:52 +080065 }
66
67 return false;
68}
69
Karl Schultz6addd812016-02-02 17:17:23 -070070template <class T, class S>
71std::vector<T> make_handles(const std::vector<S> &v) {
Chia-I Wud9e8e822015-07-03 11:45:55 +080072 std::vector<T> handles;
73 handles.reserve(v.size());
Karl Schultz6addd812016-02-02 17:17:23 -070074 for (typename std::vector<S>::const_iterator it = v.begin(); it != v.end();
75 it++)
Chia-I Wud9e8e822015-07-03 11:45:55 +080076 handles.push_back((*it)->handle());
77 return handles;
78}
79
Karl Schultz6addd812016-02-02 17:17:23 -070080VkMemoryAllocateInfo get_resource_alloc_info(const vk_testing::Device &dev,
81 const VkMemoryRequirements &reqs,
82 VkMemoryPropertyFlags mem_props) {
83 VkMemoryAllocateInfo info =
84 vk_testing::DeviceMemory::alloc_info(reqs.size, 0);
Chia-I Wu681d7a02015-07-03 13:44:34 +080085 dev.phy().set_memory_type(reqs.memoryTypeBits, &info, mem_props);
Chia-I Wuf1e2e992014-12-27 14:12:52 +080086
87 return info;
88}
Chia-I Wu681d7a02015-07-03 13:44:34 +080089
Chia-I Wuf1e2e992014-12-27 14:12:52 +080090} // namespace
91
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060092namespace vk_testing {
Chia-I Wuf1e2e992014-12-27 14:12:52 +080093
Karl Schultz6addd812016-02-02 17:17:23 -070094void set_error_callback(ErrorCallback callback) { error_callback = callback; }
Chia-I Wuf1e2e992014-12-27 14:12:52 +080095
Karl Schultz6addd812016-02-02 17:17:23 -070096VkPhysicalDeviceProperties PhysicalDevice::properties() const {
Tony Barbour59a47322015-06-24 16:06:58 -060097 VkPhysicalDeviceProperties info;
98
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -060099 vkGetPhysicalDeviceProperties(handle(), &info);
Tony Barbour59a47322015-06-24 16:06:58 -0600100
101 return info;
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800102}
103
Karl Schultz6addd812016-02-02 17:17:23 -0700104std::vector<VkQueueFamilyProperties> PhysicalDevice::queue_properties() const {
Cody Northropd0802882015-08-03 17:04:53 -0600105 std::vector<VkQueueFamilyProperties> info;
Tony Barbour59a47322015-06-24 16:06:58 -0600106 uint32_t count;
107
Cody Northropd0802882015-08-03 17:04:53 -0600108 // Call once with NULL data to receive count
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600109 vkGetPhysicalDeviceQueueFamilyProperties(handle(), &count, NULL);
110 info.resize(count);
111 vkGetPhysicalDeviceQueueFamilyProperties(handle(), &count, info.data());
Tony Barbour59a47322015-06-24 16:06:58 -0600112
113 return info;
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800114}
115
Karl Schultz6addd812016-02-02 17:17:23 -0700116VkPhysicalDeviceMemoryProperties PhysicalDevice::memory_properties() const {
Tony Barbour59a47322015-06-24 16:06:58 -0600117 VkPhysicalDeviceMemoryProperties info;
118
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600119 vkGetPhysicalDeviceMemoryProperties(handle(), &info);
Mark Lobodzinskib3fbcd92015-07-02 16:49:40 -0600120
Tony Barbour59a47322015-06-24 16:06:58 -0600121 return info;
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800122}
123
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600124/*
125 * Return list of Global layers available
126 */
Karl Schultz6addd812016-02-02 17:17:23 -0700127std::vector<VkLayerProperties> GetGlobalLayers() {
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600128 VkResult err;
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600129 std::vector<VkLayerProperties> layers;
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600130 uint32_t layer_count;
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600131
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600132 do {
133 layer_count = 0;
Courtney Goeltzenleuchter35985f62015-09-14 17:22:16 -0600134 err = vkEnumerateInstanceLayerProperties(&layer_count, NULL);
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600135
136 if (err == VK_SUCCESS) {
137 layers.reserve(layer_count);
Karl Schultz6addd812016-02-02 17:17:23 -0700138 err =
139 vkEnumerateInstanceLayerProperties(&layer_count, layers.data());
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600140 }
141 } while (err == VK_INCOMPLETE);
142
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600143 assert(err == VK_SUCCESS);
144
145 return layers;
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800146}
147
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600148/*
149 * Return list of Global extensions provided by the ICD / Loader
150 */
Karl Schultz6addd812016-02-02 17:17:23 -0700151std::vector<VkExtensionProperties> GetGlobalExtensions() {
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600152 return GetGlobalExtensions(NULL);
153}
154
155/*
156 * Return list of Global extensions provided by the specified layer
Karl Schultz6addd812016-02-02 17:17:23 -0700157 * If pLayerName is NULL, will return extensions implemented by the loader /
158 * ICDs
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600159 */
Karl Schultz6addd812016-02-02 17:17:23 -0700160std::vector<VkExtensionProperties> GetGlobalExtensions(const char *pLayerName) {
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600161 std::vector<VkExtensionProperties> exts;
162 uint32_t ext_count;
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600163 VkResult err;
164
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600165 do {
166 ext_count = 0;
Karl Schultz6addd812016-02-02 17:17:23 -0700167 err = vkEnumerateInstanceExtensionProperties(pLayerName, &ext_count,
168 NULL);
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600169
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600170 if (err == VK_SUCCESS) {
Courtney Goeltzenleuchter381f3a22015-07-06 15:45:58 -0600171 exts.resize(ext_count);
Karl Schultz6addd812016-02-02 17:17:23 -0700172 err = vkEnumerateInstanceExtensionProperties(pLayerName, &ext_count,
173 exts.data());
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600174 }
175 } while (err == VK_INCOMPLETE);
176
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600177 assert(err == VK_SUCCESS);
178
179 return exts;
180}
181
182/*
183 * Return list of PhysicalDevice extensions provided by the ICD / Loader
184 */
Karl Schultz6addd812016-02-02 17:17:23 -0700185std::vector<VkExtensionProperties> PhysicalDevice::extensions() const {
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600186 return extensions(NULL);
187}
188
189/*
190 * Return list of PhysicalDevice extensions provided by the specified layer
191 * If pLayerName is NULL, will return extensions for ICD / loader.
192 */
Karl Schultz6addd812016-02-02 17:17:23 -0700193std::vector<VkExtensionProperties>
194PhysicalDevice::extensions(const char *pLayerName) const {
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600195 std::vector<VkExtensionProperties> exts;
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600196 VkResult err;
197
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600198 do {
199 uint32_t extCount = 0;
Karl Schultz6addd812016-02-02 17:17:23 -0700200 err = vkEnumerateDeviceExtensionProperties(handle(), pLayerName,
201 &extCount, NULL);
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600202
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600203 if (err == VK_SUCCESS) {
Ian Elliott1a3845b2015-07-06 14:33:04 -0600204 exts.resize(extCount);
Karl Schultz6addd812016-02-02 17:17:23 -0700205 err = vkEnumerateDeviceExtensionProperties(handle(), pLayerName,
206 &extCount, exts.data());
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600207 }
208 } while (err == VK_INCOMPLETE);
209
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600210 assert(err == VK_SUCCESS);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800211
212 return exts;
213}
214
Karl Schultz6addd812016-02-02 17:17:23 -0700215bool PhysicalDevice::set_memory_type(const uint32_t type_bits,
216 VkMemoryAllocateInfo *info,
217 const VkFlags properties,
218 const VkFlags forbid) const {
219 uint32_t type_mask = type_bits;
220 // Search memtypes to find first index with those properties
221 for (uint32_t i = 0; i < memory_properties_.memoryTypeCount; i++) {
222 if ((type_mask & 1) == 1) {
223 // Type is available, does it match user properties?
224 if ((memory_properties_.memoryTypes[i].propertyFlags &
225 properties) == properties &&
226 (memory_properties_.memoryTypes[i].propertyFlags & forbid) ==
227 0) {
228 info->memoryTypeIndex = i;
229 return true;
230 }
231 }
232 type_mask >>= 1;
233 }
234 // No memory types matched, return failure
235 return false;
Mark Lobodzinskib3fbcd92015-07-02 16:49:40 -0600236}
237
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600238/*
239 * Return list of PhysicalDevice layers
240 */
Karl Schultz6addd812016-02-02 17:17:23 -0700241std::vector<VkLayerProperties> PhysicalDevice::layers() const {
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600242 std::vector<VkLayerProperties> layer_props;
243 VkResult err;
244
245 do {
246 uint32_t layer_count = 0;
Courtney Goeltzenleuchter35985f62015-09-14 17:22:16 -0600247 err = vkEnumerateDeviceLayerProperties(handle(), &layer_count, NULL);
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600248
249 if (err == VK_SUCCESS) {
250 layer_props.reserve(layer_count);
Karl Schultz6addd812016-02-02 17:17:23 -0700251 err = vkEnumerateDeviceLayerProperties(handle(), &layer_count,
252 layer_props.data());
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600253 }
254 } while (err == VK_INCOMPLETE);
255
256 assert(err == VK_SUCCESS);
257
258 return layer_props;
259}
260
Karl Schultz6addd812016-02-02 17:17:23 -0700261Device::~Device() {
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800262 if (!initialized())
263 return;
264
265 for (int i = 0; i < QUEUE_COUNT; i++) {
Karl Schultz6addd812016-02-02 17:17:23 -0700266 for (std::vector<Queue *>::iterator it = queues_[i].begin();
267 it != queues_[i].end(); it++)
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800268 delete *it;
269 queues_[i].clear();
270 }
271
Chia-I Wuf7458c52015-10-26 21:10:41 +0800272 vkDestroyDevice(handle(), NULL);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800273}
274
Karl Schultz6addd812016-02-02 17:17:23 -0700275void Device::init(std::vector<const char *> &layers,
276 std::vector<const char *> &extensions) {
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800277 // request all queues
Karl Schultz6addd812016-02-02 17:17:23 -0700278 const std::vector<VkQueueFamilyProperties> queue_props =
279 phy_.queue_properties();
Courtney Goeltzenleuchter95487bc2015-04-14 18:48:46 -0600280 std::vector<VkDeviceQueueCreateInfo> queue_info;
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800281 queue_info.reserve(queue_props.size());
Mark Lobodzinski53d023a2016-02-01 09:06:25 -0700282
283 std::vector<std::vector<float>> queue_priorities;
284
Mark Young93ecb1d2016-01-13 13:47:16 -0700285 for (uint32_t i = 0; i < (uint32_t)queue_props.size(); i++) {
Courtney Goeltzenleuchter95487bc2015-04-14 18:48:46 -0600286 VkDeviceQueueCreateInfo qi = {};
Karl Schultz6addd812016-02-02 17:17:23 -0700287 qi.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
288 qi.pNext = NULL;
289 qi.queueFamilyIndex = i;
290 qi.queueCount = queue_props[i].queueCount;
Mark Lobodzinski53d023a2016-02-01 09:06:25 -0700291
292 queue_priorities.emplace_back(qi.queueCount, 0.0);
293
294 qi.pQueuePriorities = queue_priorities[i].data();
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600295 if (queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700296 graphics_queue_node_index_ = i;
297 }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800298 queue_info.push_back(qi);
299 }
300
Courtney Goeltzenleuchter95487bc2015-04-14 18:48:46 -0600301 VkDeviceCreateInfo dev_info = {};
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600302 dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
Courtney Goeltzenleuchterf579fa62015-06-10 17:39:03 -0600303 dev_info.pNext = NULL;
Chia-I Wu02124482015-11-06 06:42:02 +0800304 dev_info.queueCreateInfoCount = queue_info.size();
305 dev_info.pQueueCreateInfos = queue_info.data();
Jon Ashburnf19916e2016-01-11 13:12:43 -0700306 dev_info.enabledLayerCount = layers.size();
Tony Barbour482c6092015-07-27 09:37:48 -0600307 dev_info.ppEnabledLayerNames = layers.data();
Jon Ashburnf19916e2016-01-11 13:12:43 -0700308 dev_info.enabledExtensionCount = extensions.size();
Tony Barbour482c6092015-07-27 09:37:48 -0600309 dev_info.ppEnabledExtensionNames = extensions.data();
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800310
311 init(dev_info);
312}
313
Karl Schultz6addd812016-02-02 17:17:23 -0700314void Device::init(const VkDeviceCreateInfo &info) {
Chia-I Wuf368b602015-07-03 10:41:20 +0800315 VkDevice dev;
316
Chia-I Wuf7458c52015-10-26 21:10:41 +0800317 if (EXPECT(vkCreateDevice(phy_.handle(), &info, NULL, &dev) == VK_SUCCESS))
Chia-I Wuf368b602015-07-03 10:41:20 +0800318 Handle::init(dev);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800319
320 init_queues();
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800321 init_formats();
322}
323
Karl Schultz6addd812016-02-02 17:17:23 -0700324void Device::init_queues() {
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700325 uint32_t queue_node_count;
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800326
Cody Northropd0802882015-08-03 17:04:53 -0600327 // Call with NULL data to get count
Karl Schultz6addd812016-02-02 17:17:23 -0700328 vkGetPhysicalDeviceQueueFamilyProperties(phy_.handle(), &queue_node_count,
329 NULL);
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700330 EXPECT(queue_node_count >= 1);
331
Karl Schultz6addd812016-02-02 17:17:23 -0700332 VkQueueFamilyProperties *queue_props =
333 new VkQueueFamilyProperties[queue_node_count];
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700334
Karl Schultz6addd812016-02-02 17:17:23 -0700335 vkGetPhysicalDeviceQueueFamilyProperties(phy_.handle(), &queue_node_count,
336 queue_props);
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700337
Tony Barbour7ea6aa22015-05-22 09:44:58 -0600338 for (uint32_t i = 0; i < queue_node_count; i++) {
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600339 VkQueue queue;
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700340
Tony Barbour7ea6aa22015-05-22 09:44:58 -0600341 for (uint32_t j = 0; j < queue_props[i].queueCount; j++) {
Karl Schultz6addd812016-02-02 17:17:23 -0700342 // TODO: Need to add support for separate MEMMGR and work queues,
343 // including synchronization
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600344 vkGetDeviceQueue(handle(), i, j, &queue);
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700345
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600346 if (queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
Tony Barbourfb21ea32015-07-23 10:35:30 -0600347 queues_[GRAPHICS].push_back(new Queue(queue, i));
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700348 }
349
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600350 if (queue_props[i].queueFlags & VK_QUEUE_COMPUTE_BIT) {
Tony Barbourfb21ea32015-07-23 10:35:30 -0600351 queues_[COMPUTE].push_back(new Queue(queue, i));
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700352 }
353
Chia-I Wu1b99bb22015-10-27 19:25:11 +0800354 if (queue_props[i].queueFlags & VK_QUEUE_TRANSFER_BIT) {
Tony Barbourfb21ea32015-07-23 10:35:30 -0600355 queues_[DMA].push_back(new Queue(queue, i));
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700356 }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800357 }
358 }
359
Chris Forbes02038792015-06-04 10:49:27 +1200360 delete[] queue_props;
Tony Barbour3d69c9e2015-05-20 16:53:31 -0600361
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800362 EXPECT(!queues_[GRAPHICS].empty() || !queues_[COMPUTE].empty());
363}
364
Karl Schultz6addd812016-02-02 17:17:23 -0700365void Device::init_formats() {
Tony Barbourd1c35722015-04-16 15:59:00 -0600366 for (int f = VK_FORMAT_BEGIN_RANGE; f <= VK_FORMAT_END_RANGE; f++) {
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600367 const VkFormat fmt = static_cast<VkFormat>(f);
368 const VkFormatProperties props = format_properties(fmt);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800369
Jeremy Hayesa058eee2015-01-23 08:51:43 -0700370 if (props.linearTilingFeatures) {
Karl Schultz6addd812016-02-02 17:17:23 -0700371 const Format tmp = {fmt, VK_IMAGE_TILING_LINEAR,
372 props.linearTilingFeatures};
Jeremy Hayesa058eee2015-01-23 08:51:43 -0700373 formats_.push_back(tmp);
374 }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800375
Jeremy Hayesa058eee2015-01-23 08:51:43 -0700376 if (props.optimalTilingFeatures) {
Karl Schultz6addd812016-02-02 17:17:23 -0700377 const Format tmp = {fmt, VK_IMAGE_TILING_OPTIMAL,
378 props.optimalTilingFeatures};
Jeremy Hayesa058eee2015-01-23 08:51:43 -0700379 formats_.push_back(tmp);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800380 }
381 }
382
383 EXPECT(!formats_.empty());
384}
385
Karl Schultz6addd812016-02-02 17:17:23 -0700386VkFormatProperties Device::format_properties(VkFormat format) {
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600387 VkFormatProperties data;
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600388 vkGetPhysicalDeviceFormatProperties(phy().handle(), format, &data);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800389
390 return data;
391}
392
Karl Schultz6addd812016-02-02 17:17:23 -0700393void Device::wait() { EXPECT(vkDeviceWaitIdle(handle()) == VK_SUCCESS); }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800394
Karl Schultz6addd812016-02-02 17:17:23 -0700395VkResult Device::wait(const std::vector<const Fence *> &fences, bool wait_all,
396 uint64_t timeout) {
Chia-I Wud9e8e822015-07-03 11:45:55 +0800397 const std::vector<VkFence> fence_handles = make_handles<VkFence>(fences);
Karl Schultz6addd812016-02-02 17:17:23 -0700398 VkResult err = vkWaitForFences(handle(), fence_handles.size(),
399 fence_handles.data(), wait_all, timeout);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600400 EXPECT(err == VK_SUCCESS || err == VK_TIMEOUT);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800401
402 return err;
403}
404
Karl Schultz6addd812016-02-02 17:17:23 -0700405void Device::update_descriptor_sets(
406 const std::vector<VkWriteDescriptorSet> &writes,
407 const std::vector<VkCopyDescriptorSet> &copies) {
408 vkUpdateDescriptorSets(handle(), writes.size(), writes.data(),
409 copies.size(), copies.data());
Chia-I Wu9d00ed72015-05-25 16:27:55 +0800410}
411
Karl Schultz6addd812016-02-02 17:17:23 -0700412void Queue::submit(const std::vector<const CommandBuffer *> &cmds,
413 Fence &fence) {
414 const std::vector<VkCommandBuffer> cmd_handles =
415 make_handles<VkCommandBuffer>(cmds);
Courtney Goeltzenleuchter806c7002015-10-27 11:22:14 -0600416 VkSubmitInfo submit_info;
Chia-I Wuf9be13c2015-10-26 20:37:06 +0800417 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
418 submit_info.pNext = NULL;
Chia-I Wud50a7d72015-10-26 20:48:51 +0800419 submit_info.waitSemaphoreCount = 0;
Courtney Goeltzenleuchter806c7002015-10-27 11:22:14 -0600420 submit_info.pWaitSemaphores = NULL;
Jon Ashburn7f9716c2015-12-30 16:42:50 -0700421 submit_info.pWaitDstStageMask = NULL;
Chia-I Wud50a7d72015-10-26 20:48:51 +0800422 submit_info.commandBufferCount = (uint32_t)cmd_handles.size();
Courtney Goeltzenleuchter806c7002015-10-27 11:22:14 -0600423 submit_info.pCommandBuffers = cmd_handles.data();
Chia-I Wud50a7d72015-10-26 20:48:51 +0800424 submit_info.signalSemaphoreCount = 0;
Courtney Goeltzenleuchter806c7002015-10-27 11:22:14 -0600425 submit_info.pSignalSemaphores = NULL;
Courtney Goeltzenleuchter646b9072015-10-20 18:04:07 -0600426
Karl Schultz6addd812016-02-02 17:17:23 -0700427 EXPECT(vkQueueSubmit(handle(), 1, &submit_info, fence.handle()) ==
428 VK_SUCCESS);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800429}
430
Karl Schultz6addd812016-02-02 17:17:23 -0700431void Queue::submit(const CommandBuffer &cmd, Fence &fence) {
432 submit(std::vector<const CommandBuffer *>(1, &cmd), fence);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800433}
434
Karl Schultz6addd812016-02-02 17:17:23 -0700435void Queue::submit(const CommandBuffer &cmd) {
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800436 Fence fence;
Courtney Goeltzenleuchter97b75232015-04-07 17:13:38 -0600437 submit(cmd, fence);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800438}
439
Karl Schultz6addd812016-02-02 17:17:23 -0700440void Queue::wait() { EXPECT(vkQueueWaitIdle(handle()) == VK_SUCCESS); }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800441
Karl Schultz6addd812016-02-02 17:17:23 -0700442DeviceMemory::~DeviceMemory() {
Chia-I Wuf8f074f2015-07-03 10:58:57 +0800443 if (initialized())
Chia-I Wuf7458c52015-10-26 21:10:41 +0800444 vkFreeMemory(device(), handle(), NULL);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800445}
446
Karl Schultz6addd812016-02-02 17:17:23 -0700447void DeviceMemory::init(const Device &dev, const VkMemoryAllocateInfo &info) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800448 NON_DISPATCHABLE_HANDLE_INIT(vkAllocateMemory, dev, &info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800449}
450
Karl Schultz6addd812016-02-02 17:17:23 -0700451const void *DeviceMemory::map(VkFlags flags) const {
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800452 void *data;
Karl Schultz6addd812016-02-02 17:17:23 -0700453 if (!EXPECT(vkMapMemory(device(), handle(), 0, VK_WHOLE_SIZE, flags,
454 &data) == VK_SUCCESS))
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800455 data = NULL;
456
457 return data;
458}
459
Karl Schultz6addd812016-02-02 17:17:23 -0700460void *DeviceMemory::map(VkFlags flags) {
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800461 void *data;
Karl Schultz6addd812016-02-02 17:17:23 -0700462 if (!EXPECT(vkMapMemory(device(), handle(), 0, VK_WHOLE_SIZE, flags,
463 &data) == VK_SUCCESS))
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800464 data = NULL;
465
466 return data;
467}
468
Karl Schultz6addd812016-02-02 17:17:23 -0700469void DeviceMemory::unmap() const { vkUnmapMemory(device(), handle()); }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800470
Tony Barbour67e99152015-07-10 14:10:27 -0600471NON_DISPATCHABLE_HANDLE_DTOR(Fence, vkDestroyFence)
Chia-I Wud9e8e822015-07-03 11:45:55 +0800472
Karl Schultz6addd812016-02-02 17:17:23 -0700473void Fence::init(const Device &dev, const VkFenceCreateInfo &info) {
Chia-I Wud9e8e822015-07-03 11:45:55 +0800474 NON_DISPATCHABLE_HANDLE_INIT(vkCreateFence, dev, &info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800475}
476
Tony Barbour67e99152015-07-10 14:10:27 -0600477NON_DISPATCHABLE_HANDLE_DTOR(Semaphore, vkDestroySemaphore)
Chia-I Wu6b1c2482015-07-03 11:49:42 +0800478
Karl Schultz6addd812016-02-02 17:17:23 -0700479void Semaphore::init(const Device &dev, const VkSemaphoreCreateInfo &info) {
Chia-I Wu6b1c2482015-07-03 11:49:42 +0800480 NON_DISPATCHABLE_HANDLE_INIT(vkCreateSemaphore, dev, &info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800481}
482
Tony Barbour67e99152015-07-10 14:10:27 -0600483NON_DISPATCHABLE_HANDLE_DTOR(Event, vkDestroyEvent)
Chia-I Wuc5c97992015-07-03 11:49:42 +0800484
Karl Schultz6addd812016-02-02 17:17:23 -0700485void Event::init(const Device &dev, const VkEventCreateInfo &info) {
Chia-I Wuc5c97992015-07-03 11:49:42 +0800486 NON_DISPATCHABLE_HANDLE_INIT(vkCreateEvent, dev, &info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800487}
488
Karl Schultz6addd812016-02-02 17:17:23 -0700489void Event::set() { EXPECT(vkSetEvent(device(), handle()) == VK_SUCCESS); }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800490
Karl Schultz6addd812016-02-02 17:17:23 -0700491void Event::reset() { EXPECT(vkResetEvent(device(), handle()) == VK_SUCCESS); }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800492
Tony Barbour67e99152015-07-10 14:10:27 -0600493NON_DISPATCHABLE_HANDLE_DTOR(QueryPool, vkDestroyQueryPool)
Chia-I Wu1b7d4762015-07-03 11:49:42 +0800494
Karl Schultz6addd812016-02-02 17:17:23 -0700495void QueryPool::init(const Device &dev, const VkQueryPoolCreateInfo &info) {
Chia-I Wu1b7d4762015-07-03 11:49:42 +0800496 NON_DISPATCHABLE_HANDLE_INIT(vkCreateQueryPool, dev, &info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800497}
498
Karl Schultz6addd812016-02-02 17:17:23 -0700499VkResult QueryPool::results(uint32_t first, uint32_t count, size_t size,
500 void *data, size_t stride) {
501 VkResult err = vkGetQueryPoolResults(device(), handle(), first, count, size,
502 data, stride, 0);
Chia-I Wuccc93a72015-10-26 18:36:20 +0800503 EXPECT(err == VK_SUCCESS || err == VK_NOT_READY);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800504
505 return err;
506}
507
Tony Barbour67e99152015-07-10 14:10:27 -0600508NON_DISPATCHABLE_HANDLE_DTOR(Buffer, vkDestroyBuffer)
Chia-I Wu1a28fe02015-01-01 07:55:04 +0800509
Karl Schultz6addd812016-02-02 17:17:23 -0700510void Buffer::init(const Device &dev, const VkBufferCreateInfo &info,
511 VkMemoryPropertyFlags mem_props) {
Tony Barbour4c97d7a2015-04-22 15:10:33 -0600512 init_no_mem(dev, info);
Chia-I Wu681d7a02015-07-03 13:44:34 +0800513
Karl Schultz6addd812016-02-02 17:17:23 -0700514 internal_mem_.init(
515 dev, get_resource_alloc_info(dev, memory_requirements(), mem_props));
Chia-I Wu681d7a02015-07-03 13:44:34 +0800516 bind_memory(internal_mem_, 0);
Tony Barbour4c97d7a2015-04-22 15:10:33 -0600517}
518
Karl Schultz6addd812016-02-02 17:17:23 -0700519void Buffer::init_no_mem(const Device &dev, const VkBufferCreateInfo &info) {
Chia-I Wu681d7a02015-07-03 13:44:34 +0800520 NON_DISPATCHABLE_HANDLE_INIT(vkCreateBuffer, dev, &info);
Chia-I Wu1a28fe02015-01-01 07:55:04 +0800521 create_info_ = info;
522}
523
Karl Schultz6addd812016-02-02 17:17:23 -0700524VkMemoryRequirements Buffer::memory_requirements() const {
Chia-I Wu681d7a02015-07-03 13:44:34 +0800525 VkMemoryRequirements reqs;
526
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600527 vkGetBufferMemoryRequirements(device(), handle(), &reqs);
Chia-I Wu681d7a02015-07-03 13:44:34 +0800528
529 return reqs;
530}
531
Karl Schultz6addd812016-02-02 17:17:23 -0700532void Buffer::bind_memory(const DeviceMemory &mem, VkDeviceSize mem_offset) {
533 EXPECT(vkBindBufferMemory(device(), handle(), mem.handle(), mem_offset) ==
534 VK_SUCCESS);
Mark Lobodzinski942b1722015-05-11 17:21:15 -0500535}
536
Tony Barbour67e99152015-07-10 14:10:27 -0600537NON_DISPATCHABLE_HANDLE_DTOR(BufferView, vkDestroyBufferView)
Chia-I Wu3158bf32015-07-03 11:49:42 +0800538
Karl Schultz6addd812016-02-02 17:17:23 -0700539void BufferView::init(const Device &dev, const VkBufferViewCreateInfo &info) {
Chia-I Wu3158bf32015-07-03 11:49:42 +0800540 NON_DISPATCHABLE_HANDLE_INIT(vkCreateBufferView, dev, &info);
Chia-I Wu1a28fe02015-01-01 07:55:04 +0800541}
542
Tony Barbour67e99152015-07-10 14:10:27 -0600543NON_DISPATCHABLE_HANDLE_DTOR(Image, vkDestroyImage)
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800544
Karl Schultz6addd812016-02-02 17:17:23 -0700545void Image::init(const Device &dev, const VkImageCreateInfo &info,
546 VkMemoryPropertyFlags mem_props) {
Tony Barbour4c97d7a2015-04-22 15:10:33 -0600547 init_no_mem(dev, info);
Chia-I Wu681d7a02015-07-03 13:44:34 +0800548
Karl Schultz6addd812016-02-02 17:17:23 -0700549 internal_mem_.init(
550 dev, get_resource_alloc_info(dev, memory_requirements(), mem_props));
Chia-I Wu681d7a02015-07-03 13:44:34 +0800551 bind_memory(internal_mem_, 0);
Tony Barbour4c97d7a2015-04-22 15:10:33 -0600552}
553
Karl Schultz6addd812016-02-02 17:17:23 -0700554void Image::init_no_mem(const Device &dev, const VkImageCreateInfo &info) {
Chia-I Wu681d7a02015-07-03 13:44:34 +0800555 NON_DISPATCHABLE_HANDLE_INIT(vkCreateImage, dev, &info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800556 init_info(dev, info);
557}
558
Karl Schultz6addd812016-02-02 17:17:23 -0700559void Image::init_info(const Device &dev, const VkImageCreateInfo &info) {
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800560 create_info_ = info;
561
Karl Schultz6addd812016-02-02 17:17:23 -0700562 for (std::vector<Device::Format>::const_iterator it = dev.formats().begin();
563 it != dev.formats().end(); it++) {
564 if (memcmp(&it->format, &create_info_.format, sizeof(it->format)) ==
565 0 &&
566 it->tiling == create_info_.tiling) {
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800567 format_features_ = it->features;
568 break;
569 }
570 }
571}
572
Karl Schultz6addd812016-02-02 17:17:23 -0700573VkMemoryRequirements Image::memory_requirements() const {
Chia-I Wu681d7a02015-07-03 13:44:34 +0800574 VkMemoryRequirements reqs;
575
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600576 vkGetImageMemoryRequirements(device(), handle(), &reqs);
Chia-I Wu681d7a02015-07-03 13:44:34 +0800577
578 return reqs;
579}
580
Karl Schultz6addd812016-02-02 17:17:23 -0700581void Image::bind_memory(const DeviceMemory &mem, VkDeviceSize mem_offset) {
582 EXPECT(vkBindImageMemory(device(), handle(), mem.handle(), mem_offset) ==
583 VK_SUCCESS);
Chia-I Wu1a28fe02015-01-01 07:55:04 +0800584}
585
Karl Schultz6addd812016-02-02 17:17:23 -0700586VkSubresourceLayout
587Image::subresource_layout(const VkImageSubresource &subres) const {
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600588 VkSubresourceLayout data;
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800589 size_t size = sizeof(data);
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600590 vkGetImageSubresourceLayout(device(), handle(), &subres, &data);
591 if (size != sizeof(data))
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800592 memset(&data, 0, sizeof(data));
593
594 return data;
595}
596
Karl Schultz6addd812016-02-02 17:17:23 -0700597VkSubresourceLayout
598Image::subresource_layout(const VkImageSubresourceLayers &subrescopy) const {
Courtney Goeltzenleuchter01ee1ca2015-09-10 16:41:13 -0600599 VkSubresourceLayout data;
Karl Schultz6addd812016-02-02 17:17:23 -0700600 VkImageSubresource subres =
601 subresource(image_aspect(subrescopy.aspectMask), subrescopy.mipLevel,
602 subrescopy.baseArrayLayer);
Courtney Goeltzenleuchter01ee1ca2015-09-10 16:41:13 -0600603 size_t size = sizeof(data);
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -0600604 vkGetImageSubresourceLayout(device(), handle(), &subres, &data);
605 if (size != sizeof(data))
Courtney Goeltzenleuchter01ee1ca2015-09-10 16:41:13 -0600606 memset(&data, 0, sizeof(data));
607
608 return data;
609}
610
Karl Schultz6addd812016-02-02 17:17:23 -0700611bool Image::transparent() const {
612 return (
613 create_info_.tiling == VK_IMAGE_TILING_LINEAR &&
614 create_info_.samples == VK_SAMPLE_COUNT_1_BIT &&
615 !(create_info_.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
616 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)));
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800617}
618
Tony Barbour67e99152015-07-10 14:10:27 -0600619NON_DISPATCHABLE_HANDLE_DTOR(ImageView, vkDestroyImageView)
Chia-I Wu3158bf32015-07-03 11:49:42 +0800620
Karl Schultz6addd812016-02-02 17:17:23 -0700621void ImageView::init(const Device &dev, const VkImageViewCreateInfo &info) {
Chia-I Wu3158bf32015-07-03 11:49:42 +0800622 NON_DISPATCHABLE_HANDLE_INIT(vkCreateImageView, dev, &info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800623}
624
Tony Barbour67e99152015-07-10 14:10:27 -0600625NON_DISPATCHABLE_HANDLE_DTOR(ShaderModule, vkDestroyShaderModule)
Chia-I Wu4d0c7922015-07-03 11:49:42 +0800626
Karl Schultz6addd812016-02-02 17:17:23 -0700627void ShaderModule::init(const Device &dev,
628 const VkShaderModuleCreateInfo &info) {
Chia-I Wu4d0c7922015-07-03 11:49:42 +0800629 NON_DISPATCHABLE_HANDLE_INIT(vkCreateShaderModule, dev, &info);
Courtney Goeltzenleuchteree4027d2015-06-28 13:01:17 -0600630}
631
Karl Schultz6addd812016-02-02 17:17:23 -0700632VkResult ShaderModule::init_try(const Device &dev,
633 const VkShaderModuleCreateInfo &info) {
Chia-I Wu4d0c7922015-07-03 11:49:42 +0800634 VkShaderModule mod;
635
Chia-I Wuf7458c52015-10-26 21:10:41 +0800636 VkResult err = vkCreateShaderModule(dev.handle(), &info, NULL, &mod);
Courtney Goeltzenleuchteree4027d2015-06-28 13:01:17 -0600637 if (err == VK_SUCCESS)
Chia-I Wu4d0c7922015-07-03 11:49:42 +0800638 NonDispHandle::init(dev.handle(), mod);
Courtney Goeltzenleuchteree4027d2015-06-28 13:01:17 -0600639
640 return err;
641}
642
Tony Barbour67e99152015-07-10 14:10:27 -0600643NON_DISPATCHABLE_HANDLE_DTOR(Pipeline, vkDestroyPipeline)
Chia-I Wu2ff72fd2015-07-03 11:49:42 +0800644
Karl Schultz6addd812016-02-02 17:17:23 -0700645void Pipeline::init(const Device &dev,
646 const VkGraphicsPipelineCreateInfo &info) {
Jon Ashburnc669cc62015-07-09 15:02:25 -0600647 VkPipelineCache cache;
648 VkPipelineCacheCreateInfo ci;
Karl Schultz6addd812016-02-02 17:17:23 -0700649 memset((void *)&ci, 0, sizeof(VkPipelineCacheCreateInfo));
Jon Ashburnc669cc62015-07-09 15:02:25 -0600650 ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
Chia-I Wuf7458c52015-10-26 21:10:41 +0800651 VkResult err = vkCreatePipelineCache(dev.handle(), &ci, NULL, &cache);
Jon Ashburnc669cc62015-07-09 15:02:25 -0600652 if (err == VK_SUCCESS) {
Karl Schultz6addd812016-02-02 17:17:23 -0700653 NON_DISPATCHABLE_HANDLE_INIT(vkCreateGraphicsPipelines, dev, cache, 1,
654 &info);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800655 vkDestroyPipelineCache(dev.handle(), cache, NULL);
Jon Ashburnc669cc62015-07-09 15:02:25 -0600656 }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800657}
658
Karl Schultz6addd812016-02-02 17:17:23 -0700659VkResult Pipeline::init_try(const Device &dev,
660 const VkGraphicsPipelineCreateInfo &info) {
Chris Forbes95292b12015-05-25 11:13:26 +1200661 VkPipeline pipe;
Jon Ashburnc669cc62015-07-09 15:02:25 -0600662 VkPipelineCache cache;
663 VkPipelineCacheCreateInfo ci;
Karl Schultz6addd812016-02-02 17:17:23 -0700664 memset((void *)&ci, 0, sizeof(VkPipelineCacheCreateInfo));
Jon Ashburnc669cc62015-07-09 15:02:25 -0600665 ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
Chia-I Wuf7458c52015-10-26 21:10:41 +0800666 VkResult err = vkCreatePipelineCache(dev.handle(), &ci, NULL, &cache);
Chia-I Wuf368b602015-07-03 10:41:20 +0800667 EXPECT(err == VK_SUCCESS);
Chris Forbes95292b12015-05-25 11:13:26 +1200668 if (err == VK_SUCCESS) {
Karl Schultz6addd812016-02-02 17:17:23 -0700669 err = vkCreateGraphicsPipelines(dev.handle(), cache, 1, &info, NULL,
670 &pipe);
Jon Ashburnc669cc62015-07-09 15:02:25 -0600671 if (err == VK_SUCCESS) {
Chia-I Wu2ff72fd2015-07-03 11:49:42 +0800672 NonDispHandle::init(dev.handle(), pipe);
Jon Ashburnc669cc62015-07-09 15:02:25 -0600673 }
Chia-I Wuf7458c52015-10-26 21:10:41 +0800674 vkDestroyPipelineCache(dev.handle(), cache, NULL);
Chris Forbes95292b12015-05-25 11:13:26 +1200675 }
676
677 return err;
678}
679
Karl Schultz6addd812016-02-02 17:17:23 -0700680void Pipeline::init(const Device &dev,
681 const VkComputePipelineCreateInfo &info) {
Jon Ashburnc669cc62015-07-09 15:02:25 -0600682 VkPipelineCache cache;
683 VkPipelineCacheCreateInfo ci;
Karl Schultz6addd812016-02-02 17:17:23 -0700684 memset((void *)&ci, 0, sizeof(VkPipelineCacheCreateInfo));
Jon Ashburnc669cc62015-07-09 15:02:25 -0600685 ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
Chia-I Wuf7458c52015-10-26 21:10:41 +0800686 VkResult err = vkCreatePipelineCache(dev.handle(), &ci, NULL, &cache);
Jon Ashburnc669cc62015-07-09 15:02:25 -0600687 if (err == VK_SUCCESS) {
Karl Schultz6addd812016-02-02 17:17:23 -0700688 NON_DISPATCHABLE_HANDLE_INIT(vkCreateComputePipelines, dev, cache, 1,
689 &info);
Chia-I Wuf7458c52015-10-26 21:10:41 +0800690 vkDestroyPipelineCache(dev.handle(), cache, NULL);
Jon Ashburnc669cc62015-07-09 15:02:25 -0600691 }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800692}
693
Tony Barbour67e99152015-07-10 14:10:27 -0600694NON_DISPATCHABLE_HANDLE_DTOR(PipelineLayout, vkDestroyPipelineLayout)
Chia-I Wufd46e7d2015-07-03 11:49:42 +0800695
Karl Schultz6addd812016-02-02 17:17:23 -0700696void PipelineLayout::init(
697 const Device &dev, VkPipelineLayoutCreateInfo &info,
698 const std::vector<const DescriptorSetLayout *> &layouts) {
699 const std::vector<VkDescriptorSetLayout> layout_handles =
700 make_handles<VkDescriptorSetLayout>(layouts);
Tony Barbour482c6092015-07-27 09:37:48 -0600701 info.pSetLayouts = layout_handles.data();
Chia-I Wufd46e7d2015-07-03 11:49:42 +0800702
703 NON_DISPATCHABLE_HANDLE_INIT(vkCreatePipelineLayout, dev, &info);
704}
705
Tony Barbour67e99152015-07-10 14:10:27 -0600706NON_DISPATCHABLE_HANDLE_DTOR(Sampler, vkDestroySampler)
Chia-I Wu8c721c62015-07-03 11:49:42 +0800707
Karl Schultz6addd812016-02-02 17:17:23 -0700708void Sampler::init(const Device &dev, const VkSamplerCreateInfo &info) {
Chia-I Wu8c721c62015-07-03 11:49:42 +0800709 NON_DISPATCHABLE_HANDLE_INIT(vkCreateSampler, dev, &info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800710}
711
Tony Barbour67e99152015-07-10 14:10:27 -0600712NON_DISPATCHABLE_HANDLE_DTOR(DescriptorSetLayout, vkDestroyDescriptorSetLayout)
Chia-I Wuafdfd7f2015-07-03 11:49:42 +0800713
Karl Schultz6addd812016-02-02 17:17:23 -0700714void DescriptorSetLayout::init(const Device &dev,
715 const VkDescriptorSetLayoutCreateInfo &info) {
Chia-I Wuafdfd7f2015-07-03 11:49:42 +0800716 NON_DISPATCHABLE_HANDLE_INIT(vkCreateDescriptorSetLayout, dev, &info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800717}
718
Tony Barbour67e99152015-07-10 14:10:27 -0600719NON_DISPATCHABLE_HANDLE_DTOR(DescriptorPool, vkDestroyDescriptorPool)
Chia-I Wuafdfd7f2015-07-03 11:49:42 +0800720
Karl Schultz6addd812016-02-02 17:17:23 -0700721void DescriptorPool::init(const Device &dev,
722 const VkDescriptorPoolCreateInfo &info) {
723 setDynamicUsage(info.flags &
724 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT);
Courtney Goeltzenleuchterfe908d32015-09-16 16:12:45 -0600725 NON_DISPATCHABLE_HANDLE_INIT(vkCreateDescriptorPool, dev, &info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800726}
727
Karl Schultz6addd812016-02-02 17:17:23 -0700728void DescriptorPool::reset() {
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -0600729 EXPECT(vkResetDescriptorPool(device(), handle(), 0) == VK_SUCCESS);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800730}
731
Karl Schultz6addd812016-02-02 17:17:23 -0700732std::vector<DescriptorSet *> DescriptorPool::alloc_sets(
733 const Device &dev,
734 const std::vector<const DescriptorSetLayout *> &layouts) {
735 const std::vector<VkDescriptorSetLayout> layout_handles =
736 make_handles<VkDescriptorSetLayout>(layouts);
Chia-I Wu11078b02015-01-04 16:27:24 +0800737
Chia-I Wuafdfd7f2015-07-03 11:49:42 +0800738 std::vector<VkDescriptorSet> set_handles;
739 set_handles.resize(layout_handles.size());
Chia-I Wu11078b02015-01-04 16:27:24 +0800740
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800741 VkDescriptorSetAllocateInfo alloc_info = {};
Chia-I Wu00ce5402015-11-10 16:21:09 +0800742 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
Jon Ashburnf19916e2016-01-11 13:12:43 -0700743 alloc_info.descriptorSetCount = layout_handles.size();
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -0600744 alloc_info.descriptorPool = handle();
745 alloc_info.pSetLayouts = layout_handles.data();
Karl Schultz6addd812016-02-02 17:17:23 -0700746 VkResult err =
747 vkAllocateDescriptorSets(device(), &alloc_info, set_handles.data());
Cody Northrop1e4f8022015-08-03 12:47:29 -0600748 EXPECT(err == VK_SUCCESS);
Chia-I Wu11078b02015-01-04 16:27:24 +0800749
750 std::vector<DescriptorSet *> sets;
Karl Schultz6addd812016-02-02 17:17:23 -0700751 for (std::vector<VkDescriptorSet>::const_iterator it = set_handles.begin();
752 it != set_handles.end(); it++) {
Chia-I Wu11078b02015-01-04 16:27:24 +0800753 // do descriptor sets need memories bound?
Cody Northropcdc72a42015-10-08 11:39:25 -0600754 DescriptorSet *descriptorSet = new DescriptorSet(dev, this, *it);
Mark Lobodzinski40f7f402015-04-16 11:44:05 -0500755 sets.push_back(descriptorSet);
Chia-I Wu11078b02015-01-04 16:27:24 +0800756 }
Chia-I Wu11078b02015-01-04 16:27:24 +0800757 return sets;
758}
759
Karl Schultz6addd812016-02-02 17:17:23 -0700760std::vector<DescriptorSet *>
761DescriptorPool::alloc_sets(const Device &dev, const DescriptorSetLayout &layout,
762 uint32_t count) {
763 return alloc_sets(dev,
764 std::vector<const DescriptorSetLayout *>(count, &layout));
Chia-I Wu11078b02015-01-04 16:27:24 +0800765}
766
Karl Schultz6addd812016-02-02 17:17:23 -0700767DescriptorSet *DescriptorPool::alloc_sets(const Device &dev,
768 const DescriptorSetLayout &layout) {
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -0600769 std::vector<DescriptorSet *> set = alloc_sets(dev, layout, 1);
Chia-I Wu11078b02015-01-04 16:27:24 +0800770 return (set.empty()) ? NULL : set[0];
771}
772
Karl Schultz6addd812016-02-02 17:17:23 -0700773DescriptorSet::~DescriptorSet() {
Tony Barbour67e99152015-07-10 14:10:27 -0600774 if (initialized()) {
Cody Northropcdc72a42015-10-08 11:39:25 -0600775 // Only call vkFree* on sets allocated from pool with usage *_DYNAMIC
776 if (containing_pool_->getDynamicUsage()) {
Karl Schultz6addd812016-02-02 17:17:23 -0700777 VkDescriptorSet sets[1] = {handle()};
778 EXPECT(vkFreeDescriptorSets(device(), containing_pool_->GetObj(), 1,
779 sets) == VK_SUCCESS);
Cody Northropcdc72a42015-10-08 11:39:25 -0600780 }
Tony Barbour67e99152015-07-10 14:10:27 -0600781 }
782}
Chia-I Wuafdfd7f2015-07-03 11:49:42 +0800783
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800784NON_DISPATCHABLE_HANDLE_DTOR(CommandPool, vkDestroyCommandPool)
Courtney Goeltzenleuchteree5d80b2015-07-10 19:50:17 -0600785
Karl Schultz6addd812016-02-02 17:17:23 -0700786void CommandPool::init(const Device &dev, const VkCommandPoolCreateInfo &info) {
Courtney Goeltzenleuchteree5d80b2015-07-10 19:50:17 -0600787 NON_DISPATCHABLE_HANDLE_INIT(vkCreateCommandPool, dev, &info);
788}
789
Karl Schultz6addd812016-02-02 17:17:23 -0700790CommandBuffer::~CommandBuffer() {
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -0600791 if (initialized()) {
Karl Schultz6addd812016-02-02 17:17:23 -0700792 VkCommandBuffer cmds[] = {handle()};
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -0600793 vkFreeCommandBuffers(dev_handle_, cmd_pool_, 1, cmds);
794 }
Chia-I Wube2b9172015-07-03 11:49:42 +0800795}
796
Karl Schultz6addd812016-02-02 17:17:23 -0700797void CommandBuffer::init(const Device &dev,
798 const VkCommandBufferAllocateInfo &info) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800799 VkCommandBuffer cmd;
Chia-I Wube2b9172015-07-03 11:49:42 +0800800
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800801 // Make sure commandPool is set
802 assert(info.commandPool);
Courtney Goeltzenleuchterd8e68bb2015-07-13 12:53:32 -0600803
Karl Schultz6addd812016-02-02 17:17:23 -0700804 if (EXPECT(vkAllocateCommandBuffers(dev.handle(), &info, &cmd) ==
805 VK_SUCCESS)) {
Chia-I Wube2b9172015-07-03 11:49:42 +0800806 Handle::init(cmd);
807 dev_handle_ = dev.handle();
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800808 cmd_pool_ = info.commandPool;
Chia-I Wube2b9172015-07-03 11:49:42 +0800809 }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800810}
811
Karl Schultz6addd812016-02-02 17:17:23 -0700812void CommandBuffer::begin(const VkCommandBufferBeginInfo *info) {
Chia-I Wube2b9172015-07-03 11:49:42 +0800813 EXPECT(vkBeginCommandBuffer(handle(), info) == VK_SUCCESS);
Jeremy Hayesd65ae082015-01-14 16:17:08 -0700814}
815
Karl Schultz6addd812016-02-02 17:17:23 -0700816void CommandBuffer::begin() {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800817 VkCommandBufferBeginInfo info = {};
Jon Ashburnf19916e2016-01-11 13:12:43 -0700818 VkCommandBufferInheritanceInfo hinfo = {};
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800819 info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
820 info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
Jon Ashburnf19916e2016-01-11 13:12:43 -0700821 info.pInheritanceInfo = &hinfo;
822 hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
823 hinfo.pNext = NULL;
824 hinfo.renderPass = VK_NULL_HANDLE;
825 hinfo.subpass = 0;
826 hinfo.framebuffer = VK_NULL_HANDLE;
827 hinfo.occlusionQueryEnable = VK_FALSE;
828 hinfo.queryFlags = 0;
829 hinfo.pipelineStatistics = 0;
Jeremy Hayesd65ae082015-01-14 16:17:08 -0700830
831 begin(&info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800832}
833
Karl Schultz6addd812016-02-02 17:17:23 -0700834void CommandBuffer::end() {
Chia-I Wube2b9172015-07-03 11:49:42 +0800835 EXPECT(vkEndCommandBuffer(handle()) == VK_SUCCESS);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800836}
837
Karl Schultz6addd812016-02-02 17:17:23 -0700838void CommandBuffer::reset(VkCommandBufferResetFlags flags) {
Cody Northrope62183e2015-07-09 18:08:05 -0600839 EXPECT(vkResetCommandBuffer(handle(), flags) == VK_SUCCESS);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800840}
841
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600842}; // namespace vk_testing