blob: fa4d4fb5fd1e9344749b5a1cb869fbb8c89b230e [file] [log] [blame]
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -06001// VK tests
Chia-I Wu82bff272014-12-27 14:12:52 +08002//
3// Copyright (C) 2014 LunarG, Inc.
4//
5// Permission is hereby granted, free of charge, to any person obtaining a
6// copy of this software and associated documentation files (the "Software"),
7// to deal in the Software without restriction, including without limitation
8// the rights to use, copy, modify, merge, publish, distribute, sublicense,
9// and/or sell copies of the Software, and to permit persons to whom the
10// Software is furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included
13// in all copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21// DEALINGS IN THE SOFTWARE.
22
23#include <iostream>
24#include <string.h> // memset(), memcmp()
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060025#include "vktestbinding.h"
Chia-I Wu82bff272014-12-27 14:12:52 +080026
27namespace {
28
29#define DERIVED_OBJECT_INIT(create_func, ...) \
30 do { \
31 obj_type obj; \
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060032 if (EXPECT(create_func(__VA_ARGS__, &obj) == VK_SUCCESS)) \
Chia-I Wu82bff272014-12-27 14:12:52 +080033 base_type::init(obj); \
34 } while (0)
35
36#define STRINGIFY(x) #x
37#define EXPECT(expr) ((expr) ? true : expect_failure(STRINGIFY(expr), __FILE__, __LINE__, __FUNCTION__))
38
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060039vk_testing::ErrorCallback error_callback;
Chia-I Wu82bff272014-12-27 14:12:52 +080040
41bool expect_failure(const char *expr, const char *file, unsigned int line, const char *function)
42{
43 if (error_callback) {
44 error_callback(expr, file, line, function);
45 } else {
46 std::cerr << file << ":" << line << ": " << function <<
47 ": Expectation `" << expr << "' failed.\n";
48 }
49
50 return false;
51}
52
53template<class T, class S>
54std::vector<T> make_objects(const std::vector<S> &v)
55{
56 std::vector<T> objs;
57 objs.reserve(v.size());
58 for (typename std::vector<S>::const_iterator it = v.begin(); it != v.end(); it++)
59 objs.push_back((*it)->obj());
60 return objs;
61}
62
63template<typename T>
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060064std::vector<T> get_info(VkPhysicalGpu gpu, VkPhysicalGpuInfoType type, size_t min_elems)
Chia-I Wu82bff272014-12-27 14:12:52 +080065{
66 std::vector<T> info;
Jon Ashburn23bd3822015-02-11 09:36:41 -070067 size_t size;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060068 if (EXPECT(vkGetGpuInfo(gpu, type, &size, NULL) == VK_SUCCESS && size % sizeof(T) == 0)) {
Chia-I Wu82bff272014-12-27 14:12:52 +080069 info.resize(size / sizeof(T));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060070 if (!EXPECT(vkGetGpuInfo(gpu, type, &size, &info[0]) == VK_SUCCESS && size == info.size() * sizeof(T)))
Chia-I Wu82bff272014-12-27 14:12:52 +080071 info.clear();
72 }
73
74 if (info.size() < min_elems)
75 info.resize(min_elems);
76
77 return info;
78}
79
80template<typename T>
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -060081std::vector<T> get_info(VkBaseObject obj, VkObjectInfoType type, size_t min_elems)
Chia-I Wu82bff272014-12-27 14:12:52 +080082{
83 std::vector<T> info;
Jon Ashburn23bd3822015-02-11 09:36:41 -070084 size_t size;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060085 if (EXPECT(vkGetObjectInfo(obj, type, &size, NULL) == VK_SUCCESS && size % sizeof(T) == 0)) {
Chia-I Wu82bff272014-12-27 14:12:52 +080086 info.resize(size / sizeof(T));
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060087 if (!EXPECT(vkGetObjectInfo(obj, type, &size, &info[0]) == VK_SUCCESS && size == info.size() * sizeof(T)))
Chia-I Wu82bff272014-12-27 14:12:52 +080088 info.clear();
89 }
90
91 if (info.size() < min_elems)
92 info.resize(min_elems);
93
94 return info;
95}
96
97} // namespace
98
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -060099namespace vk_testing {
Chia-I Wu82bff272014-12-27 14:12:52 +0800100
101void set_error_callback(ErrorCallback callback)
102{
103 error_callback = callback;
104}
105
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600106VkPhysicalGpuProperties PhysicalGpu::properties() const
Chia-I Wu82bff272014-12-27 14:12:52 +0800107{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600108 return get_info<VkPhysicalGpuProperties>(gpu_, VK_INFO_TYPE_PHYSICAL_GPU_PROPERTIES, 1)[0];
Chia-I Wu82bff272014-12-27 14:12:52 +0800109}
110
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600111VkPhysicalGpuPerformance PhysicalGpu::performance() const
Chia-I Wu82bff272014-12-27 14:12:52 +0800112{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600113 return get_info<VkPhysicalGpuPerformance>(gpu_, VK_INFO_TYPE_PHYSICAL_GPU_PERFORMANCE, 1)[0];
Chia-I Wu82bff272014-12-27 14:12:52 +0800114}
115
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600116std::vector<VkPhysicalGpuQueueProperties> PhysicalGpu::queue_properties() const
Chia-I Wu82bff272014-12-27 14:12:52 +0800117{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600118 return get_info<VkPhysicalGpuQueueProperties>(gpu_, VK_INFO_TYPE_PHYSICAL_GPU_QUEUE_PROPERTIES, 0);
Chia-I Wu82bff272014-12-27 14:12:52 +0800119}
120
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600121VkPhysicalGpuMemoryProperties PhysicalGpu::memory_properties() const
Chia-I Wu82bff272014-12-27 14:12:52 +0800122{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600123 return get_info<VkPhysicalGpuMemoryProperties>(gpu_, VK_INFO_TYPE_PHYSICAL_GPU_MEMORY_PROPERTIES, 1)[0];
Chia-I Wu82bff272014-12-27 14:12:52 +0800124}
125
126std::vector<const char *> PhysicalGpu::layers(std::vector<char> &buf) const
127{
128 const size_t max_layer_count = 16;
129 const size_t max_string_size = 256;
130
131 buf.resize(max_layer_count * max_string_size);
132
133 std::vector<const char *> layers;
134 layers.reserve(max_layer_count);
135 for (size_t i = 0; i < max_layer_count; i++)
136 layers.push_back(&buf[0] + max_string_size * i);
137
138 char * const *out = const_cast<char * const *>(&layers[0]);
139 size_t count;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600140 if (!EXPECT(vkEnumerateLayers(gpu_, max_layer_count, max_string_size, &count, out, NULL) == VK_SUCCESS))
Chia-I Wu82bff272014-12-27 14:12:52 +0800141 count = 0;
142 layers.resize(count);
143
144 return layers;
145}
146
147std::vector<const char *> PhysicalGpu::extensions() const
148{
149 static const char *known_exts[] = {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600150 "VK_WSI_X11",
Chia-I Wu82bff272014-12-27 14:12:52 +0800151 };
152
153 std::vector<const char *> exts;
154 for (int i = 0; i < sizeof(known_exts) / sizeof(known_exts[0]); i++) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600155 VkResult err = vkGetExtensionSupport(gpu_, known_exts[i]);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600156 if (err == VK_SUCCESS)
Chia-I Wu82bff272014-12-27 14:12:52 +0800157 exts.push_back(known_exts[i]);
158 }
159
160 return exts;
161}
162
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600163VkGpuCompatibilityInfo PhysicalGpu::compatibility(const PhysicalGpu &other) const
Chia-I Wu82bff272014-12-27 14:12:52 +0800164{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600165 VkGpuCompatibilityInfo data;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600166 if (!EXPECT(vkGetMultiGpuCompatibility(gpu_, other.gpu_, &data) == VK_SUCCESS))
Chia-I Wu82bff272014-12-27 14:12:52 +0800167 memset(&data, 0, sizeof(data));
168
169 return data;
170}
171
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600172void BaseObject::init(VkBaseObject obj, bool own)
Chia-I Wu82bff272014-12-27 14:12:52 +0800173{
174 EXPECT(!initialized());
175 reinit(obj, own);
176}
177
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600178void BaseObject::reinit(VkBaseObject obj, bool own)
Chia-I Wu82bff272014-12-27 14:12:52 +0800179{
180 obj_ = obj;
181 own_obj_ = own;
182}
183
184uint32_t BaseObject::memory_allocation_count() const
185{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600186 return get_info<uint32_t>(obj_, VK_INFO_TYPE_MEMORY_ALLOCATION_COUNT, 1)[0];
Chia-I Wu82bff272014-12-27 14:12:52 +0800187}
188
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600189std::vector<VkMemoryRequirements> BaseObject::memory_requirements() const
Chia-I Wu82bff272014-12-27 14:12:52 +0800190{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600191 VkResult err;
Mark Lobodzinskie2d07a52015-01-29 08:55:56 -0600192 uint32_t num_allocations = 0;
193 size_t num_alloc_size = sizeof(num_allocations);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600194 err = vkGetObjectInfo(obj_, VK_INFO_TYPE_MEMORY_ALLOCATION_COUNT,
Jon Ashburna9ae3832015-01-16 09:37:43 -0700195 &num_alloc_size, &num_allocations);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600196 EXPECT(err == VK_SUCCESS && num_alloc_size == sizeof(num_allocations));
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600197 std::vector<VkMemoryRequirements> info =
198 get_info<VkMemoryRequirements>(obj_, VK_INFO_TYPE_MEMORY_REQUIREMENTS, 0);
Jon Ashburna9ae3832015-01-16 09:37:43 -0700199 EXPECT(info.size() == num_allocations);
Chia-I Wu82bff272014-12-27 14:12:52 +0800200 if (info.size() == 1 && !info[0].size)
201 info.clear();
202
203 return info;
204}
205
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600206void Object::init(VkObject obj, bool own)
Chia-I Wu82bff272014-12-27 14:12:52 +0800207{
208 BaseObject::init(obj, own);
209 mem_alloc_count_ = memory_allocation_count();
210}
211
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600212void Object::reinit(VkObject obj, bool own)
Chia-I Wu82bff272014-12-27 14:12:52 +0800213{
214 cleanup();
215 BaseObject::reinit(obj, own);
216 mem_alloc_count_ = memory_allocation_count();
217}
218
219void Object::cleanup()
220{
221 if (!initialized())
222 return;
223
Tony Barbour2b5fb342015-04-09 16:00:18 -0600224 if(bound) {
225 unbind_memory();
226 }
Chia-I Wu82bff272014-12-27 14:12:52 +0800227
228 if (internal_mems_) {
229 delete[] internal_mems_;
230 internal_mems_ = NULL;
231 primary_mem_ = NULL;
232 }
233
234 mem_alloc_count_ = 0;
235
236 if (own())
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600237 EXPECT(vkDestroyObject(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800238}
239
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600240void Object::bind_memory(uint32_t alloc_idx, const GpuMemory &mem, VkGpuSize mem_offset)
Chia-I Wu82bff272014-12-27 14:12:52 +0800241{
Tony Barbour2b5fb342015-04-09 16:00:18 -0600242 bound = true;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600243 EXPECT(vkBindObjectMemory(obj(), alloc_idx, mem.obj(), mem_offset) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800244}
245
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600246void Object::bind_memory(uint32_t alloc_idx, VkGpuSize offset, VkGpuSize size,
247 const GpuMemory &mem, VkGpuSize mem_offset)
Chia-I Wu714df452015-01-01 07:55:04 +0800248{
Tony Barbour2b5fb342015-04-09 16:00:18 -0600249 bound = true;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600250 EXPECT(!alloc_idx && vkBindObjectMemoryRange(obj(), 0, offset, size, mem.obj(), mem_offset) == VK_SUCCESS);
Chia-I Wu714df452015-01-01 07:55:04 +0800251}
252
Chia-I Wu82bff272014-12-27 14:12:52 +0800253void Object::unbind_memory(uint32_t alloc_idx)
254{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600255 EXPECT(vkBindObjectMemory(obj(), alloc_idx, VK_NULL_HANDLE, 0) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800256}
257
258void Object::unbind_memory()
259{
260 for (uint32_t i = 0; i < mem_alloc_count_; i++)
261 unbind_memory(i);
262}
263
Mark Lobodzinski97dcd042015-04-16 08:52:00 -0500264void Object::alloc_memory(const Device &dev)
Chia-I Wu82bff272014-12-27 14:12:52 +0800265{
266 if (!EXPECT(!internal_mems_) || !mem_alloc_count_)
267 return;
268
269 internal_mems_ = new GpuMemory[mem_alloc_count_];
270
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600271 const std::vector<VkMemoryRequirements> mem_reqs = memory_requirements();
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600272 VkMemoryAllocInfo info, *next_info = NULL;
Jon Ashburnc6ae13d2015-01-19 15:00:26 -0700273
Chia-I Wu82bff272014-12-27 14:12:52 +0800274 for (int i = 0; i < mem_reqs.size(); i++) {
Jon Ashburn5567c812015-01-20 08:50:12 -0700275 info = GpuMemory::alloc_info(mem_reqs[i], next_info);
Mark Lobodzinski97dcd042015-04-16 08:52:00 -0500276 primary_mem_ = &internal_mems_[i];
Chia-I Wu82bff272014-12-27 14:12:52 +0800277 internal_mems_[i].init(dev, info);
278 bind_memory(i, internal_mems_[i], 0);
279 }
280}
281
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600282void Object::alloc_memory(const std::vector<VkGpuMemory> &mems)
Chia-I Wu82bff272014-12-27 14:12:52 +0800283{
284 if (!EXPECT(!internal_mems_) || !mem_alloc_count_)
285 return;
286
287 internal_mems_ = new GpuMemory[mem_alloc_count_];
288
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600289 const std::vector<VkMemoryRequirements> mem_reqs = memory_requirements();
Chia-I Wu82bff272014-12-27 14:12:52 +0800290 if (!EXPECT(mem_reqs.size() == mems.size()))
291 return;
292
293 for (int i = 0; i < mem_reqs.size(); i++) {
294 primary_mem_ = &internal_mems_[i];
295
296 internal_mems_[i].init(mems[i]);
297 bind_memory(i, internal_mems_[i], 0);
298 }
299}
300
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600301std::vector<VkGpuMemory> Object::memories() const
Chia-I Wu82bff272014-12-27 14:12:52 +0800302{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600303 std::vector<VkGpuMemory> mems;
Chia-I Wu82bff272014-12-27 14:12:52 +0800304 if (internal_mems_) {
305 mems.reserve(mem_alloc_count_);
306 for (uint32_t i = 0; i < mem_alloc_count_; i++)
307 mems.push_back(internal_mems_[i].obj());
308 }
309
310 return mems;
311}
312
313Device::~Device()
314{
315 if (!initialized())
316 return;
317
318 for (int i = 0; i < QUEUE_COUNT; i++) {
319 for (std::vector<Queue *>::iterator it = queues_[i].begin(); it != queues_[i].end(); it++)
320 delete *it;
321 queues_[i].clear();
322 }
323
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600324 EXPECT(vkDestroyDevice(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800325}
326
Chia-I Wu6c099222015-01-06 10:40:45 +0800327void Device::init(bool enable_layers)
Chia-I Wu82bff272014-12-27 14:12:52 +0800328{
329 // request all queues
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600330 const std::vector<VkPhysicalGpuQueueProperties> queue_props = gpu_.queue_properties();
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600331 std::vector<VkDeviceQueueCreateInfo> queue_info;
Chia-I Wu82bff272014-12-27 14:12:52 +0800332 queue_info.reserve(queue_props.size());
333 for (int i = 0; i < queue_props.size(); i++) {
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600334 VkDeviceQueueCreateInfo qi = {};
Chia-I Wu82bff272014-12-27 14:12:52 +0800335 qi.queueNodeIndex = i;
336 qi.queueCount = queue_props[i].queueCount;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600337 if (queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700338 graphics_queue_node_index_ = i;
339 }
Chia-I Wu82bff272014-12-27 14:12:52 +0800340 queue_info.push_back(qi);
341 }
342
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600343 VkLayerCreateInfo layer_info = {};
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600344 layer_info.sType = VK_STRUCTURE_TYPE_LAYER_CREATE_INFO;
Chia-I Wu6c099222015-01-06 10:40:45 +0800345
346 std::vector<const char *> layers;
347 std::vector<char> layer_buf;
348 // request all layers
349 if (enable_layers) {
350 layers = gpu_.layers(layer_buf);
351 layer_info.layerCount = layers.size();
352 layer_info.ppActiveLayerNames = &layers[0];
353 }
Chia-I Wu82bff272014-12-27 14:12:52 +0800354
355 const std::vector<const char *> exts = gpu_.extensions();
356
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600357 VkDeviceCreateInfo dev_info = {};
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600358 dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
Jon Ashburnca930582015-01-22 13:33:15 -0700359 dev_info.pNext = (enable_layers) ? static_cast<void *>(&layer_info) : NULL;
Chia-I Wu82bff272014-12-27 14:12:52 +0800360 dev_info.queueRecordCount = queue_info.size();
361 dev_info.pRequestedQueues = &queue_info[0];
362 dev_info.extensionCount = exts.size();
363 dev_info.ppEnabledExtensionNames = &exts[0];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600364 dev_info.flags = VK_DEVICE_CREATE_VALIDATION_BIT;
Chia-I Wu82bff272014-12-27 14:12:52 +0800365
366 init(dev_info);
367}
368
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600369void Device::init(const VkDeviceCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800370{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600371 DERIVED_OBJECT_INIT(vkCreateDevice, gpu_.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800372
373 init_queues();
Chia-I Wu82bff272014-12-27 14:12:52 +0800374 init_formats();
375}
376
377void Device::init_queues()
378{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600379 VkResult err;
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700380 size_t data_size;
381 uint32_t queue_node_count;
Chia-I Wu82bff272014-12-27 14:12:52 +0800382
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600383 err = vkGetGpuInfo(gpu_.obj(), VK_INFO_TYPE_PHYSICAL_GPU_QUEUE_PROPERTIES,
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700384 &data_size, NULL);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600385 EXPECT(err == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800386
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600387 queue_node_count = data_size / sizeof(VkPhysicalGpuQueueProperties);
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700388 EXPECT(queue_node_count >= 1);
389
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600390 VkPhysicalGpuQueueProperties queue_props[queue_node_count];
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700391
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600392 err = vkGetGpuInfo(gpu_.obj(), VK_INFO_TYPE_PHYSICAL_GPU_QUEUE_PROPERTIES,
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700393 &data_size, queue_props);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600394 EXPECT(err == VK_SUCCESS);
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700395
396 for (int i = 0; i < queue_node_count; i++) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600397 VkQueue queue;
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700398
399 for (int j = 0; j < queue_props[i].queueCount; j++) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600400 err = vkGetDeviceQueue(obj(), i, j, &queue);
401 EXPECT(err == VK_SUCCESS);
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700402
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600403 if (queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700404 queues_[GRAPHICS].push_back(new Queue(queue));
405 }
406
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600407 if (queue_props[i].queueFlags & VK_QUEUE_COMPUTE_BIT) {
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700408 queues_[COMPUTE].push_back(new Queue(queue));
409 }
410
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600411 if (queue_props[i].queueFlags & VK_QUEUE_DMA_BIT) {
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700412 queues_[DMA].push_back(new Queue(queue));
413 }
Chia-I Wu82bff272014-12-27 14:12:52 +0800414 }
415 }
416
417 EXPECT(!queues_[GRAPHICS].empty() || !queues_[COMPUTE].empty());
418}
419
Chia-I Wu82bff272014-12-27 14:12:52 +0800420void Device::init_formats()
421{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600422 for (int f = VK_FMT_BEGIN_RANGE; f <= VK_FMT_END_RANGE; f++) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600423 const VkFormat fmt = static_cast<VkFormat>(f);
424 const VkFormatProperties props = format_properties(fmt);
Chia-I Wu82bff272014-12-27 14:12:52 +0800425
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700426 if (props.linearTilingFeatures) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600427 const Format tmp = { fmt, VK_LINEAR_TILING, props.linearTilingFeatures };
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700428 formats_.push_back(tmp);
429 }
Chia-I Wu82bff272014-12-27 14:12:52 +0800430
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700431 if (props.optimalTilingFeatures) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600432 const Format tmp = { fmt, VK_OPTIMAL_TILING, props.optimalTilingFeatures };
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700433 formats_.push_back(tmp);
Chia-I Wu82bff272014-12-27 14:12:52 +0800434 }
435 }
436
437 EXPECT(!formats_.empty());
438}
439
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600440VkFormatProperties Device::format_properties(VkFormat format)
Chia-I Wu82bff272014-12-27 14:12:52 +0800441{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600442 const VkFormatInfoType type = VK_INFO_TYPE_FORMAT_PROPERTIES;
443 VkFormatProperties data;
Chia-I Wu82bff272014-12-27 14:12:52 +0800444 size_t size = sizeof(data);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600445 if (!EXPECT(vkGetFormatInfo(obj(), format, type, &size, &data) == VK_SUCCESS && size == sizeof(data)))
Chia-I Wu82bff272014-12-27 14:12:52 +0800446 memset(&data, 0, sizeof(data));
447
448 return data;
449}
450
451void Device::wait()
452{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600453 EXPECT(vkDeviceWaitIdle(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800454}
455
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600456VkResult Device::wait(const std::vector<const Fence *> &fences, bool wait_all, uint64_t timeout)
Chia-I Wu82bff272014-12-27 14:12:52 +0800457{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600458 const std::vector<VkFence> fence_objs = make_objects<VkFence>(fences);
459 VkResult err = vkWaitForFences(obj(), fence_objs.size(), &fence_objs[0], wait_all, timeout);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600460 EXPECT(err == VK_SUCCESS || err == VK_TIMEOUT);
Chia-I Wu82bff272014-12-27 14:12:52 +0800461
462 return err;
463}
464
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600465void Device::begin_descriptor_pool_update(VkDescriptorUpdateMode mode)
Chia-I Wuf8385062015-01-04 16:27:24 +0800466{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600467 EXPECT(vkBeginDescriptorPoolUpdate(obj(), mode) == VK_SUCCESS);
Chia-I Wuf8385062015-01-04 16:27:24 +0800468}
469
Chia-I Wu8d24b3b2015-03-26 13:14:16 +0800470void Device::end_descriptor_pool_update(CmdBuffer &cmd)
Chia-I Wuf8385062015-01-04 16:27:24 +0800471{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600472 EXPECT(vkEndDescriptorPoolUpdate(obj(), cmd.obj()) == VK_SUCCESS);
Chia-I Wuf8385062015-01-04 16:27:24 +0800473}
474
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600475void Queue::submit(const std::vector<const CmdBuffer *> &cmds, Fence &fence)
Chia-I Wu82bff272014-12-27 14:12:52 +0800476{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600477 const std::vector<VkCmdBuffer> cmd_objs = make_objects<VkCmdBuffer>(cmds);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600478 EXPECT(vkQueueSubmit(obj(), cmd_objs.size(), &cmd_objs[0], fence.obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800479}
480
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600481void Queue::submit(const CmdBuffer &cmd, Fence &fence)
Chia-I Wu82bff272014-12-27 14:12:52 +0800482{
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600483 submit(std::vector<const CmdBuffer*>(1, &cmd), fence);
Chia-I Wu82bff272014-12-27 14:12:52 +0800484}
485
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600486void Queue::submit(const CmdBuffer &cmd)
Chia-I Wu82bff272014-12-27 14:12:52 +0800487{
488 Fence fence;
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600489 submit(cmd, fence);
Chia-I Wu82bff272014-12-27 14:12:52 +0800490}
491
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600492void Queue::add_mem_references(const std::vector<VkGpuMemory> &mem_refs)
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600493{
494 for (int i = 0; i < mem_refs.size(); i++) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600495 EXPECT(vkQueueAddMemReference(obj(), mem_refs[i]) == VK_SUCCESS);
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600496 }
497}
498
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600499void Queue::remove_mem_references(const std::vector<VkGpuMemory> &mem_refs)
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600500{
501 for (int i = 0; i < mem_refs.size(); i++) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600502 EXPECT(vkQueueRemoveMemReference(obj(), mem_refs[i]) == VK_SUCCESS);
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600503 }
504}
Chia-I Wu82bff272014-12-27 14:12:52 +0800505
506void Queue::wait()
507{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600508 EXPECT(vkQueueWaitIdle(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800509}
510
Courtney Goeltzenleuchter0d2efef2015-03-25 17:14:29 -0600511void Queue::signal_semaphore(Semaphore &sem)
Chia-I Wu82bff272014-12-27 14:12:52 +0800512{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600513 EXPECT(vkQueueSignalSemaphore(obj(), sem.obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800514}
515
Courtney Goeltzenleuchter0d2efef2015-03-25 17:14:29 -0600516void Queue::wait_semaphore(Semaphore &sem)
Chia-I Wu82bff272014-12-27 14:12:52 +0800517{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600518 EXPECT(vkQueueWaitSemaphore(obj(), sem.obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800519}
520
521GpuMemory::~GpuMemory()
522{
523 if (initialized() && own())
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600524 EXPECT(vkFreeMemory(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800525}
526
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600527void GpuMemory::init(const Device &dev, const VkMemoryAllocInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800528{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600529 DERIVED_OBJECT_INIT(vkAllocMemory, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800530}
531
Chia-I Wu82bff272014-12-27 14:12:52 +0800532void GpuMemory::init(const Device &dev, size_t size, const void *data)
533{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600534 DERIVED_OBJECT_INIT(vkPinSystemMemory, dev.obj(), data, size);
Chia-I Wu82bff272014-12-27 14:12:52 +0800535}
536
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600537void GpuMemory::init(const Device &dev, const VkMemoryOpenInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800538{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600539 DERIVED_OBJECT_INIT(vkOpenSharedMemory, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800540}
541
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600542void GpuMemory::init(const Device &dev, const VkPeerMemoryOpenInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800543{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600544 DERIVED_OBJECT_INIT(vkOpenPeerMemory, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800545}
546
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600547void GpuMemory::set_priority(VkMemoryPriority priority)
Chia-I Wu82bff272014-12-27 14:12:52 +0800548{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600549 EXPECT(vkSetMemoryPriority(obj(), priority) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800550}
551
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600552const void *GpuMemory::map(VkFlags flags) const
Chia-I Wu82bff272014-12-27 14:12:52 +0800553{
554 void *data;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600555 if (!EXPECT(vkMapMemory(obj(), flags, &data) == VK_SUCCESS))
Chia-I Wu82bff272014-12-27 14:12:52 +0800556 data = NULL;
557
558 return data;
559}
560
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600561void *GpuMemory::map(VkFlags flags)
Chia-I Wu82bff272014-12-27 14:12:52 +0800562{
563 void *data;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600564 if (!EXPECT(vkMapMemory(obj(), flags, &data) == VK_SUCCESS))
Chia-I Wu82bff272014-12-27 14:12:52 +0800565 data = NULL;
566
567 return data;
568}
569
570void GpuMemory::unmap() const
571{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600572 EXPECT(vkUnmapMemory(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800573}
574
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600575void Fence::init(const Device &dev, const VkFenceCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800576{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600577 DERIVED_OBJECT_INIT(vkCreateFence, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800578 alloc_memory(dev);
579}
580
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600581void Semaphore::init(const Device &dev, const VkSemaphoreCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800582{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600583 DERIVED_OBJECT_INIT(vkCreateSemaphore, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800584 alloc_memory(dev);
585}
586
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600587void Semaphore::init(const Device &dev, const VkSemaphoreOpenInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800588{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600589 DERIVED_OBJECT_INIT(vkOpenSharedSemaphore, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800590}
591
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600592void Event::init(const Device &dev, const VkEventCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800593{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600594 DERIVED_OBJECT_INIT(vkCreateEvent, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800595 alloc_memory(dev);
596}
597
598void Event::set()
599{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600600 EXPECT(vkSetEvent(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800601}
602
603void Event::reset()
604{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600605 EXPECT(vkResetEvent(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800606}
607
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600608void QueryPool::init(const Device &dev, const VkQueryPoolCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800609{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600610 DERIVED_OBJECT_INIT(vkCreateQueryPool, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800611 alloc_memory(dev);
612}
613
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600614VkResult QueryPool::results(uint32_t start, uint32_t count, size_t size, void *data)
Chia-I Wu82bff272014-12-27 14:12:52 +0800615{
616 size_t tmp = size;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600617 VkResult err = vkGetQueryPoolResults(obj(), start, count, &tmp, data);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600618 if (err == VK_SUCCESS) {
Chia-I Wu82bff272014-12-27 14:12:52 +0800619 if (!EXPECT(tmp == size))
620 memset(data, 0, size);
621 } else {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600622 EXPECT(err == VK_NOT_READY);
Chia-I Wu82bff272014-12-27 14:12:52 +0800623 }
624
625 return err;
626}
627
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600628void Buffer::init(const Device &dev, const VkBufferCreateInfo &info)
Chia-I Wu714df452015-01-01 07:55:04 +0800629{
630 init_no_mem(dev, info);
Mark Lobodzinski97dcd042015-04-16 08:52:00 -0500631 alloc_memory(dev);
Chia-I Wu714df452015-01-01 07:55:04 +0800632}
633
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600634void Buffer::init_no_mem(const Device &dev, const VkBufferCreateInfo &info)
Chia-I Wu714df452015-01-01 07:55:04 +0800635{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600636 DERIVED_OBJECT_INIT(vkCreateBuffer, dev.obj(), &info);
Chia-I Wu714df452015-01-01 07:55:04 +0800637 create_info_ = info;
638}
639
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600640void BufferView::init(const Device &dev, const VkBufferViewCreateInfo &info)
Chia-I Wu714df452015-01-01 07:55:04 +0800641{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600642 DERIVED_OBJECT_INIT(vkCreateBufferView, dev.obj(), &info);
Chia-I Wu714df452015-01-01 07:55:04 +0800643 alloc_memory(dev);
644}
645
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600646void Image::init(const Device &dev, const VkImageCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800647{
648 init_no_mem(dev, info);
Mark Lobodzinski97dcd042015-04-16 08:52:00 -0500649 alloc_memory(dev);
Chia-I Wu82bff272014-12-27 14:12:52 +0800650}
651
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600652void Image::init_no_mem(const Device &dev, const VkImageCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800653{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600654 DERIVED_OBJECT_INIT(vkCreateImage, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800655 init_info(dev, info);
656}
657
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600658void Image::init(const Device &dev, const VkPeerImageOpenInfo &info, const VkImageCreateInfo &original_info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800659{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600660 VkImage img;
661 VkGpuMemory mem;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600662 EXPECT(vkOpenPeerImage(dev.obj(), &info, &img, &mem) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800663 Object::init(img);
664
665 init_info(dev, original_info);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600666 alloc_memory(std::vector<VkGpuMemory>(1, mem));
Chia-I Wu82bff272014-12-27 14:12:52 +0800667}
668
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600669void Image::init_info(const Device &dev, const VkImageCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800670{
671 create_info_ = info;
672
673 for (std::vector<Device::Format>::const_iterator it = dev.formats().begin(); it != dev.formats().end(); it++) {
674 if (memcmp(&it->format, &create_info_.format, sizeof(it->format)) == 0 && it->tiling == create_info_.tiling) {
675 format_features_ = it->features;
676 break;
677 }
678 }
679}
680
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600681void Image::bind_memory(uint32_t alloc_idx, const VkImageMemoryBindInfo &info,
682 const GpuMemory &mem, VkGpuSize mem_offset)
Chia-I Wu714df452015-01-01 07:55:04 +0800683{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600684 EXPECT(!alloc_idx && vkBindImageMemoryRange(obj(), 0, &info, mem.obj(), mem_offset) == VK_SUCCESS);
Chia-I Wu714df452015-01-01 07:55:04 +0800685}
686
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600687VkSubresourceLayout Image::subresource_layout(const VkImageSubresource &subres) const
Chia-I Wu82bff272014-12-27 14:12:52 +0800688{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600689 const VkSubresourceInfoType type = VK_INFO_TYPE_SUBRESOURCE_LAYOUT;
690 VkSubresourceLayout data;
Chia-I Wu82bff272014-12-27 14:12:52 +0800691 size_t size = sizeof(data);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600692 if (!EXPECT(vkGetImageSubresourceInfo(obj(), &subres, type, &size, &data) == VK_SUCCESS && size == sizeof(data)))
Chia-I Wu82bff272014-12-27 14:12:52 +0800693 memset(&data, 0, sizeof(data));
694
695 return data;
696}
697
698bool Image::transparent() const
699{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600700 return (create_info_.tiling == VK_LINEAR_TILING &&
Chia-I Wu82bff272014-12-27 14:12:52 +0800701 create_info_.samples == 1 &&
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600702 !(create_info_.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
703 VK_IMAGE_USAGE_DEPTH_STENCIL_BIT)));
Chia-I Wu82bff272014-12-27 14:12:52 +0800704}
705
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600706void ImageView::init(const Device &dev, const VkImageViewCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800707{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600708 DERIVED_OBJECT_INIT(vkCreateImageView, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800709 alloc_memory(dev);
710}
711
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600712void ColorAttachmentView::init(const Device &dev, const VkColorAttachmentViewCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800713{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600714 DERIVED_OBJECT_INIT(vkCreateColorAttachmentView, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800715 alloc_memory(dev);
716}
717
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600718void DepthStencilView::init(const Device &dev, const VkDepthStencilViewCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800719{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600720 DERIVED_OBJECT_INIT(vkCreateDepthStencilView, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800721 alloc_memory(dev);
722}
723
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600724void Shader::init(const Device &dev, const VkShaderCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800725{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600726 DERIVED_OBJECT_INIT(vkCreateShader, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800727}
728
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600729VkResult Shader::init_try(const Device &dev, const VkShaderCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800730{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600731 VkShader sh;
732 VkResult err = vkCreateShader(dev.obj(), &info, &sh);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600733 if (err == VK_SUCCESS)
Chia-I Wu82bff272014-12-27 14:12:52 +0800734 Object::init(sh);
735
736 return err;
737}
738
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600739void Pipeline::init(const Device &dev, const VkGraphicsPipelineCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800740{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600741 DERIVED_OBJECT_INIT(vkCreateGraphicsPipeline, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800742 alloc_memory(dev);
743}
744
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -0600745void Pipeline::init(
746 const Device &dev,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600747 const VkGraphicsPipelineCreateInfo &info,
748 const VkPipeline basePipeline)
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -0600749{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600750 DERIVED_OBJECT_INIT(vkCreateGraphicsPipelineDerivative, dev.obj(), &info, basePipeline);
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -0600751 alloc_memory(dev);
752}
753
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600754void Pipeline::init(const Device &dev, const VkComputePipelineCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800755{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600756 DERIVED_OBJECT_INIT(vkCreateComputePipeline, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800757 alloc_memory(dev);
758}
759
760void Pipeline::init(const Device&dev, size_t size, const void *data)
761{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600762 DERIVED_OBJECT_INIT(vkLoadPipeline, dev.obj(), size, data);
Chia-I Wu82bff272014-12-27 14:12:52 +0800763 alloc_memory(dev);
764}
765
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -0600766void Pipeline::init(
767 const Device&dev,
768 size_t size,
769 const void *data,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600770 const VkPipeline basePipeline)
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -0600771{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600772 DERIVED_OBJECT_INIT(vkLoadPipelineDerivative, dev.obj(), size, data, basePipeline);
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -0600773 alloc_memory(dev);
774}
775
Chia-I Wu82bff272014-12-27 14:12:52 +0800776size_t Pipeline::store(size_t size, void *data)
777{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600778 if (!EXPECT(vkStorePipeline(obj(), &size, data) == VK_SUCCESS))
Chia-I Wu82bff272014-12-27 14:12:52 +0800779 size = 0;
780
781 return size;
782}
783
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600784void Sampler::init(const Device &dev, const VkSamplerCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800785{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600786 DERIVED_OBJECT_INIT(vkCreateSampler, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800787 alloc_memory(dev);
788}
789
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600790void DescriptorSetLayout::init(const Device &dev, const VkDescriptorSetLayoutCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800791{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600792 DERIVED_OBJECT_INIT(vkCreateDescriptorSetLayout, dev.obj(), &info);
Chia-I Wuf8385062015-01-04 16:27:24 +0800793 alloc_memory(dev);
Chia-I Wu82bff272014-12-27 14:12:52 +0800794}
795
Chia-I Wu7732cb22015-03-26 15:27:55 +0800796void DescriptorSetLayoutChain::init(const Device &dev, const std::vector<const DescriptorSetLayout *> &layouts)
Chia-I Wu82bff272014-12-27 14:12:52 +0800797{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600798 const std::vector<VkDescriptorSetLayout> layout_objs = make_objects<VkDescriptorSetLayout>(layouts);
Chia-I Wu7732cb22015-03-26 15:27:55 +0800799
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600800 DERIVED_OBJECT_INIT(vkCreateDescriptorSetLayoutChain, dev.obj(), layout_objs.size(), &layout_objs[0]);
Chia-I Wu7732cb22015-03-26 15:27:55 +0800801 alloc_memory(dev);
Chia-I Wu82bff272014-12-27 14:12:52 +0800802}
803
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600804void DescriptorPool::init(const Device &dev, VkDescriptorPoolUsage usage,
805 uint32_t max_sets, const VkDescriptorPoolCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800806{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600807 DERIVED_OBJECT_INIT(vkCreateDescriptorPool, dev.obj(), usage, max_sets, &info);
Chia-I Wuf8385062015-01-04 16:27:24 +0800808 alloc_memory(dev);
Chia-I Wu82bff272014-12-27 14:12:52 +0800809}
810
Chia-I Wudee95612015-03-26 15:23:52 +0800811void DescriptorPool::reset()
Chia-I Wu82bff272014-12-27 14:12:52 +0800812{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600813 EXPECT(vkResetDescriptorPool(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800814}
815
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600816std::vector<DescriptorSet *> DescriptorPool::alloc_sets(VkDescriptorSetUsage usage, const std::vector<const DescriptorSetLayout *> &layouts)
Chia-I Wu82bff272014-12-27 14:12:52 +0800817{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600818 const std::vector<VkDescriptorSetLayout> layout_objs = make_objects<VkDescriptorSetLayout>(layouts);
Chia-I Wuf8385062015-01-04 16:27:24 +0800819
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600820 std::vector<VkDescriptorSet> set_objs;
Chia-I Wuf8385062015-01-04 16:27:24 +0800821 set_objs.resize(layout_objs.size());
822
823 uint32_t set_count;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600824 VkResult err = vkAllocDescriptorSets(obj(), usage, layout_objs.size(), &layout_objs[0], &set_objs[0], &set_count);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600825 if (err == VK_SUCCESS)
Chia-I Wuf8385062015-01-04 16:27:24 +0800826 EXPECT(set_count == set_objs.size());
827 set_objs.resize(set_count);
828
829 std::vector<DescriptorSet *> sets;
830 sets.reserve(set_count);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600831 for (std::vector<VkDescriptorSet>::const_iterator it = set_objs.begin(); it != set_objs.end(); it++) {
Chia-I Wuf8385062015-01-04 16:27:24 +0800832 // do descriptor sets need memories bound?
833 sets.push_back(new DescriptorSet(*it));
834 }
835
836 return sets;
837}
838
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600839std::vector<DescriptorSet *> DescriptorPool::alloc_sets(VkDescriptorSetUsage usage, const DescriptorSetLayout &layout, uint32_t count)
Chia-I Wuf8385062015-01-04 16:27:24 +0800840{
841 return alloc_sets(usage, std::vector<const DescriptorSetLayout *>(count, &layout));
842}
843
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600844DescriptorSet *DescriptorPool::alloc_sets(VkDescriptorSetUsage usage, const DescriptorSetLayout &layout)
Chia-I Wuf8385062015-01-04 16:27:24 +0800845{
846 std::vector<DescriptorSet *> set = alloc_sets(usage, layout, 1);
847 return (set.empty()) ? NULL : set[0];
848}
849
Chia-I Wu8d24b3b2015-03-26 13:14:16 +0800850void DescriptorPool::clear_sets(const std::vector<DescriptorSet *> &sets)
Chia-I Wuf8385062015-01-04 16:27:24 +0800851{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600852 const std::vector<VkDescriptorSet> set_objs = make_objects<VkDescriptorSet>(sets);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600853 vkClearDescriptorSets(obj(), set_objs.size(), &set_objs[0]);
Chia-I Wuf8385062015-01-04 16:27:24 +0800854}
855
Chia-I Wu7732cb22015-03-26 15:27:55 +0800856void DescriptorSet::update(const std::vector<const void *> &update_array)
Chia-I Wuf8385062015-01-04 16:27:24 +0800857{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600858 vkUpdateDescriptors(obj(), update_array.size(), const_cast<const void **>(&update_array[0]));
Chia-I Wu82bff272014-12-27 14:12:52 +0800859}
860
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600861void DynamicVpStateObject::init(const Device &dev, const VkDynamicVpStateCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800862{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600863 DERIVED_OBJECT_INIT(vkCreateDynamicViewportState, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800864 alloc_memory(dev);
865}
866
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600867void DynamicRsStateObject::init(const Device &dev, const VkDynamicRsStateCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800868{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600869 DERIVED_OBJECT_INIT(vkCreateDynamicRasterState, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800870 alloc_memory(dev);
871}
872
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600873void DynamicCbStateObject::init(const Device &dev, const VkDynamicCbStateCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800874{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600875 DERIVED_OBJECT_INIT(vkCreateDynamicColorBlendState, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800876 alloc_memory(dev);
877}
878
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600879void DynamicDsStateObject::init(const Device &dev, const VkDynamicDsStateCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800880{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600881 DERIVED_OBJECT_INIT(vkCreateDynamicDepthStencilState, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800882 alloc_memory(dev);
883}
884
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600885void CmdBuffer::init(const Device &dev, const VkCmdBufferCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800886{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600887 DERIVED_OBJECT_INIT(vkCreateCommandBuffer, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800888}
889
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600890void CmdBuffer::begin(const VkCmdBufferBeginInfo *info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800891{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600892 EXPECT(vkBeginCommandBuffer(obj(), info) == VK_SUCCESS);
Jeremy Hayese0c3b222015-01-14 16:17:08 -0700893}
894
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600895void CmdBuffer::begin(VkRenderPass renderpass_obj, VkFramebuffer framebuffer_obj)
Jeremy Hayese0c3b222015-01-14 16:17:08 -0700896{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600897 VkCmdBufferBeginInfo info = {};
898 VkCmdBufferGraphicsBeginInfo graphics_cmd_buf_info = {};
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600899 graphics_cmd_buf_info.sType = VK_STRUCTURE_TYPE_CMD_BUFFER_GRAPHICS_BEGIN_INFO;
Tony Barbour901f3bc2015-04-01 17:10:07 -0600900 graphics_cmd_buf_info.pNext = NULL;
Courtney Goeltzenleuchtere3b0f3a2015-04-03 15:25:24 -0600901 graphics_cmd_buf_info.renderPassContinue.renderPass = renderpass_obj;
902 graphics_cmd_buf_info.renderPassContinue.framebuffer = framebuffer_obj;
Tony Barbour901f3bc2015-04-01 17:10:07 -0600903
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600904 info.flags = VK_CMD_BUFFER_OPTIMIZE_GPU_SMALL_BATCH_BIT |
905 VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT;
906 info.sType = VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO;
Jeremy Hayese0c3b222015-01-14 16:17:08 -0700907 info.pNext = &graphics_cmd_buf_info;
908
909 begin(&info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800910}
911
912void CmdBuffer::begin()
913{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600914 VkCmdBufferBeginInfo info = {};
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600915 info.flags = VK_CMD_BUFFER_OPTIMIZE_GPU_SMALL_BATCH_BIT |
916 VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT;
917 info.sType = VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO;
Jeremy Hayese0c3b222015-01-14 16:17:08 -0700918
919 begin(&info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800920}
921
922void CmdBuffer::end()
923{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600924 EXPECT(vkEndCommandBuffer(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800925}
926
927void CmdBuffer::reset()
928{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600929 EXPECT(vkResetCommandBuffer(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800930}
931
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600932}; // namespace vk_testing