blob: 8714c5b54cf6b0f7a7db0eca06ae2673d6206a23 [file] [log] [blame]
Karl Schultz99e9d1d2016-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 Schultz99e9d1d2016-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 Wu82bff272014-12-27 14:12:52 +080028
29#include <iostream>
30#include <string.h> // memset(), memcmp()
Courtney Goeltzenleuchter6d55b9c2015-04-19 19:07:33 -060031#include <assert.h>
Tony Barboure84a8d62015-07-10 14:10:27 -060032#include <stdarg.h>
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060033#include "vktestbinding.h"
Chia-I Wu82bff272014-12-27 14:12:52 +080034
35namespace {
Chia-I Wu82bff272014-12-27 14:12:52 +080036
Karl Schultz99e9d1d2016-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 Wuba0836f2015-07-03 10:58:57 +080043 } while (0)
44
Karl Schultz99e9d1d2016-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 Wua4992342015-07-03 11:45:55 +080049 }
50
Chia-I Wu82bff272014-12-27 14:12:52 +080051#define STRINGIFY(x) #x
Karl Schultz99e9d1d2016-02-02 17:17:23 -070052#define EXPECT(expr) \
53 ((expr) ? true : expect_failure(STRINGIFY(expr), __FILE__, __LINE__, \
54 __FUNCTION__))
Chia-I Wu82bff272014-12-27 14:12:52 +080055
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060056vk_testing::ErrorCallback error_callback;
Chia-I Wu82bff272014-12-27 14:12:52 +080057
Karl Schultz99e9d1d2016-02-02 17:17:23 -070058bool expect_failure(const char *expr, const char *file, unsigned int line,
59 const char *function) {
Chia-I Wu82bff272014-12-27 14:12:52 +080060 if (error_callback) {
61 error_callback(expr, file, line, function);
62 } else {
Karl Schultz99e9d1d2016-02-02 17:17:23 -070063 std::cerr << file << ":" << line << ": " << function
64 << ": Expectation `" << expr << "' failed.\n";
Chia-I Wu82bff272014-12-27 14:12:52 +080065 }
66
67 return false;
68}
69
Karl Schultz99e9d1d2016-02-02 17:17:23 -070070template <class T, class S>
71std::vector<T> make_handles(const std::vector<S> &v) {
Chia-I Wua4992342015-07-03 11:45:55 +080072 std::vector<T> handles;
73 handles.reserve(v.size());
Karl Schultz99e9d1d2016-02-02 17:17:23 -070074 for (typename std::vector<S>::const_iterator it = v.begin(); it != v.end();
75 it++)
Chia-I Wua4992342015-07-03 11:45:55 +080076 handles.push_back((*it)->handle());
77 return handles;
78}
79
Karl Schultz99e9d1d2016-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 Wuf4aed6c2015-07-03 13:44:34 +080085 dev.phy().set_memory_type(reqs.memoryTypeBits, &info, mem_props);
Chia-I Wu82bff272014-12-27 14:12:52 +080086
87 return info;
88}
Chia-I Wuf4aed6c2015-07-03 13:44:34 +080089
Chia-I Wu82bff272014-12-27 14:12:52 +080090} // namespace
91
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060092namespace vk_testing {
Chia-I Wu82bff272014-12-27 14:12:52 +080093
Karl Schultz99e9d1d2016-02-02 17:17:23 -070094void set_error_callback(ErrorCallback callback) { error_callback = callback; }
Chia-I Wu82bff272014-12-27 14:12:52 +080095
Karl Schultz99e9d1d2016-02-02 17:17:23 -070096VkPhysicalDeviceProperties PhysicalDevice::properties() const {
Tony Barbour426b9052015-06-24 16:06:58 -060097 VkPhysicalDeviceProperties info;
98
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -060099 vkGetPhysicalDeviceProperties(handle(), &info);
Tony Barbour426b9052015-06-24 16:06:58 -0600100
101 return info;
Chia-I Wu82bff272014-12-27 14:12:52 +0800102}
103
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700104std::vector<VkQueueFamilyProperties> PhysicalDevice::queue_properties() const {
Cody Northropef72e2a2015-08-03 17:04:53 -0600105 std::vector<VkQueueFamilyProperties> info;
Tony Barbour426b9052015-06-24 16:06:58 -0600106 uint32_t count;
107
Cody Northropef72e2a2015-08-03 17:04:53 -0600108 // Call once with NULL data to receive count
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600109 vkGetPhysicalDeviceQueueFamilyProperties(handle(), &count, NULL);
110 info.resize(count);
111 vkGetPhysicalDeviceQueueFamilyProperties(handle(), &count, info.data());
Tony Barbour426b9052015-06-24 16:06:58 -0600112
113 return info;
Chia-I Wu82bff272014-12-27 14:12:52 +0800114}
115
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700116VkPhysicalDeviceMemoryProperties PhysicalDevice::memory_properties() const {
Tony Barbour426b9052015-06-24 16:06:58 -0600117 VkPhysicalDeviceMemoryProperties info;
118
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600119 vkGetPhysicalDeviceMemoryProperties(handle(), &info);
Mark Lobodzinski72346292015-07-02 16:49:40 -0600120
Tony Barbour426b9052015-06-24 16:06:58 -0600121 return info;
Chia-I Wu82bff272014-12-27 14:12:52 +0800122}
123
Chris Forbes90479f42016-04-04 17:22:42 +1200124VkPhysicalDeviceFeatures PhysicalDevice::features() const {
125 VkPhysicalDeviceFeatures features;
126 vkGetPhysicalDeviceFeatures(handle(), &features);
127 return features;
128}
129
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600130/*
131 * Return list of Global layers available
132 */
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700133std::vector<VkLayerProperties> GetGlobalLayers() {
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600134 VkResult err;
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600135 std::vector<VkLayerProperties> layers;
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600136 uint32_t layer_count;
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600137
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600138 do {
139 layer_count = 0;
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600140 err = vkEnumerateInstanceLayerProperties(&layer_count, NULL);
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600141
142 if (err == VK_SUCCESS) {
143 layers.reserve(layer_count);
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700144 err =
145 vkEnumerateInstanceLayerProperties(&layer_count, layers.data());
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600146 }
147 } while (err == VK_INCOMPLETE);
148
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600149 assert(err == VK_SUCCESS);
150
151 return layers;
Chia-I Wu82bff272014-12-27 14:12:52 +0800152}
153
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600154/*
155 * Return list of Global extensions provided by the ICD / Loader
156 */
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700157std::vector<VkExtensionProperties> GetGlobalExtensions() {
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600158 return GetGlobalExtensions(NULL);
159}
160
161/*
162 * Return list of Global extensions provided by the specified layer
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700163 * If pLayerName is NULL, will return extensions implemented by the loader /
164 * ICDs
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600165 */
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700166std::vector<VkExtensionProperties> GetGlobalExtensions(const char *pLayerName) {
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600167 std::vector<VkExtensionProperties> exts;
168 uint32_t ext_count;
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600169 VkResult err;
170
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600171 do {
172 ext_count = 0;
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700173 err = vkEnumerateInstanceExtensionProperties(pLayerName, &ext_count,
174 NULL);
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600175
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600176 if (err == VK_SUCCESS) {
Courtney Goeltzenleuchterb774fb42015-07-06 15:45:58 -0600177 exts.resize(ext_count);
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700178 err = vkEnumerateInstanceExtensionProperties(pLayerName, &ext_count,
179 exts.data());
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600180 }
181 } while (err == VK_INCOMPLETE);
182
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600183 assert(err == VK_SUCCESS);
184
185 return exts;
186}
187
188/*
189 * Return list of PhysicalDevice extensions provided by the ICD / Loader
190 */
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700191std::vector<VkExtensionProperties> PhysicalDevice::extensions() const {
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600192 return extensions(NULL);
193}
194
195/*
196 * Return list of PhysicalDevice extensions provided by the specified layer
197 * If pLayerName is NULL, will return extensions for ICD / loader.
198 */
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700199std::vector<VkExtensionProperties>
200PhysicalDevice::extensions(const char *pLayerName) const {
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600201 std::vector<VkExtensionProperties> exts;
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600202 VkResult err;
203
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600204 do {
205 uint32_t extCount = 0;
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700206 err = vkEnumerateDeviceExtensionProperties(handle(), pLayerName,
207 &extCount, NULL);
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600208
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600209 if (err == VK_SUCCESS) {
Ian Elliott331f4e82015-07-06 14:33:04 -0600210 exts.resize(extCount);
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700211 err = vkEnumerateDeviceExtensionProperties(handle(), pLayerName,
212 &extCount, exts.data());
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600213 }
214 } while (err == VK_INCOMPLETE);
215
Courtney Goeltzenleuchter18061cd2015-06-29 15:39:26 -0600216 assert(err == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800217
218 return exts;
219}
220
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700221bool PhysicalDevice::set_memory_type(const uint32_t type_bits,
222 VkMemoryAllocateInfo *info,
223 const VkFlags properties,
224 const VkFlags forbid) const {
225 uint32_t type_mask = type_bits;
226 // Search memtypes to find first index with those properties
227 for (uint32_t i = 0; i < memory_properties_.memoryTypeCount; i++) {
228 if ((type_mask & 1) == 1) {
229 // Type is available, does it match user properties?
230 if ((memory_properties_.memoryTypes[i].propertyFlags &
231 properties) == properties &&
232 (memory_properties_.memoryTypes[i].propertyFlags & forbid) ==
233 0) {
234 info->memoryTypeIndex = i;
235 return true;
236 }
237 }
238 type_mask >>= 1;
239 }
240 // No memory types matched, return failure
241 return false;
Mark Lobodzinski72346292015-07-02 16:49:40 -0600242}
243
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600244/*
245 * Return list of PhysicalDevice layers
246 */
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700247std::vector<VkLayerProperties> PhysicalDevice::layers() const {
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600248 std::vector<VkLayerProperties> layer_props;
249 VkResult err;
250
251 do {
252 uint32_t layer_count = 0;
Courtney Goeltzenleuchter74c4ce92015-09-14 17:22:16 -0600253 err = vkEnumerateDeviceLayerProperties(handle(), &layer_count, NULL);
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600254
255 if (err == VK_SUCCESS) {
256 layer_props.reserve(layer_count);
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700257 err = vkEnumerateDeviceLayerProperties(handle(), &layer_count,
258 layer_props.data());
Courtney Goeltzenleuchterf5c61952015-07-06 09:10:47 -0600259 }
260 } while (err == VK_INCOMPLETE);
261
262 assert(err == VK_SUCCESS);
263
264 return layer_props;
265}
266
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700267Device::~Device() {
Chia-I Wu82bff272014-12-27 14:12:52 +0800268 if (!initialized())
269 return;
270
271 for (int i = 0; i < QUEUE_COUNT; i++) {
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700272 for (std::vector<Queue *>::iterator it = queues_[i].begin();
273 it != queues_[i].end(); it++)
Chia-I Wu82bff272014-12-27 14:12:52 +0800274 delete *it;
275 queues_[i].clear();
276 }
277
Chia-I Wu69f40122015-10-26 21:10:41 +0800278 vkDestroyDevice(handle(), NULL);
Chia-I Wu82bff272014-12-27 14:12:52 +0800279}
280
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700281void Device::init(std::vector<const char *> &layers,
282 std::vector<const char *> &extensions) {
Chia-I Wu82bff272014-12-27 14:12:52 +0800283 // request all queues
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700284 const std::vector<VkQueueFamilyProperties> queue_props =
285 phy_.queue_properties();
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600286 std::vector<VkDeviceQueueCreateInfo> queue_info;
Chia-I Wu82bff272014-12-27 14:12:52 +0800287 queue_info.reserve(queue_props.size());
Mark Lobodzinski47c60bd2016-02-01 09:06:25 -0700288
289 std::vector<std::vector<float>> queue_priorities;
290
Mark Young2acdd152016-01-13 13:47:16 -0700291 for (uint32_t i = 0; i < (uint32_t)queue_props.size(); i++) {
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600292 VkDeviceQueueCreateInfo qi = {};
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700293 qi.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
294 qi.pNext = NULL;
295 qi.queueFamilyIndex = i;
296 qi.queueCount = queue_props[i].queueCount;
Mark Lobodzinski47c60bd2016-02-01 09:06:25 -0700297
Dustin Graves20f5fc02016-04-06 10:16:05 -0600298 queue_priorities.emplace_back(qi.queueCount, 0.0f);
Mark Lobodzinski47c60bd2016-02-01 09:06:25 -0700299
300 qi.pQueuePriorities = queue_priorities[i].data();
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600301 if (queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700302 graphics_queue_node_index_ = i;
303 }
Chia-I Wu82bff272014-12-27 14:12:52 +0800304 queue_info.push_back(qi);
305 }
306
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600307 VkDeviceCreateInfo dev_info = {};
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600308 dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
Courtney Goeltzenleuchter1c7c65d2015-06-10 17:39:03 -0600309 dev_info.pNext = NULL;
Chia-I Wu045654f2015-11-06 06:42:02 +0800310 dev_info.queueCreateInfoCount = queue_info.size();
311 dev_info.pQueueCreateInfos = queue_info.data();
Jon Ashburna4ae48b2016-01-11 13:12:43 -0700312 dev_info.enabledLayerCount = layers.size();
Tony Barbourb0ae8c12015-07-27 09:37:48 -0600313 dev_info.ppEnabledLayerNames = layers.data();
Jon Ashburna4ae48b2016-01-11 13:12:43 -0700314 dev_info.enabledExtensionCount = extensions.size();
Tony Barbourb0ae8c12015-07-27 09:37:48 -0600315 dev_info.ppEnabledExtensionNames = extensions.data();
Chia-I Wu82bff272014-12-27 14:12:52 +0800316
Chris Forbes90479f42016-04-04 17:22:42 +1200317 // request all supportable features enabled
318 auto features = phy().features();
319 dev_info.pEnabledFeatures = &features;
320
Chia-I Wu82bff272014-12-27 14:12:52 +0800321 init(dev_info);
322}
323
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700324void Device::init(const VkDeviceCreateInfo &info) {
Chia-I Wua2636292015-07-03 10:41:20 +0800325 VkDevice dev;
326
Chia-I Wu69f40122015-10-26 21:10:41 +0800327 if (EXPECT(vkCreateDevice(phy_.handle(), &info, NULL, &dev) == VK_SUCCESS))
Chia-I Wua2636292015-07-03 10:41:20 +0800328 Handle::init(dev);
Chia-I Wu82bff272014-12-27 14:12:52 +0800329
330 init_queues();
Chia-I Wu82bff272014-12-27 14:12:52 +0800331 init_formats();
332}
333
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700334void Device::init_queues() {
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700335 uint32_t queue_node_count;
Chia-I Wu82bff272014-12-27 14:12:52 +0800336
Cody Northropef72e2a2015-08-03 17:04:53 -0600337 // Call with NULL data to get count
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700338 vkGetPhysicalDeviceQueueFamilyProperties(phy_.handle(), &queue_node_count,
339 NULL);
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700340 EXPECT(queue_node_count >= 1);
341
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700342 VkQueueFamilyProperties *queue_props =
343 new VkQueueFamilyProperties[queue_node_count];
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700344
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700345 vkGetPhysicalDeviceQueueFamilyProperties(phy_.handle(), &queue_node_count,
346 queue_props);
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700347
Tony Barbour8bef8ee2015-05-22 09:44:58 -0600348 for (uint32_t i = 0; i < queue_node_count; i++) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600349 VkQueue queue;
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700350
Tony Barbour8bef8ee2015-05-22 09:44:58 -0600351 for (uint32_t j = 0; j < queue_props[i].queueCount; j++) {
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700352 // TODO: Need to add support for separate MEMMGR and work queues,
353 // including synchronization
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600354 vkGetDeviceQueue(handle(), i, j, &queue);
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700355
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600356 if (queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
Tony Barbour0caa94f2015-07-23 10:35:30 -0600357 queues_[GRAPHICS].push_back(new Queue(queue, i));
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700358 }
359
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600360 if (queue_props[i].queueFlags & VK_QUEUE_COMPUTE_BIT) {
Tony Barbour0caa94f2015-07-23 10:35:30 -0600361 queues_[COMPUTE].push_back(new Queue(queue, i));
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700362 }
363
Chia-I Wuc51b1212015-10-27 19:25:11 +0800364 if (queue_props[i].queueFlags & VK_QUEUE_TRANSFER_BIT) {
Tony Barbour0caa94f2015-07-23 10:35:30 -0600365 queues_[DMA].push_back(new Queue(queue, i));
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700366 }
Chia-I Wu82bff272014-12-27 14:12:52 +0800367 }
368 }
369
Chris Forbes4506d3f2015-06-04 10:49:27 +1200370 delete[] queue_props;
Tony Barbour25e3b832015-05-20 16:53:31 -0600371
Chia-I Wu82bff272014-12-27 14:12:52 +0800372 EXPECT(!queues_[GRAPHICS].empty() || !queues_[COMPUTE].empty());
373}
374
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700375void Device::init_formats() {
Tony Barbour8205d902015-04-16 15:59:00 -0600376 for (int f = VK_FORMAT_BEGIN_RANGE; f <= VK_FORMAT_END_RANGE; f++) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600377 const VkFormat fmt = static_cast<VkFormat>(f);
378 const VkFormatProperties props = format_properties(fmt);
Chia-I Wu82bff272014-12-27 14:12:52 +0800379
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700380 if (props.linearTilingFeatures) {
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700381 const Format tmp = {fmt, VK_IMAGE_TILING_LINEAR,
382 props.linearTilingFeatures};
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700383 formats_.push_back(tmp);
384 }
Chia-I Wu82bff272014-12-27 14:12:52 +0800385
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700386 if (props.optimalTilingFeatures) {
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700387 const Format tmp = {fmt, VK_IMAGE_TILING_OPTIMAL,
388 props.optimalTilingFeatures};
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700389 formats_.push_back(tmp);
Chia-I Wu82bff272014-12-27 14:12:52 +0800390 }
391 }
392
393 EXPECT(!formats_.empty());
394}
395
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700396VkFormatProperties Device::format_properties(VkFormat format) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600397 VkFormatProperties data;
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600398 vkGetPhysicalDeviceFormatProperties(phy().handle(), format, &data);
Chia-I Wu82bff272014-12-27 14:12:52 +0800399
400 return data;
401}
402
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700403void Device::wait() { EXPECT(vkDeviceWaitIdle(handle()) == VK_SUCCESS); }
Chia-I Wu82bff272014-12-27 14:12:52 +0800404
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700405VkResult Device::wait(const std::vector<const Fence *> &fences, bool wait_all,
406 uint64_t timeout) {
Chia-I Wua4992342015-07-03 11:45:55 +0800407 const std::vector<VkFence> fence_handles = make_handles<VkFence>(fences);
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700408 VkResult err = vkWaitForFences(handle(), fence_handles.size(),
409 fence_handles.data(), wait_all, timeout);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600410 EXPECT(err == VK_SUCCESS || err == VK_TIMEOUT);
Chia-I Wu82bff272014-12-27 14:12:52 +0800411
412 return err;
413}
414
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700415void Device::update_descriptor_sets(
416 const std::vector<VkWriteDescriptorSet> &writes,
417 const std::vector<VkCopyDescriptorSet> &copies) {
418 vkUpdateDescriptorSets(handle(), writes.size(), writes.data(),
419 copies.size(), copies.data());
Chia-I Wu8cd8ecd2015-05-25 16:27:55 +0800420}
421
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700422void Queue::submit(const std::vector<const CommandBuffer *> &cmds,
423 Fence &fence) {
424 const std::vector<VkCommandBuffer> cmd_handles =
425 make_handles<VkCommandBuffer>(cmds);
Courtney Goeltzenleuchter1a748e92015-10-27 11:22:14 -0600426 VkSubmitInfo submit_info;
Chia-I Wu6ec33a02015-10-26 20:37:06 +0800427 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
428 submit_info.pNext = NULL;
Chia-I Wu763a7492015-10-26 20:48:51 +0800429 submit_info.waitSemaphoreCount = 0;
Courtney Goeltzenleuchter1a748e92015-10-27 11:22:14 -0600430 submit_info.pWaitSemaphores = NULL;
Jon Ashburn98ce7e02015-12-30 16:42:50 -0700431 submit_info.pWaitDstStageMask = NULL;
Chia-I Wu763a7492015-10-26 20:48:51 +0800432 submit_info.commandBufferCount = (uint32_t)cmd_handles.size();
Courtney Goeltzenleuchter1a748e92015-10-27 11:22:14 -0600433 submit_info.pCommandBuffers = cmd_handles.data();
Chia-I Wu763a7492015-10-26 20:48:51 +0800434 submit_info.signalSemaphoreCount = 0;
Courtney Goeltzenleuchter1a748e92015-10-27 11:22:14 -0600435 submit_info.pSignalSemaphores = NULL;
Courtney Goeltzenleuchter3ec31622015-10-20 18:04:07 -0600436
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700437 EXPECT(vkQueueSubmit(handle(), 1, &submit_info, fence.handle()) ==
438 VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800439}
440
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700441void Queue::submit(const CommandBuffer &cmd, Fence &fence) {
442 submit(std::vector<const CommandBuffer *>(1, &cmd), fence);
Chia-I Wu82bff272014-12-27 14:12:52 +0800443}
444
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700445void Queue::submit(const CommandBuffer &cmd) {
Chia-I Wu82bff272014-12-27 14:12:52 +0800446 Fence fence;
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600447 submit(cmd, fence);
Chia-I Wu82bff272014-12-27 14:12:52 +0800448}
449
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700450void Queue::wait() { EXPECT(vkQueueWaitIdle(handle()) == VK_SUCCESS); }
Chia-I Wu82bff272014-12-27 14:12:52 +0800451
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700452DeviceMemory::~DeviceMemory() {
Chia-I Wuba0836f2015-07-03 10:58:57 +0800453 if (initialized())
Chia-I Wu69f40122015-10-26 21:10:41 +0800454 vkFreeMemory(device(), handle(), NULL);
Chia-I Wu82bff272014-12-27 14:12:52 +0800455}
456
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700457void DeviceMemory::init(const Device &dev, const VkMemoryAllocateInfo &info) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800458 NON_DISPATCHABLE_HANDLE_INIT(vkAllocateMemory, dev, &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800459}
460
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700461const void *DeviceMemory::map(VkFlags flags) const {
Chia-I Wu82bff272014-12-27 14:12:52 +0800462 void *data;
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700463 if (!EXPECT(vkMapMemory(device(), handle(), 0, VK_WHOLE_SIZE, flags,
464 &data) == VK_SUCCESS))
Chia-I Wu82bff272014-12-27 14:12:52 +0800465 data = NULL;
466
467 return data;
468}
469
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700470void *DeviceMemory::map(VkFlags flags) {
Chia-I Wu82bff272014-12-27 14:12:52 +0800471 void *data;
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700472 if (!EXPECT(vkMapMemory(device(), handle(), 0, VK_WHOLE_SIZE, flags,
473 &data) == VK_SUCCESS))
Chia-I Wu82bff272014-12-27 14:12:52 +0800474 data = NULL;
475
476 return data;
477}
478
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700479void DeviceMemory::unmap() const { vkUnmapMemory(device(), handle()); }
Chia-I Wu82bff272014-12-27 14:12:52 +0800480
Tony Barboure84a8d62015-07-10 14:10:27 -0600481NON_DISPATCHABLE_HANDLE_DTOR(Fence, vkDestroyFence)
Chia-I Wua4992342015-07-03 11:45:55 +0800482
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700483void Fence::init(const Device &dev, const VkFenceCreateInfo &info) {
Chia-I Wua4992342015-07-03 11:45:55 +0800484 NON_DISPATCHABLE_HANDLE_INIT(vkCreateFence, dev, &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800485}
486
Tony Barboure84a8d62015-07-10 14:10:27 -0600487NON_DISPATCHABLE_HANDLE_DTOR(Semaphore, vkDestroySemaphore)
Chia-I Wu2454b922015-07-03 11:49:42 +0800488
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700489void Semaphore::init(const Device &dev, const VkSemaphoreCreateInfo &info) {
Chia-I Wu2454b922015-07-03 11:49:42 +0800490 NON_DISPATCHABLE_HANDLE_INIT(vkCreateSemaphore, dev, &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800491}
492
Tony Barboure84a8d62015-07-10 14:10:27 -0600493NON_DISPATCHABLE_HANDLE_DTOR(Event, vkDestroyEvent)
Chia-I Wu9b6db1d2015-07-03 11:49:42 +0800494
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700495void Event::init(const Device &dev, const VkEventCreateInfo &info) {
Chia-I Wu9b6db1d2015-07-03 11:49:42 +0800496 NON_DISPATCHABLE_HANDLE_INIT(vkCreateEvent, dev, &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800497}
498
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700499void Event::set() { EXPECT(vkSetEvent(device(), handle()) == VK_SUCCESS); }
Chia-I Wu82bff272014-12-27 14:12:52 +0800500
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700501void Event::reset() { EXPECT(vkResetEvent(device(), handle()) == VK_SUCCESS); }
Chia-I Wu82bff272014-12-27 14:12:52 +0800502
Tony Barboure84a8d62015-07-10 14:10:27 -0600503NON_DISPATCHABLE_HANDLE_DTOR(QueryPool, vkDestroyQueryPool)
Chia-I Wufd0ce992015-07-03 11:49:42 +0800504
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700505void QueryPool::init(const Device &dev, const VkQueryPoolCreateInfo &info) {
Chia-I Wufd0ce992015-07-03 11:49:42 +0800506 NON_DISPATCHABLE_HANDLE_INIT(vkCreateQueryPool, dev, &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800507}
508
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700509VkResult QueryPool::results(uint32_t first, uint32_t count, size_t size,
510 void *data, size_t stride) {
511 VkResult err = vkGetQueryPoolResults(device(), handle(), first, count, size,
512 data, stride, 0);
Chia-I Wu1f6942d2015-10-26 18:36:20 +0800513 EXPECT(err == VK_SUCCESS || err == VK_NOT_READY);
Chia-I Wu82bff272014-12-27 14:12:52 +0800514
515 return err;
516}
517
Tony Barboure84a8d62015-07-10 14:10:27 -0600518NON_DISPATCHABLE_HANDLE_DTOR(Buffer, vkDestroyBuffer)
Chia-I Wu714df452015-01-01 07:55:04 +0800519
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700520void Buffer::init(const Device &dev, const VkBufferCreateInfo &info,
521 VkMemoryPropertyFlags mem_props) {
Tony Barbour94310562015-04-22 15:10:33 -0600522 init_no_mem(dev, info);
Chia-I Wuf4aed6c2015-07-03 13:44:34 +0800523
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700524 internal_mem_.init(
525 dev, get_resource_alloc_info(dev, memory_requirements(), mem_props));
Chia-I Wuf4aed6c2015-07-03 13:44:34 +0800526 bind_memory(internal_mem_, 0);
Tony Barbour94310562015-04-22 15:10:33 -0600527}
528
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700529void Buffer::init_no_mem(const Device &dev, const VkBufferCreateInfo &info) {
Chia-I Wuf4aed6c2015-07-03 13:44:34 +0800530 NON_DISPATCHABLE_HANDLE_INIT(vkCreateBuffer, dev, &info);
Chia-I Wu714df452015-01-01 07:55:04 +0800531 create_info_ = info;
532}
533
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700534VkMemoryRequirements Buffer::memory_requirements() const {
Chia-I Wuf4aed6c2015-07-03 13:44:34 +0800535 VkMemoryRequirements reqs;
536
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600537 vkGetBufferMemoryRequirements(device(), handle(), &reqs);
Chia-I Wuf4aed6c2015-07-03 13:44:34 +0800538
539 return reqs;
540}
541
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700542void Buffer::bind_memory(const DeviceMemory &mem, VkDeviceSize mem_offset) {
543 EXPECT(vkBindBufferMemory(device(), handle(), mem.handle(), mem_offset) ==
544 VK_SUCCESS);
Mark Lobodzinskifb9f5642015-05-11 17:21:15 -0500545}
546
Tony Barboure84a8d62015-07-10 14:10:27 -0600547NON_DISPATCHABLE_HANDLE_DTOR(BufferView, vkDestroyBufferView)
Chia-I Wu76ab1ff2015-07-03 11:49:42 +0800548
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700549void BufferView::init(const Device &dev, const VkBufferViewCreateInfo &info) {
Chia-I Wu76ab1ff2015-07-03 11:49:42 +0800550 NON_DISPATCHABLE_HANDLE_INIT(vkCreateBufferView, dev, &info);
Chia-I Wu714df452015-01-01 07:55:04 +0800551}
552
Tony Barboure84a8d62015-07-10 14:10:27 -0600553NON_DISPATCHABLE_HANDLE_DTOR(Image, vkDestroyImage)
Chia-I Wu82bff272014-12-27 14:12:52 +0800554
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700555void Image::init(const Device &dev, const VkImageCreateInfo &info,
556 VkMemoryPropertyFlags mem_props) {
Tony Barbour94310562015-04-22 15:10:33 -0600557 init_no_mem(dev, info);
Chia-I Wuf4aed6c2015-07-03 13:44:34 +0800558
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700559 internal_mem_.init(
560 dev, get_resource_alloc_info(dev, memory_requirements(), mem_props));
Chia-I Wuf4aed6c2015-07-03 13:44:34 +0800561 bind_memory(internal_mem_, 0);
Tony Barbour94310562015-04-22 15:10:33 -0600562}
563
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700564void Image::init_no_mem(const Device &dev, const VkImageCreateInfo &info) {
Chia-I Wuf4aed6c2015-07-03 13:44:34 +0800565 NON_DISPATCHABLE_HANDLE_INIT(vkCreateImage, dev, &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800566 init_info(dev, info);
567}
568
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700569void Image::init_info(const Device &dev, const VkImageCreateInfo &info) {
Chia-I Wu82bff272014-12-27 14:12:52 +0800570 create_info_ = info;
571
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700572 for (std::vector<Device::Format>::const_iterator it = dev.formats().begin();
573 it != dev.formats().end(); it++) {
574 if (memcmp(&it->format, &create_info_.format, sizeof(it->format)) ==
575 0 &&
576 it->tiling == create_info_.tiling) {
Chia-I Wu82bff272014-12-27 14:12:52 +0800577 format_features_ = it->features;
578 break;
579 }
580 }
581}
582
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700583VkMemoryRequirements Image::memory_requirements() const {
Chia-I Wuf4aed6c2015-07-03 13:44:34 +0800584 VkMemoryRequirements reqs;
585
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600586 vkGetImageMemoryRequirements(device(), handle(), &reqs);
Chia-I Wuf4aed6c2015-07-03 13:44:34 +0800587
588 return reqs;
589}
590
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700591void Image::bind_memory(const DeviceMemory &mem, VkDeviceSize mem_offset) {
592 EXPECT(vkBindImageMemory(device(), handle(), mem.handle(), mem_offset) ==
593 VK_SUCCESS);
Chia-I Wu714df452015-01-01 07:55:04 +0800594}
595
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700596VkSubresourceLayout
597Image::subresource_layout(const VkImageSubresource &subres) const {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600598 VkSubresourceLayout data;
Chia-I Wu82bff272014-12-27 14:12:52 +0800599 size_t size = sizeof(data);
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600600 vkGetImageSubresourceLayout(device(), handle(), &subres, &data);
601 if (size != sizeof(data))
Chia-I Wu82bff272014-12-27 14:12:52 +0800602 memset(&data, 0, sizeof(data));
603
604 return data;
605}
606
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700607VkSubresourceLayout
608Image::subresource_layout(const VkImageSubresourceLayers &subrescopy) const {
Courtney Goeltzenleuchterbd7f5922015-09-10 16:41:13 -0600609 VkSubresourceLayout data;
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700610 VkImageSubresource subres =
Karl Schultz8da60b02016-03-29 12:41:24 -0600611 subresource(subrescopy.aspectMask, subrescopy.mipLevel,
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700612 subrescopy.baseArrayLayer);
Courtney Goeltzenleuchterbd7f5922015-09-10 16:41:13 -0600613 size_t size = sizeof(data);
Courtney Goeltzenleuchter01d2ae12015-10-20 16:40:38 -0600614 vkGetImageSubresourceLayout(device(), handle(), &subres, &data);
615 if (size != sizeof(data))
Courtney Goeltzenleuchterbd7f5922015-09-10 16:41:13 -0600616 memset(&data, 0, sizeof(data));
617
618 return data;
619}
620
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700621bool Image::transparent() const {
622 return (
623 create_info_.tiling == VK_IMAGE_TILING_LINEAR &&
624 create_info_.samples == VK_SAMPLE_COUNT_1_BIT &&
625 !(create_info_.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
626 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)));
Chia-I Wu82bff272014-12-27 14:12:52 +0800627}
628
Tony Barboure84a8d62015-07-10 14:10:27 -0600629NON_DISPATCHABLE_HANDLE_DTOR(ImageView, vkDestroyImageView)
Chia-I Wu76ab1ff2015-07-03 11:49:42 +0800630
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700631void ImageView::init(const Device &dev, const VkImageViewCreateInfo &info) {
Chia-I Wu76ab1ff2015-07-03 11:49:42 +0800632 NON_DISPATCHABLE_HANDLE_INIT(vkCreateImageView, dev, &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800633}
634
Tony Barboure84a8d62015-07-10 14:10:27 -0600635NON_DISPATCHABLE_HANDLE_DTOR(ShaderModule, vkDestroyShaderModule)
Chia-I Wub48eddb2015-07-03 11:49:42 +0800636
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700637void ShaderModule::init(const Device &dev,
638 const VkShaderModuleCreateInfo &info) {
Chia-I Wub48eddb2015-07-03 11:49:42 +0800639 NON_DISPATCHABLE_HANDLE_INIT(vkCreateShaderModule, dev, &info);
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -0600640}
641
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700642VkResult ShaderModule::init_try(const Device &dev,
643 const VkShaderModuleCreateInfo &info) {
Chia-I Wub48eddb2015-07-03 11:49:42 +0800644 VkShaderModule mod;
645
Chia-I Wu69f40122015-10-26 21:10:41 +0800646 VkResult err = vkCreateShaderModule(dev.handle(), &info, NULL, &mod);
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -0600647 if (err == VK_SUCCESS)
Chia-I Wub48eddb2015-07-03 11:49:42 +0800648 NonDispHandle::init(dev.handle(), mod);
Courtney Goeltzenleuchter2d034fd2015-06-28 13:01:17 -0600649
650 return err;
651}
652
Tony Barboure84a8d62015-07-10 14:10:27 -0600653NON_DISPATCHABLE_HANDLE_DTOR(Pipeline, vkDestroyPipeline)
Chia-I Wu2b1d4d02015-07-03 11:49:42 +0800654
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700655void Pipeline::init(const Device &dev,
656 const VkGraphicsPipelineCreateInfo &info) {
Jon Ashburn0d60d272015-07-09 15:02:25 -0600657 VkPipelineCache cache;
658 VkPipelineCacheCreateInfo ci;
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700659 memset((void *)&ci, 0, sizeof(VkPipelineCacheCreateInfo));
Jon Ashburn0d60d272015-07-09 15:02:25 -0600660 ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
Chia-I Wu69f40122015-10-26 21:10:41 +0800661 VkResult err = vkCreatePipelineCache(dev.handle(), &ci, NULL, &cache);
Jon Ashburn0d60d272015-07-09 15:02:25 -0600662 if (err == VK_SUCCESS) {
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700663 NON_DISPATCHABLE_HANDLE_INIT(vkCreateGraphicsPipelines, dev, cache, 1,
664 &info);
Chia-I Wu69f40122015-10-26 21:10:41 +0800665 vkDestroyPipelineCache(dev.handle(), cache, NULL);
Jon Ashburn0d60d272015-07-09 15:02:25 -0600666 }
Chia-I Wu82bff272014-12-27 14:12:52 +0800667}
668
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700669VkResult Pipeline::init_try(const Device &dev,
670 const VkGraphicsPipelineCreateInfo &info) {
Chris Forbesdc2188c2015-05-25 11:13:26 +1200671 VkPipeline pipe;
Jon Ashburn0d60d272015-07-09 15:02:25 -0600672 VkPipelineCache cache;
673 VkPipelineCacheCreateInfo ci;
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700674 memset((void *)&ci, 0, sizeof(VkPipelineCacheCreateInfo));
Jon Ashburn0d60d272015-07-09 15:02:25 -0600675 ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
Chia-I Wu69f40122015-10-26 21:10:41 +0800676 VkResult err = vkCreatePipelineCache(dev.handle(), &ci, NULL, &cache);
Chia-I Wua2636292015-07-03 10:41:20 +0800677 EXPECT(err == VK_SUCCESS);
Chris Forbesdc2188c2015-05-25 11:13:26 +1200678 if (err == VK_SUCCESS) {
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700679 err = vkCreateGraphicsPipelines(dev.handle(), cache, 1, &info, NULL,
680 &pipe);
Jon Ashburn0d60d272015-07-09 15:02:25 -0600681 if (err == VK_SUCCESS) {
Chia-I Wu2b1d4d02015-07-03 11:49:42 +0800682 NonDispHandle::init(dev.handle(), pipe);
Jon Ashburn0d60d272015-07-09 15:02:25 -0600683 }
Chia-I Wu69f40122015-10-26 21:10:41 +0800684 vkDestroyPipelineCache(dev.handle(), cache, NULL);
Chris Forbesdc2188c2015-05-25 11:13:26 +1200685 }
686
687 return err;
688}
689
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700690void Pipeline::init(const Device &dev,
691 const VkComputePipelineCreateInfo &info) {
Jon Ashburn0d60d272015-07-09 15:02:25 -0600692 VkPipelineCache cache;
693 VkPipelineCacheCreateInfo ci;
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700694 memset((void *)&ci, 0, sizeof(VkPipelineCacheCreateInfo));
Jon Ashburn0d60d272015-07-09 15:02:25 -0600695 ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
Chia-I Wu69f40122015-10-26 21:10:41 +0800696 VkResult err = vkCreatePipelineCache(dev.handle(), &ci, NULL, &cache);
Jon Ashburn0d60d272015-07-09 15:02:25 -0600697 if (err == VK_SUCCESS) {
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700698 NON_DISPATCHABLE_HANDLE_INIT(vkCreateComputePipelines, dev, cache, 1,
699 &info);
Chia-I Wu69f40122015-10-26 21:10:41 +0800700 vkDestroyPipelineCache(dev.handle(), cache, NULL);
Jon Ashburn0d60d272015-07-09 15:02:25 -0600701 }
Chia-I Wu82bff272014-12-27 14:12:52 +0800702}
703
Tony Barboure84a8d62015-07-10 14:10:27 -0600704NON_DISPATCHABLE_HANDLE_DTOR(PipelineLayout, vkDestroyPipelineLayout)
Chia-I Wudeb99132015-07-03 11:49:42 +0800705
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700706void PipelineLayout::init(
707 const Device &dev, VkPipelineLayoutCreateInfo &info,
708 const std::vector<const DescriptorSetLayout *> &layouts) {
709 const std::vector<VkDescriptorSetLayout> layout_handles =
710 make_handles<VkDescriptorSetLayout>(layouts);
Tony Barbourb0ae8c12015-07-27 09:37:48 -0600711 info.pSetLayouts = layout_handles.data();
Chia-I Wudeb99132015-07-03 11:49:42 +0800712
713 NON_DISPATCHABLE_HANDLE_INIT(vkCreatePipelineLayout, dev, &info);
714}
715
Tony Barboure84a8d62015-07-10 14:10:27 -0600716NON_DISPATCHABLE_HANDLE_DTOR(Sampler, vkDestroySampler)
Chia-I Wu6abe35d2015-07-03 11:49:42 +0800717
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700718void Sampler::init(const Device &dev, const VkSamplerCreateInfo &info) {
Chia-I Wu6abe35d2015-07-03 11:49:42 +0800719 NON_DISPATCHABLE_HANDLE_INIT(vkCreateSampler, dev, &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800720}
721
Tony Barboure84a8d62015-07-10 14:10:27 -0600722NON_DISPATCHABLE_HANDLE_DTOR(DescriptorSetLayout, vkDestroyDescriptorSetLayout)
Chia-I Wu55a871f2015-07-03 11:49:42 +0800723
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700724void DescriptorSetLayout::init(const Device &dev,
725 const VkDescriptorSetLayoutCreateInfo &info) {
Chia-I Wu55a871f2015-07-03 11:49:42 +0800726 NON_DISPATCHABLE_HANDLE_INIT(vkCreateDescriptorSetLayout, dev, &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800727}
728
Tony Barboure84a8d62015-07-10 14:10:27 -0600729NON_DISPATCHABLE_HANDLE_DTOR(DescriptorPool, vkDestroyDescriptorPool)
Chia-I Wu55a871f2015-07-03 11:49:42 +0800730
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700731void DescriptorPool::init(const Device &dev,
732 const VkDescriptorPoolCreateInfo &info) {
733 setDynamicUsage(info.flags &
734 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT);
Courtney Goeltzenleuchterd9e966a2015-09-16 16:12:45 -0600735 NON_DISPATCHABLE_HANDLE_INIT(vkCreateDescriptorPool, dev, &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800736}
737
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700738void DescriptorPool::reset() {
Courtney Goeltzenleuchter831c1832015-10-23 14:21:05 -0600739 EXPECT(vkResetDescriptorPool(device(), handle(), 0) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800740}
741
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700742std::vector<DescriptorSet *> DescriptorPool::alloc_sets(
743 const Device &dev,
744 const std::vector<const DescriptorSetLayout *> &layouts) {
745 const std::vector<VkDescriptorSetLayout> layout_handles =
746 make_handles<VkDescriptorSetLayout>(layouts);
Chia-I Wuf8385062015-01-04 16:27:24 +0800747
Chia-I Wu55a871f2015-07-03 11:49:42 +0800748 std::vector<VkDescriptorSet> set_handles;
749 set_handles.resize(layout_handles.size());
Chia-I Wuf8385062015-01-04 16:27:24 +0800750
Chia-I Wu1f851912015-10-27 18:04:07 +0800751 VkDescriptorSetAllocateInfo alloc_info = {};
Chia-I Wuc1f5e402015-11-10 16:21:09 +0800752 alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
Jon Ashburna4ae48b2016-01-11 13:12:43 -0700753 alloc_info.descriptorSetCount = layout_handles.size();
Courtney Goeltzenleuchter831c1832015-10-23 14:21:05 -0600754 alloc_info.descriptorPool = handle();
755 alloc_info.pSetLayouts = layout_handles.data();
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700756 VkResult err =
757 vkAllocateDescriptorSets(device(), &alloc_info, set_handles.data());
Cody Northropc8aa4a52015-08-03 12:47:29 -0600758 EXPECT(err == VK_SUCCESS);
Chia-I Wuf8385062015-01-04 16:27:24 +0800759
760 std::vector<DescriptorSet *> sets;
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700761 for (std::vector<VkDescriptorSet>::const_iterator it = set_handles.begin();
762 it != set_handles.end(); it++) {
Chia-I Wuf8385062015-01-04 16:27:24 +0800763 // do descriptor sets need memories bound?
Cody Northrop35ce7e62015-10-08 11:39:25 -0600764 DescriptorSet *descriptorSet = new DescriptorSet(dev, this, *it);
Mark Lobodzinskicf26e072015-04-16 11:44:05 -0500765 sets.push_back(descriptorSet);
Chia-I Wuf8385062015-01-04 16:27:24 +0800766 }
Chia-I Wuf8385062015-01-04 16:27:24 +0800767 return sets;
768}
769
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700770std::vector<DescriptorSet *>
771DescriptorPool::alloc_sets(const Device &dev, const DescriptorSetLayout &layout,
772 uint32_t count) {
773 return alloc_sets(dev,
774 std::vector<const DescriptorSetLayout *>(count, &layout));
Chia-I Wuf8385062015-01-04 16:27:24 +0800775}
776
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700777DescriptorSet *DescriptorPool::alloc_sets(const Device &dev,
778 const DescriptorSetLayout &layout) {
Courtney Goeltzenleuchter831c1832015-10-23 14:21:05 -0600779 std::vector<DescriptorSet *> set = alloc_sets(dev, layout, 1);
Chia-I Wuf8385062015-01-04 16:27:24 +0800780 return (set.empty()) ? NULL : set[0];
781}
782
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700783DescriptorSet::~DescriptorSet() {
Tony Barboure84a8d62015-07-10 14:10:27 -0600784 if (initialized()) {
Cody Northrop35ce7e62015-10-08 11:39:25 -0600785 // Only call vkFree* on sets allocated from pool with usage *_DYNAMIC
786 if (containing_pool_->getDynamicUsage()) {
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700787 VkDescriptorSet sets[1] = {handle()};
788 EXPECT(vkFreeDescriptorSets(device(), containing_pool_->GetObj(), 1,
789 sets) == VK_SUCCESS);
Cody Northrop35ce7e62015-10-08 11:39:25 -0600790 }
Tony Barboure84a8d62015-07-10 14:10:27 -0600791 }
792}
Chia-I Wu55a871f2015-07-03 11:49:42 +0800793
Chia-I Wu1f851912015-10-27 18:04:07 +0800794NON_DISPATCHABLE_HANDLE_DTOR(CommandPool, vkDestroyCommandPool)
Courtney Goeltzenleuchter902d0812015-07-10 19:50:17 -0600795
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700796void CommandPool::init(const Device &dev, const VkCommandPoolCreateInfo &info) {
Courtney Goeltzenleuchter902d0812015-07-10 19:50:17 -0600797 NON_DISPATCHABLE_HANDLE_INIT(vkCreateCommandPool, dev, &info);
798}
799
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700800CommandBuffer::~CommandBuffer() {
Courtney Goeltzenleuchter831c1832015-10-23 14:21:05 -0600801 if (initialized()) {
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700802 VkCommandBuffer cmds[] = {handle()};
Courtney Goeltzenleuchter831c1832015-10-23 14:21:05 -0600803 vkFreeCommandBuffers(dev_handle_, cmd_pool_, 1, cmds);
804 }
Chia-I Wu78c2a352015-07-03 11:49:42 +0800805}
806
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700807void CommandBuffer::init(const Device &dev,
808 const VkCommandBufferAllocateInfo &info) {
Chia-I Wu1f851912015-10-27 18:04:07 +0800809 VkCommandBuffer cmd;
Chia-I Wu78c2a352015-07-03 11:49:42 +0800810
Chia-I Wu1f851912015-10-27 18:04:07 +0800811 // Make sure commandPool is set
812 assert(info.commandPool);
Courtney Goeltzenleuchter4be35972015-07-13 12:53:32 -0600813
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700814 if (EXPECT(vkAllocateCommandBuffers(dev.handle(), &info, &cmd) ==
815 VK_SUCCESS)) {
Chia-I Wu78c2a352015-07-03 11:49:42 +0800816 Handle::init(cmd);
817 dev_handle_ = dev.handle();
Chia-I Wu1f851912015-10-27 18:04:07 +0800818 cmd_pool_ = info.commandPool;
Chia-I Wu78c2a352015-07-03 11:49:42 +0800819 }
Chia-I Wu82bff272014-12-27 14:12:52 +0800820}
821
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700822void CommandBuffer::begin(const VkCommandBufferBeginInfo *info) {
Chia-I Wu78c2a352015-07-03 11:49:42 +0800823 EXPECT(vkBeginCommandBuffer(handle(), info) == VK_SUCCESS);
Jeremy Hayese0c3b222015-01-14 16:17:08 -0700824}
825
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700826void CommandBuffer::begin() {
Chia-I Wu1f851912015-10-27 18:04:07 +0800827 VkCommandBufferBeginInfo info = {};
Jon Ashburna4ae48b2016-01-11 13:12:43 -0700828 VkCommandBufferInheritanceInfo hinfo = {};
Chia-I Wu1f851912015-10-27 18:04:07 +0800829 info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
830 info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
Jon Ashburna4ae48b2016-01-11 13:12:43 -0700831 info.pInheritanceInfo = &hinfo;
832 hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
833 hinfo.pNext = NULL;
834 hinfo.renderPass = VK_NULL_HANDLE;
835 hinfo.subpass = 0;
836 hinfo.framebuffer = VK_NULL_HANDLE;
837 hinfo.occlusionQueryEnable = VK_FALSE;
838 hinfo.queryFlags = 0;
839 hinfo.pipelineStatistics = 0;
Jeremy Hayese0c3b222015-01-14 16:17:08 -0700840
841 begin(&info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800842}
843
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700844void CommandBuffer::end() {
Chia-I Wu78c2a352015-07-03 11:49:42 +0800845 EXPECT(vkEndCommandBuffer(handle()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800846}
847
Karl Schultz99e9d1d2016-02-02 17:17:23 -0700848void CommandBuffer::reset(VkCommandBufferResetFlags flags) {
Cody Northropf02f9f82015-07-09 18:08:05 -0600849 EXPECT(vkResetCommandBuffer(handle(), flags) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800850}
851
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600852}; // namespace vk_testing