blob: c7f027b35dc4568bf940e5fafa8e055aa1f75b2f [file] [log] [blame]
Karl Schultz6addd812016-02-02 17:17:23 -07001/*
sfricke-samsung6fc3e322022-02-15 22:41:29 -08002 * Copyright (c) 2015-2022 The Khronos Group Inc.
3 * Copyright (c) 2015-2022 Valve Corporation
4 * Copyright (c) 2015-2022 LunarG, Inc.
Karl Schultz6addd812016-02-02 17:17:23 -07005 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -06006 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
Karl Schultz6addd812016-02-02 17:17:23 -07009 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060010 * http://www.apache.org/licenses/LICENSE-2.0
Karl Schultz6addd812016-02-02 17:17:23 -070011 *
Jon Ashburn3ebf1252016-04-19 11:30:31 -060012 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
Karl Schultz6addd812016-02-02 17:17:23 -070017 *
18 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
19 * Author: Tony Barbour <tony@LunarG.com>
20 */
Chia-I Wuf1e2e992014-12-27 14:12:52 +080021
Petr Krausc3aee2e2019-09-06 00:26:06 +020022#include "vktestbinding.h"
23
Mark Lobodzinski64318ba2017-01-26 13:34:13 -070024#include <string.h> // memset(), memcmp()
Petr Krausc3aee2e2019-09-06 00:26:06 +020025#include <algorithm>
26#include <cassert>
27#include <iostream>
28#include <vector>
29
30#include "test_common.h"
31#include "vk_typemap_helper.h"
John Zulauf5e01c4a2022-07-25 18:00:18 -060032#include "vk_format_utils.h"
Chia-I Wuf1e2e992014-12-27 14:12:52 +080033
34namespace {
Chia-I Wuf1e2e992014-12-27 14:12:52 +080035
Nathaniel Cesario6ace8022022-08-09 14:13:07 -060036#define NON_DISPATCHABLE_HANDLE_INIT(create_func, dev, ...) \
37 do { \
38 handle_type handle; \
39 auto result = create_func(dev.handle(), __VA_ARGS__, NULL, &handle); \
40 if (EXPECT((result == VK_SUCCESS) || (result == VK_ERROR_VALIDATION_FAILED_EXT) || \
41 (result == VK_ERROR_OUT_OF_DEVICE_MEMORY) || (result == VK_ERROR_OUT_OF_HOST_MEMORY))) { \
42 if (result == VK_SUCCESS) { \
43 NonDispHandle::init(dev.handle(), handle); \
44 } \
45 } \
Chia-I Wuf8f074f2015-07-03 10:58:57 +080046 } while (0)
47
Nathaniel Cesario0d50bcf2022-06-21 10:30:04 -060048#define NON_DISPATCHABLE_HANDLE_DTOR(cls, destroy_func) \
49 cls::~cls() NOEXCEPT { \
50 if (initialized()) { \
51 destroy_func(device(), handle(), NULL); \
52 handle_ = VK_NULL_HANDLE; \
53 } \
Chia-I Wud9e8e822015-07-03 11:45:55 +080054 }
55
Chia-I Wuf1e2e992014-12-27 14:12:52 +080056#define STRINGIFY(x) #x
Mark Lobodzinski722841d2016-09-07 16:34:56 -060057#define EXPECT(expr) ((expr) ? true : expect_failure(STRINGIFY(expr), __FILE__, __LINE__, __FUNCTION__))
Chia-I Wuf1e2e992014-12-27 14:12:52 +080058
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060059vk_testing::ErrorCallback error_callback;
Chia-I Wuf1e2e992014-12-27 14:12:52 +080060
Mark Lobodzinski722841d2016-09-07 16:34:56 -060061bool expect_failure(const char *expr, const char *file, unsigned int line, const char *function) {
Chia-I Wuf1e2e992014-12-27 14:12:52 +080062 if (error_callback) {
63 error_callback(expr, file, line, function);
64 } else {
Mark Lobodzinski722841d2016-09-07 16:34:56 -060065 std::cerr << file << ":" << line << ": " << function << ": Expectation `" << expr << "' failed.\n";
Chia-I Wuf1e2e992014-12-27 14:12:52 +080066 }
67
68 return false;
69}
70
Mark Lobodzinski64318ba2017-01-26 13:34:13 -070071} // namespace
Chia-I Wuf1e2e992014-12-27 14:12:52 +080072
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -060073namespace vk_testing {
Chia-I Wuf1e2e992014-12-27 14:12:52 +080074
Karl Schultz6addd812016-02-02 17:17:23 -070075void set_error_callback(ErrorCallback callback) { error_callback = callback; }
Chia-I Wuf1e2e992014-12-27 14:12:52 +080076
Karl Schultz6addd812016-02-02 17:17:23 -070077VkPhysicalDeviceProperties PhysicalDevice::properties() const {
Tony Barbour59a47322015-06-24 16:06:58 -060078 VkPhysicalDeviceProperties info;
79
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -060080 vk::GetPhysicalDeviceProperties(handle(), &info);
Tony Barbour59a47322015-06-24 16:06:58 -060081
82 return info;
Chia-I Wuf1e2e992014-12-27 14:12:52 +080083}
84
Karl Schultz6addd812016-02-02 17:17:23 -070085std::vector<VkQueueFamilyProperties> PhysicalDevice::queue_properties() const {
Cody Northropd0802882015-08-03 17:04:53 -060086 std::vector<VkQueueFamilyProperties> info;
Tony Barbour59a47322015-06-24 16:06:58 -060087 uint32_t count;
88
Cody Northropd0802882015-08-03 17:04:53 -060089 // Call once with NULL data to receive count
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -060090 vk::GetPhysicalDeviceQueueFamilyProperties(handle(), &count, NULL);
Courtney Goeltzenleuchter06d89472015-10-20 16:40:38 -060091 info.resize(count);
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -060092 vk::GetPhysicalDeviceQueueFamilyProperties(handle(), &count, info.data());
Tony Barbour59a47322015-06-24 16:06:58 -060093
94 return info;
Chia-I Wuf1e2e992014-12-27 14:12:52 +080095}
96
Karl Schultz6addd812016-02-02 17:17:23 -070097VkPhysicalDeviceMemoryProperties PhysicalDevice::memory_properties() const {
Tony Barbour59a47322015-06-24 16:06:58 -060098 VkPhysicalDeviceMemoryProperties info;
99
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600100 vk::GetPhysicalDeviceMemoryProperties(handle(), &info);
Mark Lobodzinskib3fbcd92015-07-02 16:49:40 -0600101
Tony Barbour59a47322015-06-24 16:06:58 -0600102 return info;
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800103}
104
Chris Forbesf9cfe182016-04-04 17:22:42 +1200105VkPhysicalDeviceFeatures PhysicalDevice::features() const {
106 VkPhysicalDeviceFeatures features;
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600107 vk::GetPhysicalDeviceFeatures(handle(), &features);
Chris Forbesf9cfe182016-04-04 17:22:42 +1200108 return features;
109}
110
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600111/*
112 * Return list of Global layers available
113 */
Karl Schultz6addd812016-02-02 17:17:23 -0700114std::vector<VkLayerProperties> GetGlobalLayers() {
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600115 VkResult err;
Charles Giessenadf933c2022-07-12 11:57:16 -0600116 uint32_t layer_count = 32;
117 std::vector<VkLayerProperties> layers(layer_count);
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600118 do {
Petr Kraus979fd532020-04-02 22:07:26 +0200119 err = vk::EnumerateInstanceLayerProperties(&layer_count, layers.data());
Charles Giessenadf933c2022-07-12 11:57:16 -0600120 if (err || 0 == layer_count) return {};
121 if (err == VK_INCOMPLETE) layer_count *= 2; // wasn't enough space, increase it
122 layers.resize(layer_count);
123
Petr Kraus979fd532020-04-02 22:07:26 +0200124 } while (VK_INCOMPLETE == err);
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600125
Petr Kraus979fd532020-04-02 22:07:26 +0200126 assert(!err);
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600127 return layers;
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800128}
129
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600130/*
131 * Return list of Global extensions provided by the ICD / Loader
132 */
Petr Kraus979fd532020-04-02 22:07:26 +0200133std::vector<VkExtensionProperties> GetGlobalExtensions() { return GetGlobalExtensions(nullptr); }
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600134
135/*
136 * Return list of Global extensions provided by the specified layer
Karl Schultz6addd812016-02-02 17:17:23 -0700137 * If pLayerName is NULL, will return extensions implemented by the loader /
138 * ICDs
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600139 */
Karl Schultz6addd812016-02-02 17:17:23 -0700140std::vector<VkExtensionProperties> GetGlobalExtensions(const char *pLayerName) {
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600141 VkResult err;
Charles Giessenadf933c2022-07-12 11:57:16 -0600142 uint32_t extension_count = 32;
143 std::vector<VkExtensionProperties> extensions(extension_count);
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600144 do {
Petr Kraus979fd532020-04-02 22:07:26 +0200145 err = vk::EnumerateInstanceExtensionProperties(nullptr, &extension_count, extensions.data());
Charles Giessenadf933c2022-07-12 11:57:16 -0600146 if (err || 0 == extension_count) return {};
147 if (err == VK_INCOMPLETE) extension_count *= 2; // wasn't enough space, increase it
148 extensions.resize(extension_count);
Petr Kraus979fd532020-04-02 22:07:26 +0200149 } while (VK_INCOMPLETE == err);
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600150
Petr Kraus979fd532020-04-02 22:07:26 +0200151 assert(!err);
Petr Kraus979fd532020-04-02 22:07:26 +0200152 return extensions;
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600153}
154
155/*
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600156 * Return list of PhysicalDevice extensions provided by the specified layer
157 * If pLayerName is NULL, will return extensions for ICD / loader.
158 */
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600159std::vector<VkExtensionProperties> PhysicalDevice::extensions(const char *pLayerName) const {
Courtney Goeltzenleuchter110fdf92015-06-29 15:39:26 -0600160 VkResult err;
Charles Giessenadf933c2022-07-12 11:57:16 -0600161 uint32_t extension_count = 256;
162 std::vector<VkExtensionProperties> extensions(extension_count);
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600163 do {
Petr Kraus43bba7b2020-04-02 19:55:31 +0200164 err = vk::EnumerateDeviceExtensionProperties(handle(), pLayerName, &extension_count, extensions.data());
Charles Giessenadf933c2022-07-12 11:57:16 -0600165 if (err || 0 == extension_count) return {};
166 if (err == VK_INCOMPLETE) extension_count *= 2; // wasn't enough space, increase it
167 extensions.resize(extension_count);
Petr Kraus43bba7b2020-04-02 19:55:31 +0200168 } while (VK_INCOMPLETE == err);
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600169
Petr Kraus43bba7b2020-04-02 19:55:31 +0200170 return extensions;
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800171}
172
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600173bool PhysicalDevice::set_memory_type(const uint32_t type_bits, VkMemoryAllocateInfo *info, const VkFlags properties,
Karl Schultz6addd812016-02-02 17:17:23 -0700174 const VkFlags forbid) const {
175 uint32_t type_mask = type_bits;
176 // Search memtypes to find first index with those properties
177 for (uint32_t i = 0; i < memory_properties_.memoryTypeCount; i++) {
178 if ((type_mask & 1) == 1) {
179 // Type is available, does it match user properties?
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600180 if ((memory_properties_.memoryTypes[i].propertyFlags & properties) == properties &&
paul-lunarg1a2fcc82022-07-14 15:33:02 -0600181 (memory_properties_.memoryTypes[i].propertyFlags & forbid) == 0 &&
182 (memory_properties_.memoryHeaps[memory_properties_.memoryTypes[i].heapIndex].size >= info->allocationSize)) {
Karl Schultz6addd812016-02-02 17:17:23 -0700183 info->memoryTypeIndex = i;
184 return true;
185 }
186 }
187 type_mask >>= 1;
188 }
189 // No memory types matched, return failure
190 return false;
Mark Lobodzinskib3fbcd92015-07-02 16:49:40 -0600191}
192
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600193/*
194 * Return list of PhysicalDevice layers
195 */
Karl Schultz6addd812016-02-02 17:17:23 -0700196std::vector<VkLayerProperties> PhysicalDevice::layers() const {
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600197 VkResult err;
Charles Giessenadf933c2022-07-12 11:57:16 -0600198 uint32_t layer_count = 32;
199 std::vector<VkLayerProperties> layers(layer_count);
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600200 do {
Petr Kraus43bba7b2020-04-02 19:55:31 +0200201 err = vk::EnumerateDeviceLayerProperties(handle(), &layer_count, layers.data());
Charles Giessenadf933c2022-07-12 11:57:16 -0600202 if (err || 0 == layer_count) return {};
203 if (err == VK_INCOMPLETE) layer_count *= 2; // wasn't enough space, increase it
204 layers.resize(layer_count);
Petr Kraus43bba7b2020-04-02 19:55:31 +0200205 } while (VK_INCOMPLETE == err);
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600206
Petr Kraus43bba7b2020-04-02 19:55:31 +0200207 return layers;
Courtney Goeltzenleuchtercd69eee2015-07-06 09:10:47 -0600208}
209
Dave Houlton6c72f352018-02-06 17:49:16 -0700210QueueCreateInfoArray::QueueCreateInfoArray(const std::vector<VkQueueFamilyProperties> &queue_props)
211 : queue_info_(), queue_priorities_() {
John Zulauf01da3ee2017-10-18 18:13:37 -0600212 queue_info_.reserve(queue_props.size());
213
Petr Kraus540a67d2017-12-11 00:35:33 +0100214 for (uint32_t i = 0; i < (uint32_t)queue_props.size(); ++i) {
215 if (queue_props[i].queueCount > 0) {
sfricke-samsung6fc3e322022-02-15 22:41:29 -0800216 VkDeviceQueueCreateInfo qi = LvlInitStruct<VkDeviceQueueCreateInfo>();
Petr Kraus540a67d2017-12-11 00:35:33 +0100217 qi.queueFamilyIndex = i;
218 qi.queueCount = queue_props[i].queueCount;
219 queue_priorities_.emplace_back(qi.queueCount, 0.0f);
220 qi.pQueuePriorities = queue_priorities_[i].data();
221 queue_info_.push_back(qi);
222 }
John Zulauf01da3ee2017-10-18 18:13:37 -0600223 }
224}
225
Mark Lobodzinski5f025572020-03-18 12:13:48 -0600226Device::~Device() NOEXCEPT {
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700227 if (!initialized()) return;
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800228
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600229 vk::DestroyDevice(handle(), NULL);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800230}
231
Tony-LunarG58c59b42019-01-03 13:19:11 -0700232void Device::init(std::vector<const char *> &extensions, VkPhysicalDeviceFeatures *features, void *create_device_pnext) {
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800233 // request all queues
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600234 const std::vector<VkQueueFamilyProperties> queue_props = phy_.queue_properties();
John Zulauf01da3ee2017-10-18 18:13:37 -0600235 QueueCreateInfoArray queue_info(phy_.queue_properties());
Mark Young93ecb1d2016-01-13 13:47:16 -0700236 for (uint32_t i = 0; i < (uint32_t)queue_props.size(); i++) {
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600237 if (queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700238 graphics_queue_node_index_ = i;
William Henning6a354a52018-05-23 18:01:51 -0600239 break;
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700240 }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800241 }
Tobin Ehlis04dea912017-11-14 12:10:11 -0700242 // Only request creation with queuefamilies that have at least one queue
243 std::vector<VkDeviceQueueCreateInfo> create_queue_infos;
244 auto qci = queue_info.data();
245 for (uint32_t j = 0; j < queue_info.size(); ++j) {
246 if (qci[j].queueCount) {
247 create_queue_infos.push_back(qci[j]);
248 }
249 }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800250
Petr Krausb9659a02017-12-11 01:17:46 +0100251 enabled_extensions_ = extensions;
252
sfricke-samsung6fc3e322022-02-15 22:41:29 -0800253 VkDeviceCreateInfo dev_info = LvlInitStruct<VkDeviceCreateInfo>(create_device_pnext);
Tobin Ehlis04dea912017-11-14 12:10:11 -0700254 dev_info.queueCreateInfoCount = create_queue_infos.size();
255 dev_info.pQueueCreateInfos = create_queue_infos.data();
Tony Barbour4c70d102016-08-08 16:06:56 -0600256 dev_info.enabledLayerCount = 0;
257 dev_info.ppEnabledLayerNames = NULL;
Jon Ashburnf19916e2016-01-11 13:12:43 -0700258 dev_info.enabledExtensionCount = extensions.size();
Tony Barbour482c6092015-07-27 09:37:48 -0600259 dev_info.ppEnabledExtensionNames = extensions.data();
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800260
Tony Barbour53f7e892016-08-09 13:44:00 -0600261 VkPhysicalDeviceFeatures all_features;
Jeff Bolzfdf96072018-04-10 14:32:18 -0500262 // Let VkPhysicalDeviceFeatures2 take priority over VkPhysicalDeviceFeatures,
263 // since it supports extensions
Tony-LunarG58c59b42019-01-03 13:19:11 -0700264
Mark Lobodzinski1f887d32020-12-30 15:31:33 -0700265 if (!(LvlFindInChain<VkPhysicalDeviceFeatures2>(dev_info.pNext))) {
Tony-LunarG58c59b42019-01-03 13:19:11 -0700266 if (features) {
267 dev_info.pEnabledFeatures = features;
268 } else {
269 // request all supportable features enabled
270 all_features = phy().features();
271 dev_info.pEnabledFeatures = &all_features;
272 }
Tony Barbour53f7e892016-08-09 13:44:00 -0600273 }
Chris Forbesf9cfe182016-04-04 17:22:42 +1200274
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800275 init(dev_info);
276}
277
Karl Schultz6addd812016-02-02 17:17:23 -0700278void Device::init(const VkDeviceCreateInfo &info) {
Chia-I Wuf368b602015-07-03 10:41:20 +0800279 VkDevice dev;
280
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600281 if (EXPECT(vk::CreateDevice(phy_.handle(), &info, NULL, &dev) == VK_SUCCESS)) Handle::init(dev);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800282
Jeremy Gebbenc7af14b2021-10-22 11:16:48 -0600283 init_queues(info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800284 init_formats();
285}
286
Jeremy Gebbenc7af14b2021-10-22 11:16:48 -0600287void Device::init_queues(const VkDeviceCreateInfo &info) {
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700288 uint32_t queue_node_count;
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600289 vk::GetPhysicalDeviceQueueFamilyProperties(phy_.handle(), &queue_node_count, NULL);
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700290 EXPECT(queue_node_count >= 1);
291
Petr Krausc3aee2e2019-09-06 00:26:06 +0200292 std::vector<VkQueueFamilyProperties> queue_props(queue_node_count);
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600293 vk::GetPhysicalDeviceQueueFamilyProperties(phy_.handle(), &queue_node_count, queue_props.data());
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700294
John Zulauf5abdf122018-03-27 10:12:37 -0600295 queue_families_.resize(queue_node_count);
Jeremy Gebbenc7af14b2021-10-22 11:16:48 -0600296 for (uint32_t i = 0; i < info.queueCreateInfoCount; i++) {
297 const auto &queue_create_info = info.pQueueCreateInfos[i];
298 auto queue_family_i = queue_create_info.queueFamilyIndex;
299 const auto &queue_family_prop = queue_props[queue_family_i];
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700300
Petr Krausc3aee2e2019-09-06 00:26:06 +0200301 QueueFamilyQueues &queue_storage = queue_families_[queue_family_i];
Jeremy Gebbenc7af14b2021-10-22 11:16:48 -0600302 queue_storage.reserve(queue_create_info.queueCount);
303 for (uint32_t queue_i = 0; queue_i < queue_create_info.queueCount; ++queue_i) {
Karl Schultz6addd812016-02-02 17:17:23 -0700304 // TODO: Need to add support for separate MEMMGR and work queues,
305 // including synchronization
Nathaniel Cesario0d50bcf2022-06-21 10:30:04 -0600306 VkQueue queue = VK_NULL_HANDLE;
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600307 vk::GetDeviceQueue(handle(), queue_family_i, queue_i, &queue);
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700308
John Zulauf5abdf122018-03-27 10:12:37 -0600309 // Store single copy of the queue object that will self destruct
Petr Krausc3aee2e2019-09-06 00:26:06 +0200310 queue_storage.emplace_back(new Queue(queue, queue_family_i));
John Zulauf5abdf122018-03-27 10:12:37 -0600311
Jeremy Gebbenc7af14b2021-10-22 11:16:48 -0600312 if (queue_family_prop.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
John Zulauf5abdf122018-03-27 10:12:37 -0600313 queues_[GRAPHICS].push_back(queue_storage.back().get());
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700314 }
315
Jeremy Gebbenc7af14b2021-10-22 11:16:48 -0600316 if (queue_family_prop.queueFlags & VK_QUEUE_COMPUTE_BIT) {
John Zulauf5abdf122018-03-27 10:12:37 -0600317 queues_[COMPUTE].push_back(queue_storage.back().get());
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700318 }
319
Jeremy Gebbenc7af14b2021-10-22 11:16:48 -0600320 if (queue_family_prop.queueFlags & VK_QUEUE_TRANSFER_BIT) {
John Zulauf5abdf122018-03-27 10:12:37 -0600321 queues_[DMA].push_back(queue_storage.back().get());
Courtney Goeltzenleuchter18248e62015-03-05 18:09:39 -0700322 }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800323 }
324 }
325
Jeremy Gebbenc7af14b2021-10-22 11:16:48 -0600326 EXPECT(!queues_[GRAPHICS].empty() || !queues_[COMPUTE].empty() || !queues_[DMA].empty());
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800327}
Petr Krausc3aee2e2019-09-06 00:26:06 +0200328
John Zulauf5abdf122018-03-27 10:12:37 -0600329const Device::QueueFamilyQueues &Device::queue_family_queues(uint32_t queue_family) const {
330 assert(queue_family < queue_families_.size());
331 return queue_families_[queue_family];
332}
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800333
Karl Schultz6addd812016-02-02 17:17:23 -0700334void Device::init_formats() {
Mark Lobodzinski9a6555f2020-02-10 16:16:29 -0700335 // For each 1.0 core format, undefined = first, 12x12_SRGB_BLOCK = last
336 for (int f = VK_FORMAT_UNDEFINED; f <= VK_FORMAT_ASTC_12x12_SRGB_BLOCK; f++) {
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600337 const VkFormat fmt = static_cast<VkFormat>(f);
338 const VkFormatProperties props = format_properties(fmt);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800339
Jeremy Hayesa058eee2015-01-23 08:51:43 -0700340 if (props.linearTilingFeatures) {
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600341 const Format tmp = {fmt, VK_IMAGE_TILING_LINEAR, props.linearTilingFeatures};
Jeremy Hayesa058eee2015-01-23 08:51:43 -0700342 formats_.push_back(tmp);
343 }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800344
Jeremy Hayesa058eee2015-01-23 08:51:43 -0700345 if (props.optimalTilingFeatures) {
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600346 const Format tmp = {fmt, VK_IMAGE_TILING_OPTIMAL, props.optimalTilingFeatures};
Jeremy Hayesa058eee2015-01-23 08:51:43 -0700347 formats_.push_back(tmp);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800348 }
349 }
350
351 EXPECT(!formats_.empty());
352}
353
Cort Stratton72f89aa2018-05-27 10:40:27 -0700354bool Device::IsEnabledExtension(const char *extension) {
Petr Krausb9659a02017-12-11 01:17:46 +0100355 const auto is_x = [&extension](const char *enabled_extension) { return strcmp(extension, enabled_extension) == 0; };
356 return std::any_of(enabled_extensions_.begin(), enabled_extensions_.end(), is_x);
357}
358
Karl Schultz6addd812016-02-02 17:17:23 -0700359VkFormatProperties Device::format_properties(VkFormat format) {
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600360 VkFormatProperties data;
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600361 vk::GetPhysicalDeviceFormatProperties(phy().handle(), format, &data);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800362
363 return data;
364}
365
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600366void Device::wait() { EXPECT(vk::DeviceWaitIdle(handle()) == VK_SUCCESS); }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800367
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600368VkResult Device::wait(const std::vector<const Fence *> &fences, bool wait_all, uint64_t timeout) {
Petr Kraus858bacd2017-12-01 23:10:08 +0100369 const std::vector<VkFence> fence_handles = MakeVkHandles<VkFence>(fences);
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600370 VkResult err = vk::WaitForFences(handle(), fence_handles.size(), fence_handles.data(), wait_all, timeout);
Courtney Goeltzenleuchterd8e229c2015-04-08 15:36:08 -0600371 EXPECT(err == VK_SUCCESS || err == VK_TIMEOUT);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800372
373 return err;
374}
375
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600376void Device::update_descriptor_sets(const std::vector<VkWriteDescriptorSet> &writes,
377 const std::vector<VkCopyDescriptorSet> &copies) {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600378 vk::UpdateDescriptorSets(handle(), writes.size(), writes.data(), copies.size(), copies.data());
Chia-I Wu9d00ed72015-05-25 16:27:55 +0800379}
380
John Zulauf71095472018-03-26 14:45:12 -0600381VkResult Queue::submit(const std::vector<const CommandBuffer *> &cmds, const Fence &fence, bool expect_success) {
Petr Kraus858bacd2017-12-01 23:10:08 +0100382 const std::vector<VkCommandBuffer> cmd_handles = MakeVkHandles<VkCommandBuffer>(cmds);
sfricke-samsung6fc3e322022-02-15 22:41:29 -0800383 VkSubmitInfo submit_info = LvlInitStruct<VkSubmitInfo>();
Chia-I Wud50a7d72015-10-26 20:48:51 +0800384 submit_info.waitSemaphoreCount = 0;
sjfrickea143ec22022-08-02 21:46:04 +0900385 submit_info.pWaitSemaphores = nullptr;
386 submit_info.pWaitDstStageMask = nullptr;
387 submit_info.commandBufferCount = static_cast<uint32_t>(cmd_handles.size());
Courtney Goeltzenleuchter806c7002015-10-27 11:22:14 -0600388 submit_info.pCommandBuffers = cmd_handles.data();
Chia-I Wud50a7d72015-10-26 20:48:51 +0800389 submit_info.signalSemaphoreCount = 0;
sjfrickea143ec22022-08-02 21:46:04 +0900390 submit_info.pSignalSemaphores = nullptr;
Courtney Goeltzenleuchter646b9072015-10-20 18:04:07 -0600391
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600392 VkResult result = vk::QueueSubmit(handle(), 1, &submit_info, fence.handle());
John Zulauf71095472018-03-26 14:45:12 -0600393 if (expect_success) EXPECT(result == VK_SUCCESS);
394 return result;
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800395}
396
John Zulauf71095472018-03-26 14:45:12 -0600397VkResult Queue::submit(const CommandBuffer &cmd, const Fence &fence, bool expect_success) {
398 return submit(std::vector<const CommandBuffer *>(1, &cmd), fence, expect_success);
399}
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800400
John Zulauf71095472018-03-26 14:45:12 -0600401VkResult Queue::submit(const CommandBuffer &cmd, bool expect_success) {
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800402 Fence fence;
John Zulauf71095472018-03-26 14:45:12 -0600403 return submit(cmd, fence);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800404}
405
sjfrickea143ec22022-08-02 21:46:04 +0900406VkResult Queue::submit2(const std::vector<const CommandBuffer *> &cmds, const Fence &fence, bool expect_success) {
407 std::vector<VkCommandBufferSubmitInfo> cmd_submit_infos;
408 for (size_t i = 0; i < cmds.size(); i++) {
409 VkCommandBufferSubmitInfo cmd_submit_info = LvlInitStruct<VkCommandBufferSubmitInfo>();
410 cmd_submit_info.deviceMask = 0;
411 cmd_submit_info.commandBuffer = cmds[i]->handle();
412 cmd_submit_infos.push_back(cmd_submit_info);
413 }
414
415 VkSubmitInfo2 submit_info = LvlInitStruct<VkSubmitInfo2>();
416 submit_info.flags = 0;
417 submit_info.waitSemaphoreInfoCount = 0;
418 submit_info.pWaitSemaphoreInfos = nullptr;
419 submit_info.signalSemaphoreInfoCount = 0;
420 submit_info.pSignalSemaphoreInfos = nullptr;
421 submit_info.commandBufferInfoCount = static_cast<uint32_t>(cmd_submit_infos.size());
422 submit_info.pCommandBufferInfos = cmd_submit_infos.data();
423
424 // requires synchronization2 to be enabled
425 VkResult result = vk::QueueSubmit2(handle(), 1, &submit_info, fence.handle());
426 if (expect_success) EXPECT(result == VK_SUCCESS);
427 return result;
428}
429
430VkResult Queue::submit2(const CommandBuffer &cmd, const Fence &fence, bool expect_success) {
431 return submit2(std::vector<const CommandBuffer *>(1, &cmd), fence, expect_success);
432}
433
John Zulauf71095472018-03-26 14:45:12 -0600434VkResult Queue::wait() {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600435 VkResult result = vk::QueueWaitIdle(handle());
John Zulauf71095472018-03-26 14:45:12 -0600436 EXPECT(result == VK_SUCCESS);
437 return result;
438}
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800439
Mark Lobodzinski5f025572020-03-18 12:13:48 -0600440DeviceMemory::~DeviceMemory() NOEXCEPT {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600441 if (initialized()) vk::FreeMemory(device(), handle(), NULL);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800442}
443
Karl Schultz6addd812016-02-02 17:17:23 -0700444void DeviceMemory::init(const Device &dev, const VkMemoryAllocateInfo &info) {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600445 NON_DISPATCHABLE_HANDLE_INIT(vk::AllocateMemory, dev, &info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800446}
447
Karl Schultz6addd812016-02-02 17:17:23 -0700448const void *DeviceMemory::map(VkFlags flags) const {
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800449 void *data;
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600450 if (!EXPECT(vk::MapMemory(device(), handle(), 0, VK_WHOLE_SIZE, flags, &data) == VK_SUCCESS)) data = NULL;
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800451
452 return data;
453}
454
Karl Schultz6addd812016-02-02 17:17:23 -0700455void *DeviceMemory::map(VkFlags flags) {
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800456 void *data;
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600457 if (!EXPECT(vk::MapMemory(device(), handle(), 0, VK_WHOLE_SIZE, flags, &data) == VK_SUCCESS)) data = NULL;
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800458
459 return data;
460}
461
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600462void DeviceMemory::unmap() const { vk::UnmapMemory(device(), handle()); }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800463
Mike Schuchardt8cacbb02017-10-26 14:06:38 -0600464VkMemoryAllocateInfo DeviceMemory::get_resource_alloc_info(const Device &dev, const VkMemoryRequirements &reqs,
465 VkMemoryPropertyFlags mem_props) {
Tobin Ehlisa3d60642017-11-14 10:02:46 -0700466 // Find appropriate memory type for given reqs
467 VkPhysicalDeviceMemoryProperties dev_mem_props = dev.phy().memory_properties();
468 uint32_t mem_type_index = 0;
469 for (mem_type_index = 0; mem_type_index < dev_mem_props.memoryTypeCount; ++mem_type_index) {
470 if (mem_props == (mem_props & dev_mem_props.memoryTypes[mem_type_index].propertyFlags)) break;
471 }
472 // If we exceeded types, then this device doesn't have the memory we need
473 assert(mem_type_index < dev_mem_props.memoryTypeCount);
474 VkMemoryAllocateInfo info = alloc_info(reqs.size, mem_type_index);
Mike Schuchardt7e567b32017-11-16 13:15:20 -0700475 EXPECT(dev.phy().set_memory_type(reqs.memoryTypeBits, &info, mem_props));
Mike Schuchardt8cacbb02017-10-26 14:06:38 -0600476 return info;
477}
478
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600479NON_DISPATCHABLE_HANDLE_DTOR(Fence, vk::DestroyFence)
Chia-I Wud9e8e822015-07-03 11:45:55 +0800480
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600481void Fence::init(const Device &dev, const VkFenceCreateInfo &info) { NON_DISPATCHABLE_HANDLE_INIT(vk::CreateFence, dev, &info); }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800482
Petr Kraus70fc4652020-04-25 20:10:49 +0200483VkResult Fence::wait(uint64_t timeout) const {
John Zulauf71095472018-03-26 14:45:12 -0600484 VkFence fence = handle();
Petr Kraus70fc4652020-04-25 20:10:49 +0200485 return vk::WaitForFences(device(), 1, &fence, VK_TRUE, timeout);
John Zulauf71095472018-03-26 14:45:12 -0600486}
487
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600488NON_DISPATCHABLE_HANDLE_DTOR(Semaphore, vk::DestroySemaphore)
Chia-I Wu6b1c2482015-07-03 11:49:42 +0800489
Karl Schultz6addd812016-02-02 17:17:23 -0700490void Semaphore::init(const Device &dev, const VkSemaphoreCreateInfo &info) {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600491 NON_DISPATCHABLE_HANDLE_INIT(vk::CreateSemaphore, dev, &info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800492}
493
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600494NON_DISPATCHABLE_HANDLE_DTOR(Event, vk::DestroyEvent)
Chia-I Wuc5c97992015-07-03 11:49:42 +0800495
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600496void Event::init(const Device &dev, const VkEventCreateInfo &info) { NON_DISPATCHABLE_HANDLE_INIT(vk::CreateEvent, dev, &info); }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800497
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600498void Event::set() { EXPECT(vk::SetEvent(device(), handle()) == VK_SUCCESS); }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800499
John Zulauf77019312020-12-15 09:04:32 -0700500void Event::cmd_set(const CommandBuffer &cmd, VkPipelineStageFlags stage_mask) {
501 vk::CmdSetEvent(cmd.handle(), handle(), stage_mask);
502}
503
504void Event::cmd_reset(const CommandBuffer &cmd, VkPipelineStageFlags stage_mask) {
505 vk::CmdResetEvent(cmd.handle(), handle(), stage_mask);
506}
507
John Zulaufb66ee052022-06-10 16:52:28 -0600508void Event::cmd_wait(const CommandBuffer &cmd, VkPipelineStageFlags src_stage_mask, VkPipelineStageFlags dst_stage_mask,
509 const std::vector<VkMemoryBarrier> &memory_barriers, const std::vector<VkBufferMemoryBarrier> &buffer_barriers,
510 const std::vector<VkImageMemoryBarrier> &image_barriers) {
511 VkEvent event_handle = handle();
512 vk::CmdWaitEvents(cmd.handle(), 1, &event_handle, src_stage_mask, dst_stage_mask, static_cast<uint32_t>(memory_barriers.size()),
513 memory_barriers.data(), static_cast<uint32_t>(buffer_barriers.size()), buffer_barriers.data(),
514 static_cast<uint32_t>(image_barriers.size()), image_barriers.data());
515}
516
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600517void Event::reset() { EXPECT(vk::ResetEvent(device(), handle()) == VK_SUCCESS); }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800518
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600519NON_DISPATCHABLE_HANDLE_DTOR(QueryPool, vk::DestroyQueryPool)
Chia-I Wu1b7d4762015-07-03 11:49:42 +0800520
Karl Schultz6addd812016-02-02 17:17:23 -0700521void QueryPool::init(const Device &dev, const VkQueryPoolCreateInfo &info) {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600522 NON_DISPATCHABLE_HANDLE_INIT(vk::CreateQueryPool, dev, &info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800523}
524
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600525VkResult QueryPool::results(uint32_t first, uint32_t count, size_t size, void *data, size_t stride) {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600526 VkResult err = vk::GetQueryPoolResults(device(), handle(), first, count, size, data, stride, 0);
Chia-I Wuccc93a72015-10-26 18:36:20 +0800527 EXPECT(err == VK_SUCCESS || err == VK_NOT_READY);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800528
529 return err;
530}
531
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600532NON_DISPATCHABLE_HANDLE_DTOR(Buffer, vk::DestroyBuffer)
Chia-I Wu1a28fe02015-01-01 07:55:04 +0800533
Tony-LunarGc7cd9b32022-07-12 14:25:39 -0600534void Buffer::init(const Device &dev, const VkBufferCreateInfo &info, VkMemoryPropertyFlags mem_props, void *alloc_info_pnext) {
Tony Barbour4c97d7a2015-04-22 15:10:33 -0600535 init_no_mem(dev, info);
Chia-I Wu681d7a02015-07-03 13:44:34 +0800536
Tony-LunarGc7cd9b32022-07-12 14:25:39 -0600537 auto alloc_info = DeviceMemory::get_resource_alloc_info(dev, memory_requirements(), mem_props);
538 alloc_info.pNext = alloc_info_pnext;
539 internal_mem_.init(dev, alloc_info);
540
Chia-I Wu681d7a02015-07-03 13:44:34 +0800541 bind_memory(internal_mem_, 0);
Tony Barbour4c97d7a2015-04-22 15:10:33 -0600542}
543
Karl Schultz6addd812016-02-02 17:17:23 -0700544void Buffer::init_no_mem(const Device &dev, const VkBufferCreateInfo &info) {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600545 NON_DISPATCHABLE_HANDLE_INIT(vk::CreateBuffer, dev, &info);
Chia-I Wu1a28fe02015-01-01 07:55:04 +0800546 create_info_ = info;
547}
548
Karl Schultz6addd812016-02-02 17:17:23 -0700549VkMemoryRequirements Buffer::memory_requirements() const {
Chia-I Wu681d7a02015-07-03 13:44:34 +0800550 VkMemoryRequirements reqs;
551
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600552 vk::GetBufferMemoryRequirements(device(), handle(), &reqs);
Chia-I Wu681d7a02015-07-03 13:44:34 +0800553
554 return reqs;
555}
556
Karl Schultz6addd812016-02-02 17:17:23 -0700557void Buffer::bind_memory(const DeviceMemory &mem, VkDeviceSize mem_offset) {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600558 EXPECT(vk::BindBufferMemory(device(), handle(), mem.handle(), mem_offset) == VK_SUCCESS);
Mark Lobodzinski942b1722015-05-11 17:21:15 -0500559}
560
Nathaniel Cesario0d50bcf2022-06-21 10:30:04 -0600561void Buffer::bind_memory(const Device &dev, VkMemoryPropertyFlags mem_props, VkDeviceSize mem_offset) {
562 if (!internal_mem_.initialized()) {
563 internal_mem_.init(dev, DeviceMemory::get_resource_alloc_info(dev, memory_requirements(), mem_props));
564 }
565 bind_memory(internal_mem_, mem_offset);
566}
567
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600568NON_DISPATCHABLE_HANDLE_DTOR(BufferView, vk::DestroyBufferView)
Chia-I Wu3158bf32015-07-03 11:49:42 +0800569
Karl Schultz6addd812016-02-02 17:17:23 -0700570void BufferView::init(const Device &dev, const VkBufferViewCreateInfo &info) {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600571 NON_DISPATCHABLE_HANDLE_INIT(vk::CreateBufferView, dev, &info);
Chia-I Wu1a28fe02015-01-01 07:55:04 +0800572}
573
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600574NON_DISPATCHABLE_HANDLE_DTOR(Image, vk::DestroyImage)
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800575
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600576void Image::init(const Device &dev, const VkImageCreateInfo &info, VkMemoryPropertyFlags mem_props) {
Tony Barbour4c97d7a2015-04-22 15:10:33 -0600577 init_no_mem(dev, info);
Chia-I Wu681d7a02015-07-03 13:44:34 +0800578
Karl Schultzb5bc11e2016-05-04 08:36:08 -0600579 if (initialized()) {
Mike Schuchardt8cacbb02017-10-26 14:06:38 -0600580 internal_mem_.init(dev, DeviceMemory::get_resource_alloc_info(dev, memory_requirements(), mem_props));
Karl Schultzb5bc11e2016-05-04 08:36:08 -0600581 bind_memory(internal_mem_, 0);
582 }
Tony Barbour4c97d7a2015-04-22 15:10:33 -0600583}
584
Karl Schultz6addd812016-02-02 17:17:23 -0700585void Image::init_no_mem(const Device &dev, const VkImageCreateInfo &info) {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600586 NON_DISPATCHABLE_HANDLE_INIT(vk::CreateImage, dev, &info);
Karl Schultzb5bc11e2016-05-04 08:36:08 -0600587 if (initialized()) {
588 init_info(dev, info);
589 }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800590}
591
Karl Schultz6addd812016-02-02 17:17:23 -0700592void Image::init_info(const Device &dev, const VkImageCreateInfo &info) {
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800593 create_info_ = info;
594
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600595 for (std::vector<Device::Format>::const_iterator it = dev.formats().begin(); it != dev.formats().end(); it++) {
596 if (memcmp(&it->format, &create_info_.format, sizeof(it->format)) == 0 && it->tiling == create_info_.tiling) {
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800597 format_features_ = it->features;
598 break;
599 }
600 }
601}
602
Karl Schultz6addd812016-02-02 17:17:23 -0700603VkMemoryRequirements Image::memory_requirements() const {
Chia-I Wu681d7a02015-07-03 13:44:34 +0800604 VkMemoryRequirements reqs;
605
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600606 vk::GetImageMemoryRequirements(device(), handle(), &reqs);
Chia-I Wu681d7a02015-07-03 13:44:34 +0800607
608 return reqs;
609}
610
Karl Schultz6addd812016-02-02 17:17:23 -0700611void Image::bind_memory(const DeviceMemory &mem, VkDeviceSize mem_offset) {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600612 EXPECT(vk::BindImageMemory(device(), handle(), mem.handle(), mem_offset) == VK_SUCCESS);
Chia-I Wu1a28fe02015-01-01 07:55:04 +0800613}
614
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600615VkSubresourceLayout Image::subresource_layout(const VkImageSubresource &subres) const {
Courtney Goeltzenleuchterfb4efc62015-04-10 08:34:15 -0600616 VkSubresourceLayout data;
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800617 size_t size = sizeof(data);
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600618 vk::GetImageSubresourceLayout(device(), handle(), &subres, &data);
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700619 if (size != sizeof(data)) memset(&data, 0, sizeof(data));
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800620
621 return data;
622}
623
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600624VkSubresourceLayout Image::subresource_layout(const VkImageSubresourceLayers &subrescopy) const {
Courtney Goeltzenleuchter01ee1ca2015-09-10 16:41:13 -0600625 VkSubresourceLayout data;
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600626 VkImageSubresource subres = subresource(subrescopy.aspectMask, subrescopy.mipLevel, subrescopy.baseArrayLayer);
Courtney Goeltzenleuchter01ee1ca2015-09-10 16:41:13 -0600627 size_t size = sizeof(data);
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600628 vk::GetImageSubresourceLayout(device(), handle(), &subres, &data);
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700629 if (size != sizeof(data)) memset(&data, 0, sizeof(data));
Courtney Goeltzenleuchter01ee1ca2015-09-10 16:41:13 -0600630
631 return data;
632}
633
Karl Schultz6addd812016-02-02 17:17:23 -0700634bool Image::transparent() const {
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600635 return (create_info_.tiling == VK_IMAGE_TILING_LINEAR && create_info_.samples == VK_SAMPLE_COUNT_1_BIT &&
636 !(create_info_.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)));
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800637}
638
John Zulauf5e01c4a2022-07-25 18:00:18 -0600639VkImageAspectFlags Image::aspect_mask(VkFormat format) {
640 VkImageAspectFlags image_aspect;
641 if (FormatIsDepthAndStencil(format)) {
642 image_aspect = VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT;
643 } else if (FormatIsDepthOnly(format)) {
644 image_aspect = VK_IMAGE_ASPECT_DEPTH_BIT;
645 } else if (FormatIsStencilOnly(format)) {
646 image_aspect = VK_IMAGE_ASPECT_STENCIL_BIT;
647 } else { // color
648 image_aspect = VK_IMAGE_ASPECT_COLOR_BIT;
649 }
650 return image_aspect;
651}
652
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600653NON_DISPATCHABLE_HANDLE_DTOR(ImageView, vk::DestroyImageView)
Chia-I Wu3158bf32015-07-03 11:49:42 +0800654
Karl Schultz6addd812016-02-02 17:17:23 -0700655void ImageView::init(const Device &dev, const VkImageViewCreateInfo &info) {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600656 NON_DISPATCHABLE_HANDLE_INIT(vk::CreateImageView, dev, &info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800657}
658
Jason Macnakd218cba2019-07-09 15:47:02 -0700659AccelerationStructure::~AccelerationStructure() {
660 if (initialized()) {
sourav parmarbb9d8f82020-07-17 13:01:41 -0700661 PFN_vkDestroyAccelerationStructureNV vkDestroyAccelerationStructureNV =
662 (PFN_vkDestroyAccelerationStructureNV)vk::GetDeviceProcAddr(device(), "vkDestroyAccelerationStructureNV");
663 assert(vkDestroyAccelerationStructureNV != nullptr);
Jason Macnakd218cba2019-07-09 15:47:02 -0700664
sourav parmarbb9d8f82020-07-17 13:01:41 -0700665 vkDestroyAccelerationStructureNV(device(), handle(), nullptr);
Jason Macnakd218cba2019-07-09 15:47:02 -0700666 }
667}
668
sourav parmarbb9d8f82020-07-17 13:01:41 -0700669AccelerationStructureKHR::~AccelerationStructureKHR() {
670 if (initialized()) {
671 PFN_vkDestroyAccelerationStructureKHR vkDestroyAccelerationStructureKHR =
672 (PFN_vkDestroyAccelerationStructureKHR)vk::GetDeviceProcAddr(device(), "vkDestroyAccelerationStructureKHR");
673 assert(vkDestroyAccelerationStructureKHR != nullptr);
674 vkDestroyAccelerationStructureKHR(device(), handle(), nullptr);
675 }
676}
677VkMemoryRequirements2 AccelerationStructure::memory_requirements() const {
Jason Macnakd218cba2019-07-09 15:47:02 -0700678 PFN_vkGetAccelerationStructureMemoryRequirementsNV vkGetAccelerationStructureMemoryRequirementsNV =
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600679 (PFN_vkGetAccelerationStructureMemoryRequirementsNV)vk::GetDeviceProcAddr(device(),
680 "vkGetAccelerationStructureMemoryRequirementsNV");
sourav parmarbb9d8f82020-07-17 13:01:41 -0700681 assert(vkGetAccelerationStructureMemoryRequirementsNV != nullptr);
Jason Macnakd218cba2019-07-09 15:47:02 -0700682 VkMemoryRequirements2 memoryRequirements = {};
sfricke-samsung6fc3e322022-02-15 22:41:29 -0800683 VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo =
684 LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
sourav parmarbb9d8f82020-07-17 13:01:41 -0700685 memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
686 memoryRequirementsInfo.accelerationStructure = handle();
687 vkGetAccelerationStructureMemoryRequirementsNV(device(), &memoryRequirementsInfo, &memoryRequirements);
Jason Macnakd218cba2019-07-09 15:47:02 -0700688 return memoryRequirements;
689}
690
691VkMemoryRequirements2 AccelerationStructure::build_scratch_memory_requirements() const {
692 PFN_vkGetAccelerationStructureMemoryRequirementsNV vkGetAccelerationStructureMemoryRequirementsNV =
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600693 (PFN_vkGetAccelerationStructureMemoryRequirementsNV)vk::GetDeviceProcAddr(device(),
694 "vkGetAccelerationStructureMemoryRequirementsNV");
Jason Macnakd218cba2019-07-09 15:47:02 -0700695 assert(vkGetAccelerationStructureMemoryRequirementsNV != nullptr);
696
sfricke-samsung6fc3e322022-02-15 22:41:29 -0800697 VkAccelerationStructureMemoryRequirementsInfoNV memoryRequirementsInfo =
698 LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
Jason Macnakd218cba2019-07-09 15:47:02 -0700699 memoryRequirementsInfo.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV;
700 memoryRequirementsInfo.accelerationStructure = handle();
701
702 VkMemoryRequirements2 memoryRequirements = {};
703 vkGetAccelerationStructureMemoryRequirementsNV(device(), &memoryRequirementsInfo, &memoryRequirements);
704 return memoryRequirements;
705}
706
707void AccelerationStructure::init(const Device &dev, const VkAccelerationStructureCreateInfoNV &info, bool init_memory) {
708 PFN_vkCreateAccelerationStructureNV vkCreateAccelerationStructureNV =
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600709 (PFN_vkCreateAccelerationStructureNV)vk::GetDeviceProcAddr(dev.handle(), "vkCreateAccelerationStructureNV");
Jason Macnakd218cba2019-07-09 15:47:02 -0700710 assert(vkCreateAccelerationStructureNV != nullptr);
711
712 NON_DISPATCHABLE_HANDLE_INIT(vkCreateAccelerationStructureNV, dev, &info);
713
714 info_ = info.info;
715
716 if (init_memory) {
717 memory_.init(dev, DeviceMemory::get_resource_alloc_info(dev, memory_requirements().memoryRequirements,
718 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
719
720 PFN_vkBindAccelerationStructureMemoryNV vkBindAccelerationStructureMemoryNV =
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600721 (PFN_vkBindAccelerationStructureMemoryNV)vk::GetDeviceProcAddr(dev.handle(), "vkBindAccelerationStructureMemoryNV");
Jason Macnakd218cba2019-07-09 15:47:02 -0700722 assert(vkBindAccelerationStructureMemoryNV != nullptr);
723
sfricke-samsung6fc3e322022-02-15 22:41:29 -0800724 VkBindAccelerationStructureMemoryInfoNV bind_info = LvlInitStruct<VkBindAccelerationStructureMemoryInfoNV>();
Jason Macnakd218cba2019-07-09 15:47:02 -0700725 bind_info.accelerationStructure = handle();
726 bind_info.memory = memory_.handle();
727 EXPECT(vkBindAccelerationStructureMemoryNV(dev.handle(), 1, &bind_info) == VK_SUCCESS);
Jason Macnake4b41ca2019-07-11 11:05:31 -0700728
729 PFN_vkGetAccelerationStructureHandleNV vkGetAccelerationStructureHandleNV =
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600730 (PFN_vkGetAccelerationStructureHandleNV)vk::GetDeviceProcAddr(dev.handle(), "vkGetAccelerationStructureHandleNV");
Jason Macnake4b41ca2019-07-11 11:05:31 -0700731 assert(vkGetAccelerationStructureHandleNV != nullptr);
732 EXPECT(vkGetAccelerationStructureHandleNV(dev.handle(), handle(), sizeof(uint64_t), &opaque_handle_) == VK_SUCCESS);
Jason Macnakd218cba2019-07-09 15:47:02 -0700733 }
734}
Tony-LunarG2c0a9722022-07-13 15:17:17 -0600735void AccelerationStructure::create_scratch_buffer(const Device &dev, Buffer *buffer, VkBufferCreateInfo *pCreateInfo,
736 bool buffer_device_address) {
Jason Macnakd218cba2019-07-09 15:47:02 -0700737 VkMemoryRequirements scratch_buffer_memory_requirements = build_scratch_memory_requirements().memoryRequirements;
Jason Macnakd218cba2019-07-09 15:47:02 -0700738 VkBufferCreateInfo create_info = {};
Jason Macnakd218cba2019-07-09 15:47:02 -0700739 create_info.size = scratch_buffer_memory_requirements.size;
sourav parmar1e8c7ff2020-04-25 16:43:03 -0700740 if (pCreateInfo) {
741 create_info.sType = pCreateInfo->sType;
742 create_info.usage = pCreateInfo->usage;
743 } else {
744 create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
745 create_info.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
Tony-LunarG2c0a9722022-07-13 15:17:17 -0600746 if (buffer_device_address) create_info.usage |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
sourav parmar1e8c7ff2020-04-25 16:43:03 -0700747 }
Tony-LunarG2c0a9722022-07-13 15:17:17 -0600748 if (buffer_device_address) {
749 auto alloc_flags = LvlInitStruct<VkMemoryAllocateFlagsInfo>();
750 alloc_flags.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
751 buffer->init(dev, create_info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &alloc_flags);
752 } else {
753 buffer->init(dev, create_info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
754 }
Jason Macnakd218cba2019-07-09 15:47:02 -0700755}
756
sourav parmarbb9d8f82020-07-17 13:01:41 -0700757void AccelerationStructureKHR::init(const Device &dev, const VkAccelerationStructureCreateInfoKHR &info, bool init_memory) {
758 PFN_vkCreateAccelerationStructureKHR vkCreateAccelerationStructureKHR =
759 (PFN_vkCreateAccelerationStructureKHR)vk::GetDeviceProcAddr(dev.handle(), "vkCreateAccelerationStructureKHR");
760 assert(vkCreateAccelerationStructureKHR != nullptr);
761 NON_DISPATCHABLE_HANDLE_INIT(vkCreateAccelerationStructureKHR, dev, &info);
762 info_ = info;
763}
Tony-LunarG2c0a9722022-07-13 15:17:17 -0600764void AccelerationStructureKHR::create_scratch_buffer(const Device &dev, Buffer *buffer, VkBufferCreateInfo *pCreateInfo,
765 bool buffer_device_address) {
sourav parmarbb9d8f82020-07-17 13:01:41 -0700766 VkBufferCreateInfo create_info = {};
767 create_info.size = 0;
768 if (pCreateInfo) {
769 create_info.sType = pCreateInfo->sType;
770 create_info.usage = pCreateInfo->usage;
771 create_info.size = pCreateInfo->size;
772 } else {
773 create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
774 create_info.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
Tony-LunarG2c0a9722022-07-13 15:17:17 -0600775 if (buffer_device_address) create_info.usage |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT;
sourav parmarbb9d8f82020-07-17 13:01:41 -0700776 }
Tony-LunarG2c0a9722022-07-13 15:17:17 -0600777 if (buffer_device_address) {
778 auto alloc_flags = LvlInitStruct<VkMemoryAllocateFlagsInfo>();
779 alloc_flags.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR;
780 buffer->init(dev, create_info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &alloc_flags);
781 } else {
782 buffer->init(dev, create_info, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
783 }
sourav parmarbb9d8f82020-07-17 13:01:41 -0700784}
785
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600786NON_DISPATCHABLE_HANDLE_DTOR(ShaderModule, vk::DestroyShaderModule)
Chia-I Wu4d0c7922015-07-03 11:49:42 +0800787
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600788void ShaderModule::init(const Device &dev, const VkShaderModuleCreateInfo &info) {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600789 NON_DISPATCHABLE_HANDLE_INIT(vk::CreateShaderModule, dev, &info);
Courtney Goeltzenleuchteree4027d2015-06-28 13:01:17 -0600790}
791
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600792VkResult ShaderModule::init_try(const Device &dev, const VkShaderModuleCreateInfo &info) {
Chia-I Wu4d0c7922015-07-03 11:49:42 +0800793 VkShaderModule mod;
794
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600795 VkResult err = vk::CreateShaderModule(dev.handle(), &info, NULL, &mod);
Mark Lobodzinski64318ba2017-01-26 13:34:13 -0700796 if (err == VK_SUCCESS) NonDispHandle::init(dev.handle(), mod);
Courtney Goeltzenleuchteree4027d2015-06-28 13:01:17 -0600797
798 return err;
799}
800
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600801NON_DISPATCHABLE_HANDLE_DTOR(Pipeline, vk::DestroyPipeline)
Chia-I Wu2ff72fd2015-07-03 11:49:42 +0800802
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600803void Pipeline::init(const Device &dev, const VkGraphicsPipelineCreateInfo &info) {
Jon Ashburnc669cc62015-07-09 15:02:25 -0600804 VkPipelineCache cache;
sfricke-samsung6fc3e322022-02-15 22:41:29 -0800805 VkPipelineCacheCreateInfo ci = LvlInitStruct<VkPipelineCacheCreateInfo>();
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600806 VkResult err = vk::CreatePipelineCache(dev.handle(), &ci, NULL, &cache);
Jon Ashburnc669cc62015-07-09 15:02:25 -0600807 if (err == VK_SUCCESS) {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600808 NON_DISPATCHABLE_HANDLE_INIT(vk::CreateGraphicsPipelines, dev, cache, 1, &info);
809 vk::DestroyPipelineCache(dev.handle(), cache, NULL);
Jon Ashburnc669cc62015-07-09 15:02:25 -0600810 }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800811}
812
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600813VkResult Pipeline::init_try(const Device &dev, const VkGraphicsPipelineCreateInfo &info) {
Chris Forbes95292b12015-05-25 11:13:26 +1200814 VkPipeline pipe;
Jon Ashburnc669cc62015-07-09 15:02:25 -0600815 VkPipelineCache cache;
sfricke-samsung6fc3e322022-02-15 22:41:29 -0800816 VkPipelineCacheCreateInfo ci = LvlInitStruct<VkPipelineCacheCreateInfo>();
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600817 VkResult err = vk::CreatePipelineCache(dev.handle(), &ci, NULL, &cache);
Chia-I Wuf368b602015-07-03 10:41:20 +0800818 EXPECT(err == VK_SUCCESS);
Chris Forbes95292b12015-05-25 11:13:26 +1200819 if (err == VK_SUCCESS) {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600820 err = vk::CreateGraphicsPipelines(dev.handle(), cache, 1, &info, NULL, &pipe);
Jon Ashburnc669cc62015-07-09 15:02:25 -0600821 if (err == VK_SUCCESS) {
Chia-I Wu2ff72fd2015-07-03 11:49:42 +0800822 NonDispHandle::init(dev.handle(), pipe);
Jon Ashburnc669cc62015-07-09 15:02:25 -0600823 }
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600824 vk::DestroyPipelineCache(dev.handle(), cache, NULL);
Chris Forbes95292b12015-05-25 11:13:26 +1200825 }
826
827 return err;
828}
829
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600830void Pipeline::init(const Device &dev, const VkComputePipelineCreateInfo &info) {
Jon Ashburnc669cc62015-07-09 15:02:25 -0600831 VkPipelineCache cache;
sfricke-samsung6fc3e322022-02-15 22:41:29 -0800832 VkPipelineCacheCreateInfo ci = LvlInitStruct<VkPipelineCacheCreateInfo>();
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600833 VkResult err = vk::CreatePipelineCache(dev.handle(), &ci, NULL, &cache);
Jon Ashburnc669cc62015-07-09 15:02:25 -0600834 if (err == VK_SUCCESS) {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600835 NON_DISPATCHABLE_HANDLE_INIT(vk::CreateComputePipelines, dev, cache, 1, &info);
836 vk::DestroyPipelineCache(dev.handle(), cache, NULL);
Jon Ashburnc669cc62015-07-09 15:02:25 -0600837 }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800838}
839
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600840NON_DISPATCHABLE_HANDLE_DTOR(PipelineLayout, vk::DestroyPipelineLayout)
Chia-I Wufd46e7d2015-07-03 11:49:42 +0800841
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600842void PipelineLayout::init(const Device &dev, VkPipelineLayoutCreateInfo &info,
843 const std::vector<const DescriptorSetLayout *> &layouts) {
Petr Kraus858bacd2017-12-01 23:10:08 +0100844 const std::vector<VkDescriptorSetLayout> layout_handles = MakeVkHandles<VkDescriptorSetLayout>(layouts);
Petr Kraus65ccc882017-12-03 15:36:03 +0100845 info.setLayoutCount = layout_handles.size();
Tony Barbour482c6092015-07-27 09:37:48 -0600846 info.pSetLayouts = layout_handles.data();
Chia-I Wufd46e7d2015-07-03 11:49:42 +0800847
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600848 NON_DISPATCHABLE_HANDLE_INIT(vk::CreatePipelineLayout, dev, &info);
Chia-I Wufd46e7d2015-07-03 11:49:42 +0800849}
850
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600851NON_DISPATCHABLE_HANDLE_DTOR(Sampler, vk::DestroySampler)
Chia-I Wu8c721c62015-07-03 11:49:42 +0800852
Karl Schultz6addd812016-02-02 17:17:23 -0700853void Sampler::init(const Device &dev, const VkSamplerCreateInfo &info) {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600854 NON_DISPATCHABLE_HANDLE_INIT(vk::CreateSampler, dev, &info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800855}
856
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600857NON_DISPATCHABLE_HANDLE_DTOR(DescriptorSetLayout, vk::DestroyDescriptorSetLayout)
Chia-I Wuafdfd7f2015-07-03 11:49:42 +0800858
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600859void DescriptorSetLayout::init(const Device &dev, const VkDescriptorSetLayoutCreateInfo &info) {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600860 NON_DISPATCHABLE_HANDLE_INIT(vk::CreateDescriptorSetLayout, dev, &info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800861}
862
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600863NON_DISPATCHABLE_HANDLE_DTOR(DescriptorPool, vk::DestroyDescriptorPool)
Chia-I Wuafdfd7f2015-07-03 11:49:42 +0800864
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600865void DescriptorPool::init(const Device &dev, const VkDescriptorPoolCreateInfo &info) {
866 setDynamicUsage(info.flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT);
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600867 NON_DISPATCHABLE_HANDLE_INIT(vk::CreateDescriptorPool, dev, &info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800868}
869
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600870void DescriptorPool::reset() { EXPECT(vk::ResetDescriptorPool(device(), handle(), 0) == VK_SUCCESS); }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800871
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600872std::vector<DescriptorSet *> DescriptorPool::alloc_sets(const Device &dev,
873 const std::vector<const DescriptorSetLayout *> &layouts) {
Petr Kraus858bacd2017-12-01 23:10:08 +0100874 const std::vector<VkDescriptorSetLayout> layout_handles = MakeVkHandles<VkDescriptorSetLayout>(layouts);
Chia-I Wu11078b02015-01-04 16:27:24 +0800875
Chia-I Wuafdfd7f2015-07-03 11:49:42 +0800876 std::vector<VkDescriptorSet> set_handles;
877 set_handles.resize(layout_handles.size());
Chia-I Wu11078b02015-01-04 16:27:24 +0800878
sfricke-samsung6fc3e322022-02-15 22:41:29 -0800879 VkDescriptorSetAllocateInfo alloc_info = LvlInitStruct<VkDescriptorSetAllocateInfo>();
Jon Ashburnf19916e2016-01-11 13:12:43 -0700880 alloc_info.descriptorSetCount = layout_handles.size();
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -0600881 alloc_info.descriptorPool = handle();
882 alloc_info.pSetLayouts = layout_handles.data();
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600883 VkResult err = vk::AllocateDescriptorSets(device(), &alloc_info, set_handles.data());
Cody Northrop1e4f8022015-08-03 12:47:29 -0600884 EXPECT(err == VK_SUCCESS);
Chia-I Wu11078b02015-01-04 16:27:24 +0800885
886 std::vector<DescriptorSet *> sets;
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600887 for (std::vector<VkDescriptorSet>::const_iterator it = set_handles.begin(); it != set_handles.end(); it++) {
Chia-I Wu11078b02015-01-04 16:27:24 +0800888 // do descriptor sets need memories bound?
Cody Northropcdc72a42015-10-08 11:39:25 -0600889 DescriptorSet *descriptorSet = new DescriptorSet(dev, this, *it);
Mark Lobodzinski40f7f402015-04-16 11:44:05 -0500890 sets.push_back(descriptorSet);
Chia-I Wu11078b02015-01-04 16:27:24 +0800891 }
Chia-I Wu11078b02015-01-04 16:27:24 +0800892 return sets;
893}
894
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600895std::vector<DescriptorSet *> DescriptorPool::alloc_sets(const Device &dev, const DescriptorSetLayout &layout, uint32_t count) {
896 return alloc_sets(dev, std::vector<const DescriptorSetLayout *>(count, &layout));
Chia-I Wu11078b02015-01-04 16:27:24 +0800897}
898
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600899DescriptorSet *DescriptorPool::alloc_sets(const Device &dev, const DescriptorSetLayout &layout) {
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -0600900 std::vector<DescriptorSet *> set = alloc_sets(dev, layout, 1);
Chia-I Wu11078b02015-01-04 16:27:24 +0800901 return (set.empty()) ? NULL : set[0];
902}
903
Mark Lobodzinski5f025572020-03-18 12:13:48 -0600904DescriptorSet::~DescriptorSet() NOEXCEPT {
Tony Barbour67e99152015-07-10 14:10:27 -0600905 if (initialized()) {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600906 // Only call vk::Free* on sets allocated from pool with usage *_DYNAMIC
Cody Northropcdc72a42015-10-08 11:39:25 -0600907 if (containing_pool_->getDynamicUsage()) {
Karl Schultz6addd812016-02-02 17:17:23 -0700908 VkDescriptorSet sets[1] = {handle()};
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600909 EXPECT(vk::FreeDescriptorSets(device(), containing_pool_->GetObj(), 1, sets) == VK_SUCCESS);
Cody Northropcdc72a42015-10-08 11:39:25 -0600910 }
Tony Barbour67e99152015-07-10 14:10:27 -0600911 }
912}
Chia-I Wuafdfd7f2015-07-03 11:49:42 +0800913
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600914NON_DISPATCHABLE_HANDLE_DTOR(CommandPool, vk::DestroyCommandPool)
Courtney Goeltzenleuchteree5d80b2015-07-10 19:50:17 -0600915
Karl Schultz6addd812016-02-02 17:17:23 -0700916void CommandPool::init(const Device &dev, const VkCommandPoolCreateInfo &info) {
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600917 NON_DISPATCHABLE_HANDLE_INIT(vk::CreateCommandPool, dev, &info);
Courtney Goeltzenleuchteree5d80b2015-07-10 19:50:17 -0600918}
919
Mark Lobodzinski5f025572020-03-18 12:13:48 -0600920CommandBuffer::~CommandBuffer() NOEXCEPT {
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -0600921 if (initialized()) {
Karl Schultz6addd812016-02-02 17:17:23 -0700922 VkCommandBuffer cmds[] = {handle()};
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600923 vk::FreeCommandBuffers(dev_handle_, cmd_pool_, 1, cmds);
Courtney Goeltzenleuchterbee18a92015-10-23 14:21:05 -0600924 }
Chia-I Wube2b9172015-07-03 11:49:42 +0800925}
926
Mark Lobodzinski722841d2016-09-07 16:34:56 -0600927void CommandBuffer::init(const Device &dev, const VkCommandBufferAllocateInfo &info) {
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800928 VkCommandBuffer cmd;
Chia-I Wube2b9172015-07-03 11:49:42 +0800929
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800930 // Make sure commandPool is set
931 assert(info.commandPool);
Courtney Goeltzenleuchterd8e68bb2015-07-13 12:53:32 -0600932
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600933 if (EXPECT(vk::AllocateCommandBuffers(dev.handle(), &info, &cmd) == VK_SUCCESS)) {
Chia-I Wube2b9172015-07-03 11:49:42 +0800934 Handle::init(cmd);
935 dev_handle_ = dev.handle();
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800936 cmd_pool_ = info.commandPool;
Chia-I Wube2b9172015-07-03 11:49:42 +0800937 }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800938}
939
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600940void CommandBuffer::begin(const VkCommandBufferBeginInfo *info) { EXPECT(vk::BeginCommandBuffer(handle(), info) == VK_SUCCESS); }
Jeremy Hayesd65ae082015-01-14 16:17:08 -0700941
Karl Schultz6addd812016-02-02 17:17:23 -0700942void CommandBuffer::begin() {
sfricke-samsung6fc3e322022-02-15 22:41:29 -0800943 VkCommandBufferBeginInfo info = LvlInitStruct<VkCommandBufferBeginInfo>();
944 VkCommandBufferInheritanceInfo hinfo = LvlInitStruct<VkCommandBufferInheritanceInfo>();
Chia-I Wu3432a0c2015-10-27 18:04:07 +0800945 info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
Jon Ashburnf19916e2016-01-11 13:12:43 -0700946 info.pInheritanceInfo = &hinfo;
Jon Ashburnf19916e2016-01-11 13:12:43 -0700947 hinfo.renderPass = VK_NULL_HANDLE;
948 hinfo.subpass = 0;
949 hinfo.framebuffer = VK_NULL_HANDLE;
950 hinfo.occlusionQueryEnable = VK_FALSE;
951 hinfo.queryFlags = 0;
952 hinfo.pipelineStatistics = 0;
Jeremy Hayesd65ae082015-01-14 16:17:08 -0700953
954 begin(&info);
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800955}
956
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600957void CommandBuffer::end() { EXPECT(vk::EndCommandBuffer(handle()) == VK_SUCCESS); }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800958
Mark Lobodzinskic7a5fcf2019-09-27 14:09:58 -0600959void CommandBuffer::reset(VkCommandBufferResetFlags flags) { EXPECT(vk::ResetCommandBuffer(handle(), flags) == VK_SUCCESS); }
Chia-I Wuf1e2e992014-12-27 14:12:52 +0800960
Jeremy Gebben76d2de32021-08-13 13:26:59 -0600961void RenderPass::init(const Device &dev, const VkRenderPassCreateInfo &info) {
962 NON_DISPATCHABLE_HANDLE_INIT(vk::CreateRenderPass, dev, &info);
963}
964
Nathaniel Cesario0d50bcf2022-06-21 10:30:04 -0600965void RenderPass::init(const Device &dev, const VkRenderPassCreateInfo2 &info, bool khr) {
966 if (!khr) {
967 NON_DISPATCHABLE_HANDLE_INIT(vk::CreateRenderPass2, dev, &info);
968 } else {
969 auto vkCreateRenderPass2KHR =
970 reinterpret_cast<PFN_vkCreateRenderPass2KHR>(vk::GetDeviceProcAddr(dev.handle(), "vkCreateRenderPass2KHR"));
971 ASSERT_NE(vkCreateRenderPass2KHR, nullptr);
972 NON_DISPATCHABLE_HANDLE_INIT(vkCreateRenderPass2KHR, dev, &info);
973 }
ziga-lunarg2fd0e8f2022-05-09 20:59:11 +0200974}
975
Jeremy Gebben76d2de32021-08-13 13:26:59 -0600976NON_DISPATCHABLE_HANDLE_DTOR(RenderPass, vk::DestroyRenderPass)
977
978void Framebuffer::init(const Device &dev, const VkFramebufferCreateInfo &info) {
979 NON_DISPATCHABLE_HANDLE_INIT(vk::CreateFramebuffer, dev, &info);
980}
981
982NON_DISPATCHABLE_HANDLE_DTOR(Framebuffer, vk::DestroyFramebuffer)
paul-lunargb6454132022-07-13 10:00:39 -0600983
984void SamplerYcbcrConversion::init(const Device &dev, const VkSamplerYcbcrConversionCreateInfo &info, bool khr) {
985 if (!khr) {
986 NON_DISPATCHABLE_HANDLE_INIT(vk::CreateSamplerYcbcrConversion, dev, &info);
987 } else {
988 auto vkCreateSamplerYcbcrConversionKHR = reinterpret_cast<PFN_vkCreateSamplerYcbcrConversionKHR>(
989 vk::GetDeviceProcAddr(dev.handle(), "vkCreateSamplerYcbcrConversionKHR"));
990 ASSERT_NE(vkCreateSamplerYcbcrConversionKHR, nullptr);
991 NON_DISPATCHABLE_HANDLE_INIT(vkCreateSamplerYcbcrConversionKHR, dev, &info);
992 }
993}
994
995VkSamplerYcbcrConversionInfo SamplerYcbcrConversion::ConversionInfo() {
996 VkSamplerYcbcrConversionInfo ycbcr_info = LvlInitStruct<VkSamplerYcbcrConversionInfo>();
997 ycbcr_info.conversion = handle();
998 return ycbcr_info;
999}
1000
1001// static
1002VkSamplerYcbcrConversionCreateInfo SamplerYcbcrConversion::DefaultConversionInfo(VkFormat format) {
1003 auto ycbcr_create_info = LvlInitStruct<VkSamplerYcbcrConversionCreateInfo>();
1004 ycbcr_create_info.format = format;
1005 ycbcr_create_info.ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
1006 ycbcr_create_info.ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
1007 ycbcr_create_info.components = {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
1008 VK_COMPONENT_SWIZZLE_IDENTITY};
1009 ycbcr_create_info.xChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN;
1010 ycbcr_create_info.yChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN;
1011 ycbcr_create_info.chromaFilter = VK_FILTER_NEAREST;
1012 ycbcr_create_info.forceExplicitReconstruction = false;
1013 return ycbcr_create_info;
1014}
1015
1016SamplerYcbcrConversion::~SamplerYcbcrConversion() NOEXCEPT {
1017 if (initialized()) {
paul-lunarg414d1ea2022-07-14 15:03:53 -06001018 if (!khr_) {
paul-lunargb6454132022-07-13 10:00:39 -06001019 vk::DestroySamplerYcbcrConversion(device(), handle(), nullptr);
1020 } else {
1021 auto vkDestroySamplerYcbcrConversionKHR = reinterpret_cast<PFN_vkDestroySamplerYcbcrConversionKHR>(
1022 vk::GetDeviceProcAddr(device(), "vkDestroySamplerYcbcrConversionKHR"));
1023 assert(vkDestroySamplerYcbcrConversionKHR != nullptr);
1024 vkDestroySamplerYcbcrConversionKHR(device(), handle(), nullptr);
1025 }
1026 handle_ = VK_NULL_HANDLE;
1027 }
1028}
1029
Petr Kraus13c98a62017-12-09 00:22:39 +01001030} // namespace vk_testing