blob: ea968630e1f6b42e8af503545736d3772a9220f2 [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
Jon Ashburn5567c812015-01-20 08:50:12 -0700264void Object::alloc_memory(const Device &dev, bool for_buf, bool for_img)
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();
272 std::vector<VkImageMemoryRequirements> img_reqs;
273 std::vector<VkBufferMemoryRequirements> buf_reqs;
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600274 VkMemoryAllocImageInfo img_info;
275 VkMemoryAllocBufferInfo buf_info;
276 VkMemoryAllocInfo info, *next_info = NULL;
Jon Ashburnc6ae13d2015-01-19 15:00:26 -0700277
Jon Ashburn5567c812015-01-20 08:50:12 -0700278 if (for_img) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600279 img_reqs = get_info<VkImageMemoryRequirements>(obj(),
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600280 VK_INFO_TYPE_IMAGE_MEMORY_REQUIREMENTS, 0);
Jon Ashburnc6ae13d2015-01-19 15:00:26 -0700281 EXPECT(img_reqs.size() == 1);
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600282 next_info = (VkMemoryAllocInfo *) &img_info;
Jon Ashburnc6ae13d2015-01-19 15:00:26 -0700283 img_info.pNext = NULL;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600284 img_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_IMAGE_INFO;
Jon Ashburnc6ae13d2015-01-19 15:00:26 -0700285 img_info.usage = img_reqs[0].usage;
286 img_info.formatClass = img_reqs[0].formatClass;
287 img_info.samples = img_reqs[0].samples;
288 }
289
290
Jon Ashburn5567c812015-01-20 08:50:12 -0700291 if (for_buf) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600292 buf_reqs = get_info<VkBufferMemoryRequirements>(obj(),
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600293 VK_INFO_TYPE_BUFFER_MEMORY_REQUIREMENTS, 0);
Jon Ashburn5567c812015-01-20 08:50:12 -0700294 if (for_img)
295 img_info.pNext = &buf_info;
296 else
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600297 next_info = (VkMemoryAllocInfo *) &buf_info;
Jon Ashburn5567c812015-01-20 08:50:12 -0700298 buf_info.pNext = NULL;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600299 buf_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_BUFFER_INFO;
Jon Ashburn5567c812015-01-20 08:50:12 -0700300 buf_info.usage = buf_reqs[0].usage;
301 }
302
303
Chia-I Wu82bff272014-12-27 14:12:52 +0800304 for (int i = 0; i < mem_reqs.size(); i++) {
Jon Ashburn5567c812015-01-20 08:50:12 -0700305 info = GpuMemory::alloc_info(mem_reqs[i], next_info);
Chia-I Wu714df452015-01-01 07:55:04 +0800306
Jon Ashburn661c3292015-01-22 11:40:11 -0700307 switch (info.memType) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600308 case VK_MEMORY_TYPE_BUFFER:
Jon Ashburn661c3292015-01-22 11:40:11 -0700309 EXPECT(for_buf);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600310 info.memProps |= VK_MEMORY_PROPERTY_CPU_VISIBLE_BIT;
Jon Ashburn661c3292015-01-22 11:40:11 -0700311 primary_mem_ = &internal_mems_[i];
312 break;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600313 case VK_MEMORY_TYPE_IMAGE:
Jon Ashburn661c3292015-01-22 11:40:11 -0700314 EXPECT(for_img);
315 primary_mem_ = &internal_mems_[i];
316 break;
317 default:
318 break;
319 }
Chia-I Wu82bff272014-12-27 14:12:52 +0800320
321 internal_mems_[i].init(dev, info);
322 bind_memory(i, internal_mems_[i], 0);
323 }
324}
325
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600326void Object::alloc_memory(const std::vector<VkGpuMemory> &mems)
Chia-I Wu82bff272014-12-27 14:12:52 +0800327{
328 if (!EXPECT(!internal_mems_) || !mem_alloc_count_)
329 return;
330
331 internal_mems_ = new GpuMemory[mem_alloc_count_];
332
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600333 const std::vector<VkMemoryRequirements> mem_reqs = memory_requirements();
Chia-I Wu82bff272014-12-27 14:12:52 +0800334 if (!EXPECT(mem_reqs.size() == mems.size()))
335 return;
336
337 for (int i = 0; i < mem_reqs.size(); i++) {
338 primary_mem_ = &internal_mems_[i];
339
340 internal_mems_[i].init(mems[i]);
341 bind_memory(i, internal_mems_[i], 0);
342 }
343}
344
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600345std::vector<VkGpuMemory> Object::memories() const
Chia-I Wu82bff272014-12-27 14:12:52 +0800346{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600347 std::vector<VkGpuMemory> mems;
Chia-I Wu82bff272014-12-27 14:12:52 +0800348 if (internal_mems_) {
349 mems.reserve(mem_alloc_count_);
350 for (uint32_t i = 0; i < mem_alloc_count_; i++)
351 mems.push_back(internal_mems_[i].obj());
352 }
353
354 return mems;
355}
356
357Device::~Device()
358{
359 if (!initialized())
360 return;
361
362 for (int i = 0; i < QUEUE_COUNT; i++) {
363 for (std::vector<Queue *>::iterator it = queues_[i].begin(); it != queues_[i].end(); it++)
364 delete *it;
365 queues_[i].clear();
366 }
367
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600368 EXPECT(vkDestroyDevice(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800369}
370
Chia-I Wu6c099222015-01-06 10:40:45 +0800371void Device::init(bool enable_layers)
Chia-I Wu82bff272014-12-27 14:12:52 +0800372{
373 // request all queues
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600374 const std::vector<VkPhysicalGpuQueueProperties> queue_props = gpu_.queue_properties();
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600375 std::vector<VkDeviceQueueCreateInfo> queue_info;
Chia-I Wu82bff272014-12-27 14:12:52 +0800376 queue_info.reserve(queue_props.size());
377 for (int i = 0; i < queue_props.size(); i++) {
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600378 VkDeviceQueueCreateInfo qi = {};
Chia-I Wu82bff272014-12-27 14:12:52 +0800379 qi.queueNodeIndex = i;
380 qi.queueCount = queue_props[i].queueCount;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600381 if (queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700382 graphics_queue_node_index_ = i;
383 }
Chia-I Wu82bff272014-12-27 14:12:52 +0800384 queue_info.push_back(qi);
385 }
386
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600387 VkLayerCreateInfo layer_info = {};
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600388 layer_info.sType = VK_STRUCTURE_TYPE_LAYER_CREATE_INFO;
Chia-I Wu6c099222015-01-06 10:40:45 +0800389
390 std::vector<const char *> layers;
391 std::vector<char> layer_buf;
392 // request all layers
393 if (enable_layers) {
394 layers = gpu_.layers(layer_buf);
395 layer_info.layerCount = layers.size();
396 layer_info.ppActiveLayerNames = &layers[0];
397 }
Chia-I Wu82bff272014-12-27 14:12:52 +0800398
399 const std::vector<const char *> exts = gpu_.extensions();
400
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600401 VkDeviceCreateInfo dev_info = {};
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600402 dev_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
Jon Ashburnca930582015-01-22 13:33:15 -0700403 dev_info.pNext = (enable_layers) ? static_cast<void *>(&layer_info) : NULL;
Chia-I Wu82bff272014-12-27 14:12:52 +0800404 dev_info.queueRecordCount = queue_info.size();
405 dev_info.pRequestedQueues = &queue_info[0];
406 dev_info.extensionCount = exts.size();
407 dev_info.ppEnabledExtensionNames = &exts[0];
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600408 dev_info.flags = VK_DEVICE_CREATE_VALIDATION_BIT;
Chia-I Wu82bff272014-12-27 14:12:52 +0800409
410 init(dev_info);
411}
412
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600413void Device::init(const VkDeviceCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800414{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600415 DERIVED_OBJECT_INIT(vkCreateDevice, gpu_.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800416
417 init_queues();
Chia-I Wu82bff272014-12-27 14:12:52 +0800418 init_formats();
419}
420
421void Device::init_queues()
422{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600423 VkResult err;
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700424 size_t data_size;
425 uint32_t queue_node_count;
Chia-I Wu82bff272014-12-27 14:12:52 +0800426
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600427 err = vkGetGpuInfo(gpu_.obj(), VK_INFO_TYPE_PHYSICAL_GPU_QUEUE_PROPERTIES,
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700428 &data_size, NULL);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600429 EXPECT(err == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800430
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600431 queue_node_count = data_size / sizeof(VkPhysicalGpuQueueProperties);
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700432 EXPECT(queue_node_count >= 1);
433
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600434 VkPhysicalGpuQueueProperties queue_props[queue_node_count];
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700435
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600436 err = vkGetGpuInfo(gpu_.obj(), VK_INFO_TYPE_PHYSICAL_GPU_QUEUE_PROPERTIES,
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700437 &data_size, queue_props);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600438 EXPECT(err == VK_SUCCESS);
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700439
440 for (int i = 0; i < queue_node_count; i++) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600441 VkQueue queue;
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700442
443 for (int j = 0; j < queue_props[i].queueCount; j++) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600444 err = vkGetDeviceQueue(obj(), i, j, &queue);
445 EXPECT(err == VK_SUCCESS);
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700446
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600447 if (queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700448 queues_[GRAPHICS].push_back(new Queue(queue));
449 }
450
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600451 if (queue_props[i].queueFlags & VK_QUEUE_COMPUTE_BIT) {
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700452 queues_[COMPUTE].push_back(new Queue(queue));
453 }
454
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600455 if (queue_props[i].queueFlags & VK_QUEUE_DMA_BIT) {
Courtney Goeltzenleuchterf3168062015-03-05 18:09:39 -0700456 queues_[DMA].push_back(new Queue(queue));
457 }
Chia-I Wu82bff272014-12-27 14:12:52 +0800458 }
459 }
460
461 EXPECT(!queues_[GRAPHICS].empty() || !queues_[COMPUTE].empty());
462}
463
Chia-I Wu82bff272014-12-27 14:12:52 +0800464void Device::init_formats()
465{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600466 for (int f = VK_FMT_BEGIN_RANGE; f <= VK_FMT_END_RANGE; f++) {
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600467 const VkFormat fmt = static_cast<VkFormat>(f);
468 const VkFormatProperties props = format_properties(fmt);
Chia-I Wu82bff272014-12-27 14:12:52 +0800469
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700470 if (props.linearTilingFeatures) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600471 const Format tmp = { fmt, VK_LINEAR_TILING, props.linearTilingFeatures };
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700472 formats_.push_back(tmp);
473 }
Chia-I Wu82bff272014-12-27 14:12:52 +0800474
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700475 if (props.optimalTilingFeatures) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600476 const Format tmp = { fmt, VK_OPTIMAL_TILING, props.optimalTilingFeatures };
Jeremy Hayes2b7e88a2015-01-23 08:51:43 -0700477 formats_.push_back(tmp);
Chia-I Wu82bff272014-12-27 14:12:52 +0800478 }
479 }
480
481 EXPECT(!formats_.empty());
482}
483
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600484VkFormatProperties Device::format_properties(VkFormat format)
Chia-I Wu82bff272014-12-27 14:12:52 +0800485{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600486 const VkFormatInfoType type = VK_INFO_TYPE_FORMAT_PROPERTIES;
487 VkFormatProperties data;
Chia-I Wu82bff272014-12-27 14:12:52 +0800488 size_t size = sizeof(data);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600489 if (!EXPECT(vkGetFormatInfo(obj(), format, type, &size, &data) == VK_SUCCESS && size == sizeof(data)))
Chia-I Wu82bff272014-12-27 14:12:52 +0800490 memset(&data, 0, sizeof(data));
491
492 return data;
493}
494
495void Device::wait()
496{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600497 EXPECT(vkDeviceWaitIdle(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800498}
499
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600500VkResult Device::wait(const std::vector<const Fence *> &fences, bool wait_all, uint64_t timeout)
Chia-I Wu82bff272014-12-27 14:12:52 +0800501{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600502 const std::vector<VkFence> fence_objs = make_objects<VkFence>(fences);
503 VkResult err = vkWaitForFences(obj(), fence_objs.size(), &fence_objs[0], wait_all, timeout);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600504 EXPECT(err == VK_SUCCESS || err == VK_TIMEOUT);
Chia-I Wu82bff272014-12-27 14:12:52 +0800505
506 return err;
507}
508
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600509void Device::begin_descriptor_pool_update(VkDescriptorUpdateMode mode)
Chia-I Wuf8385062015-01-04 16:27:24 +0800510{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600511 EXPECT(vkBeginDescriptorPoolUpdate(obj(), mode) == VK_SUCCESS);
Chia-I Wuf8385062015-01-04 16:27:24 +0800512}
513
Chia-I Wu8d24b3b2015-03-26 13:14:16 +0800514void Device::end_descriptor_pool_update(CmdBuffer &cmd)
Chia-I Wuf8385062015-01-04 16:27:24 +0800515{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600516 EXPECT(vkEndDescriptorPoolUpdate(obj(), cmd.obj()) == VK_SUCCESS);
Chia-I Wuf8385062015-01-04 16:27:24 +0800517}
518
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600519void Queue::submit(const std::vector<const CmdBuffer *> &cmds, Fence &fence)
Chia-I Wu82bff272014-12-27 14:12:52 +0800520{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600521 const std::vector<VkCmdBuffer> cmd_objs = make_objects<VkCmdBuffer>(cmds);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600522 EXPECT(vkQueueSubmit(obj(), cmd_objs.size(), &cmd_objs[0], fence.obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800523}
524
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600525void Queue::submit(const CmdBuffer &cmd, Fence &fence)
Chia-I Wu82bff272014-12-27 14:12:52 +0800526{
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600527 submit(std::vector<const CmdBuffer*>(1, &cmd), fence);
Chia-I Wu82bff272014-12-27 14:12:52 +0800528}
529
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600530void Queue::submit(const CmdBuffer &cmd)
Chia-I Wu82bff272014-12-27 14:12:52 +0800531{
532 Fence fence;
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600533 submit(cmd, fence);
Chia-I Wu82bff272014-12-27 14:12:52 +0800534}
535
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600536void Queue::add_mem_references(const std::vector<VkGpuMemory> &mem_refs)
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600537{
538 for (int i = 0; i < mem_refs.size(); i++) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600539 EXPECT(vkQueueAddMemReference(obj(), mem_refs[i]) == VK_SUCCESS);
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600540 }
541}
542
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600543void Queue::remove_mem_references(const std::vector<VkGpuMemory> &mem_refs)
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600544{
545 for (int i = 0; i < mem_refs.size(); i++) {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600546 EXPECT(vkQueueRemoveMemReference(obj(), mem_refs[i]) == VK_SUCCESS);
Courtney Goeltzenleuchter8d49dbd2015-04-07 17:13:38 -0600547 }
548}
Chia-I Wu82bff272014-12-27 14:12:52 +0800549
550void Queue::wait()
551{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600552 EXPECT(vkQueueWaitIdle(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800553}
554
Courtney Goeltzenleuchter0d2efef2015-03-25 17:14:29 -0600555void Queue::signal_semaphore(Semaphore &sem)
Chia-I Wu82bff272014-12-27 14:12:52 +0800556{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600557 EXPECT(vkQueueSignalSemaphore(obj(), sem.obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800558}
559
Courtney Goeltzenleuchter0d2efef2015-03-25 17:14:29 -0600560void Queue::wait_semaphore(Semaphore &sem)
Chia-I Wu82bff272014-12-27 14:12:52 +0800561{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600562 EXPECT(vkQueueWaitSemaphore(obj(), sem.obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800563}
564
565GpuMemory::~GpuMemory()
566{
567 if (initialized() && own())
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600568 EXPECT(vkFreeMemory(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800569}
570
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600571void GpuMemory::init(const Device &dev, const VkMemoryAllocInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800572{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600573 DERIVED_OBJECT_INIT(vkAllocMemory, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800574}
575
Chia-I Wu82bff272014-12-27 14:12:52 +0800576void GpuMemory::init(const Device &dev, size_t size, const void *data)
577{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600578 DERIVED_OBJECT_INIT(vkPinSystemMemory, dev.obj(), data, size);
Chia-I Wu82bff272014-12-27 14:12:52 +0800579}
580
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600581void GpuMemory::init(const Device &dev, const VkMemoryOpenInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800582{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600583 DERIVED_OBJECT_INIT(vkOpenSharedMemory, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800584}
585
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600586void GpuMemory::init(const Device &dev, const VkPeerMemoryOpenInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800587{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600588 DERIVED_OBJECT_INIT(vkOpenPeerMemory, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800589}
590
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600591void GpuMemory::set_priority(VkMemoryPriority priority)
Chia-I Wu82bff272014-12-27 14:12:52 +0800592{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600593 EXPECT(vkSetMemoryPriority(obj(), priority) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800594}
595
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600596const void *GpuMemory::map(VkFlags flags) const
Chia-I Wu82bff272014-12-27 14:12:52 +0800597{
598 void *data;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600599 if (!EXPECT(vkMapMemory(obj(), flags, &data) == VK_SUCCESS))
Chia-I Wu82bff272014-12-27 14:12:52 +0800600 data = NULL;
601
602 return data;
603}
604
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600605void *GpuMemory::map(VkFlags flags)
Chia-I Wu82bff272014-12-27 14:12:52 +0800606{
607 void *data;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600608 if (!EXPECT(vkMapMemory(obj(), flags, &data) == VK_SUCCESS))
Chia-I Wu82bff272014-12-27 14:12:52 +0800609 data = NULL;
610
611 return data;
612}
613
614void GpuMemory::unmap() const
615{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600616 EXPECT(vkUnmapMemory(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800617}
618
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600619void Fence::init(const Device &dev, const VkFenceCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800620{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600621 DERIVED_OBJECT_INIT(vkCreateFence, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800622 alloc_memory(dev);
623}
624
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600625void Semaphore::init(const Device &dev, const VkSemaphoreCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800626{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600627 DERIVED_OBJECT_INIT(vkCreateSemaphore, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800628 alloc_memory(dev);
629}
630
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600631void Semaphore::init(const Device &dev, const VkSemaphoreOpenInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800632{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600633 DERIVED_OBJECT_INIT(vkOpenSharedSemaphore, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800634}
635
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600636void Event::init(const Device &dev, const VkEventCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800637{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600638 DERIVED_OBJECT_INIT(vkCreateEvent, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800639 alloc_memory(dev);
640}
641
642void Event::set()
643{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600644 EXPECT(vkSetEvent(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800645}
646
647void Event::reset()
648{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600649 EXPECT(vkResetEvent(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800650}
651
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600652void QueryPool::init(const Device &dev, const VkQueryPoolCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800653{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600654 DERIVED_OBJECT_INIT(vkCreateQueryPool, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800655 alloc_memory(dev);
656}
657
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600658VkResult QueryPool::results(uint32_t start, uint32_t count, size_t size, void *data)
Chia-I Wu82bff272014-12-27 14:12:52 +0800659{
660 size_t tmp = size;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600661 VkResult err = vkGetQueryPoolResults(obj(), start, count, &tmp, data);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600662 if (err == VK_SUCCESS) {
Chia-I Wu82bff272014-12-27 14:12:52 +0800663 if (!EXPECT(tmp == size))
664 memset(data, 0, size);
665 } else {
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600666 EXPECT(err == VK_NOT_READY);
Chia-I Wu82bff272014-12-27 14:12:52 +0800667 }
668
669 return err;
670}
671
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600672void Buffer::init(const Device &dev, const VkBufferCreateInfo &info)
Chia-I Wu714df452015-01-01 07:55:04 +0800673{
674 init_no_mem(dev, info);
Jon Ashburn5567c812015-01-20 08:50:12 -0700675 alloc_memory(dev, true, false);
Chia-I Wu714df452015-01-01 07:55:04 +0800676}
677
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600678void Buffer::init_no_mem(const Device &dev, const VkBufferCreateInfo &info)
Chia-I Wu714df452015-01-01 07:55:04 +0800679{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600680 DERIVED_OBJECT_INIT(vkCreateBuffer, dev.obj(), &info);
Chia-I Wu714df452015-01-01 07:55:04 +0800681 create_info_ = info;
682}
683
Courtney Goeltzenleuchterddcb6192015-04-14 18:48:46 -0600684void BufferView::init(const Device &dev, const VkBufferViewCreateInfo &info)
Chia-I Wu714df452015-01-01 07:55:04 +0800685{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600686 DERIVED_OBJECT_INIT(vkCreateBufferView, dev.obj(), &info);
Chia-I Wu714df452015-01-01 07:55:04 +0800687 alloc_memory(dev);
688}
689
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600690void Image::init(const Device &dev, const VkImageCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800691{
692 init_no_mem(dev, info);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600693 alloc_memory(dev, info.tiling == VK_LINEAR_TILING, true);
Chia-I Wu82bff272014-12-27 14:12:52 +0800694}
695
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600696void Image::init_no_mem(const Device &dev, const VkImageCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800697{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600698 DERIVED_OBJECT_INIT(vkCreateImage, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800699 init_info(dev, info);
700}
701
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600702void Image::init(const Device &dev, const VkPeerImageOpenInfo &info, const VkImageCreateInfo &original_info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800703{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600704 VkImage img;
705 VkGpuMemory mem;
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600706 EXPECT(vkOpenPeerImage(dev.obj(), &info, &img, &mem) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800707 Object::init(img);
708
709 init_info(dev, original_info);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600710 alloc_memory(std::vector<VkGpuMemory>(1, mem));
Chia-I Wu82bff272014-12-27 14:12:52 +0800711}
712
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600713void Image::init_info(const Device &dev, const VkImageCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800714{
715 create_info_ = info;
716
717 for (std::vector<Device::Format>::const_iterator it = dev.formats().begin(); it != dev.formats().end(); it++) {
718 if (memcmp(&it->format, &create_info_.format, sizeof(it->format)) == 0 && it->tiling == create_info_.tiling) {
719 format_features_ = it->features;
720 break;
721 }
722 }
723}
724
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600725void Image::bind_memory(uint32_t alloc_idx, const VkImageMemoryBindInfo &info,
726 const GpuMemory &mem, VkGpuSize mem_offset)
Chia-I Wu714df452015-01-01 07:55:04 +0800727{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600728 EXPECT(!alloc_idx && vkBindImageMemoryRange(obj(), 0, &info, mem.obj(), mem_offset) == VK_SUCCESS);
Chia-I Wu714df452015-01-01 07:55:04 +0800729}
730
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600731VkSubresourceLayout Image::subresource_layout(const VkImageSubresource &subres) const
Chia-I Wu82bff272014-12-27 14:12:52 +0800732{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600733 const VkSubresourceInfoType type = VK_INFO_TYPE_SUBRESOURCE_LAYOUT;
734 VkSubresourceLayout data;
Chia-I Wu82bff272014-12-27 14:12:52 +0800735 size_t size = sizeof(data);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600736 if (!EXPECT(vkGetImageSubresourceInfo(obj(), &subres, type, &size, &data) == VK_SUCCESS && size == sizeof(data)))
Chia-I Wu82bff272014-12-27 14:12:52 +0800737 memset(&data, 0, sizeof(data));
738
739 return data;
740}
741
742bool Image::transparent() const
743{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600744 return (create_info_.tiling == VK_LINEAR_TILING &&
Chia-I Wu82bff272014-12-27 14:12:52 +0800745 create_info_.samples == 1 &&
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600746 !(create_info_.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
747 VK_IMAGE_USAGE_DEPTH_STENCIL_BIT)));
Chia-I Wu82bff272014-12-27 14:12:52 +0800748}
749
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600750void ImageView::init(const Device &dev, const VkImageViewCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800751{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600752 DERIVED_OBJECT_INIT(vkCreateImageView, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800753 alloc_memory(dev);
754}
755
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600756void ColorAttachmentView::init(const Device &dev, const VkColorAttachmentViewCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800757{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600758 DERIVED_OBJECT_INIT(vkCreateColorAttachmentView, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800759 alloc_memory(dev);
760}
761
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600762void DepthStencilView::init(const Device &dev, const VkDepthStencilViewCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800763{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600764 DERIVED_OBJECT_INIT(vkCreateDepthStencilView, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800765 alloc_memory(dev);
766}
767
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600768void Shader::init(const Device &dev, const VkShaderCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800769{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600770 DERIVED_OBJECT_INIT(vkCreateShader, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800771}
772
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600773VkResult Shader::init_try(const Device &dev, const VkShaderCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800774{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600775 VkShader sh;
776 VkResult err = vkCreateShader(dev.obj(), &info, &sh);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600777 if (err == VK_SUCCESS)
Chia-I Wu82bff272014-12-27 14:12:52 +0800778 Object::init(sh);
779
780 return err;
781}
782
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600783void Pipeline::init(const Device &dev, const VkGraphicsPipelineCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800784{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600785 DERIVED_OBJECT_INIT(vkCreateGraphicsPipeline, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800786 alloc_memory(dev);
787}
788
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -0600789void Pipeline::init(
790 const Device &dev,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600791 const VkGraphicsPipelineCreateInfo &info,
792 const VkPipeline basePipeline)
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -0600793{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600794 DERIVED_OBJECT_INIT(vkCreateGraphicsPipelineDerivative, dev.obj(), &info, basePipeline);
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -0600795 alloc_memory(dev);
796}
797
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600798void Pipeline::init(const Device &dev, const VkComputePipelineCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800799{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600800 DERIVED_OBJECT_INIT(vkCreateComputePipeline, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800801 alloc_memory(dev);
802}
803
804void Pipeline::init(const Device&dev, size_t size, const void *data)
805{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600806 DERIVED_OBJECT_INIT(vkLoadPipeline, dev.obj(), size, data);
Chia-I Wu82bff272014-12-27 14:12:52 +0800807 alloc_memory(dev);
808}
809
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -0600810void Pipeline::init(
811 const Device&dev,
812 size_t size,
813 const void *data,
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600814 const VkPipeline basePipeline)
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -0600815{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600816 DERIVED_OBJECT_INIT(vkLoadPipelineDerivative, dev.obj(), size, data, basePipeline);
Courtney Goeltzenleuchter32876a12015-03-25 15:37:49 -0600817 alloc_memory(dev);
818}
819
Chia-I Wu82bff272014-12-27 14:12:52 +0800820size_t Pipeline::store(size_t size, void *data)
821{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600822 if (!EXPECT(vkStorePipeline(obj(), &size, data) == VK_SUCCESS))
Chia-I Wu82bff272014-12-27 14:12:52 +0800823 size = 0;
824
825 return size;
826}
827
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600828void Sampler::init(const Device &dev, const VkSamplerCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800829{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600830 DERIVED_OBJECT_INIT(vkCreateSampler, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800831 alloc_memory(dev);
832}
833
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600834void DescriptorSetLayout::init(const Device &dev, const VkDescriptorSetLayoutCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800835{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600836 DERIVED_OBJECT_INIT(vkCreateDescriptorSetLayout, dev.obj(), &info);
Chia-I Wuf8385062015-01-04 16:27:24 +0800837 alloc_memory(dev);
Chia-I Wu82bff272014-12-27 14:12:52 +0800838}
839
Chia-I Wu7732cb22015-03-26 15:27:55 +0800840void DescriptorSetLayoutChain::init(const Device &dev, const std::vector<const DescriptorSetLayout *> &layouts)
Chia-I Wu82bff272014-12-27 14:12:52 +0800841{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600842 const std::vector<VkDescriptorSetLayout> layout_objs = make_objects<VkDescriptorSetLayout>(layouts);
Chia-I Wu7732cb22015-03-26 15:27:55 +0800843
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600844 DERIVED_OBJECT_INIT(vkCreateDescriptorSetLayoutChain, dev.obj(), layout_objs.size(), &layout_objs[0]);
Chia-I Wu7732cb22015-03-26 15:27:55 +0800845 alloc_memory(dev);
Chia-I Wu82bff272014-12-27 14:12:52 +0800846}
847
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600848void DescriptorPool::init(const Device &dev, VkDescriptorPoolUsage usage,
849 uint32_t max_sets, const VkDescriptorPoolCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800850{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600851 DERIVED_OBJECT_INIT(vkCreateDescriptorPool, dev.obj(), usage, max_sets, &info);
Chia-I Wuf8385062015-01-04 16:27:24 +0800852 alloc_memory(dev);
Chia-I Wu82bff272014-12-27 14:12:52 +0800853}
854
Chia-I Wudee95612015-03-26 15:23:52 +0800855void DescriptorPool::reset()
Chia-I Wu82bff272014-12-27 14:12:52 +0800856{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600857 EXPECT(vkResetDescriptorPool(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800858}
859
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600860std::vector<DescriptorSet *> DescriptorPool::alloc_sets(VkDescriptorSetUsage usage, const std::vector<const DescriptorSetLayout *> &layouts)
Chia-I Wu82bff272014-12-27 14:12:52 +0800861{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600862 const std::vector<VkDescriptorSetLayout> layout_objs = make_objects<VkDescriptorSetLayout>(layouts);
Chia-I Wuf8385062015-01-04 16:27:24 +0800863
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600864 std::vector<VkDescriptorSet> set_objs;
Chia-I Wuf8385062015-01-04 16:27:24 +0800865 set_objs.resize(layout_objs.size());
866
867 uint32_t set_count;
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600868 VkResult err = vkAllocDescriptorSets(obj(), usage, layout_objs.size(), &layout_objs[0], &set_objs[0], &set_count);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600869 if (err == VK_SUCCESS)
Chia-I Wuf8385062015-01-04 16:27:24 +0800870 EXPECT(set_count == set_objs.size());
871 set_objs.resize(set_count);
872
873 std::vector<DescriptorSet *> sets;
874 sets.reserve(set_count);
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600875 for (std::vector<VkDescriptorSet>::const_iterator it = set_objs.begin(); it != set_objs.end(); it++) {
Chia-I Wuf8385062015-01-04 16:27:24 +0800876 // do descriptor sets need memories bound?
877 sets.push_back(new DescriptorSet(*it));
878 }
879
880 return sets;
881}
882
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600883std::vector<DescriptorSet *> DescriptorPool::alloc_sets(VkDescriptorSetUsage usage, const DescriptorSetLayout &layout, uint32_t count)
Chia-I Wuf8385062015-01-04 16:27:24 +0800884{
885 return alloc_sets(usage, std::vector<const DescriptorSetLayout *>(count, &layout));
886}
887
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600888DescriptorSet *DescriptorPool::alloc_sets(VkDescriptorSetUsage usage, const DescriptorSetLayout &layout)
Chia-I Wuf8385062015-01-04 16:27:24 +0800889{
890 std::vector<DescriptorSet *> set = alloc_sets(usage, layout, 1);
891 return (set.empty()) ? NULL : set[0];
892}
893
Chia-I Wu8d24b3b2015-03-26 13:14:16 +0800894void DescriptorPool::clear_sets(const std::vector<DescriptorSet *> &sets)
Chia-I Wuf8385062015-01-04 16:27:24 +0800895{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600896 const std::vector<VkDescriptorSet> set_objs = make_objects<VkDescriptorSet>(sets);
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600897 vkClearDescriptorSets(obj(), set_objs.size(), &set_objs[0]);
Chia-I Wuf8385062015-01-04 16:27:24 +0800898}
899
Chia-I Wu7732cb22015-03-26 15:27:55 +0800900void DescriptorSet::update(const std::vector<const void *> &update_array)
Chia-I Wuf8385062015-01-04 16:27:24 +0800901{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600902 vkUpdateDescriptors(obj(), update_array.size(), const_cast<const void **>(&update_array[0]));
Chia-I Wu82bff272014-12-27 14:12:52 +0800903}
904
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600905void DynamicVpStateObject::init(const Device &dev, const VkDynamicVpStateCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800906{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600907 DERIVED_OBJECT_INIT(vkCreateDynamicViewportState, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800908 alloc_memory(dev);
909}
910
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600911void DynamicRsStateObject::init(const Device &dev, const VkDynamicRsStateCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800912{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600913 DERIVED_OBJECT_INIT(vkCreateDynamicRasterState, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800914 alloc_memory(dev);
915}
916
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600917void DynamicCbStateObject::init(const Device &dev, const VkDynamicCbStateCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800918{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600919 DERIVED_OBJECT_INIT(vkCreateDynamicColorBlendState, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800920 alloc_memory(dev);
921}
922
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600923void DynamicDsStateObject::init(const Device &dev, const VkDynamicDsStateCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800924{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600925 DERIVED_OBJECT_INIT(vkCreateDynamicDepthStencilState, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800926 alloc_memory(dev);
927}
928
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600929void CmdBuffer::init(const Device &dev, const VkCmdBufferCreateInfo &info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800930{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600931 DERIVED_OBJECT_INIT(vkCreateCommandBuffer, dev.obj(), &info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800932}
933
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600934void CmdBuffer::begin(const VkCmdBufferBeginInfo *info)
Chia-I Wu82bff272014-12-27 14:12:52 +0800935{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600936 EXPECT(vkBeginCommandBuffer(obj(), info) == VK_SUCCESS);
Jeremy Hayese0c3b222015-01-14 16:17:08 -0700937}
938
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600939void CmdBuffer::begin(VkRenderPass renderpass_obj, VkFramebuffer framebuffer_obj)
Jeremy Hayese0c3b222015-01-14 16:17:08 -0700940{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600941 VkCmdBufferBeginInfo info = {};
942 VkCmdBufferGraphicsBeginInfo graphics_cmd_buf_info = {};
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600943 graphics_cmd_buf_info.sType = VK_STRUCTURE_TYPE_CMD_BUFFER_GRAPHICS_BEGIN_INFO;
Tony Barbour901f3bc2015-04-01 17:10:07 -0600944 graphics_cmd_buf_info.pNext = NULL;
Courtney Goeltzenleuchtere3b0f3a2015-04-03 15:25:24 -0600945 graphics_cmd_buf_info.renderPassContinue.renderPass = renderpass_obj;
946 graphics_cmd_buf_info.renderPassContinue.framebuffer = framebuffer_obj;
Tony Barbour901f3bc2015-04-01 17:10:07 -0600947
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600948 info.flags = VK_CMD_BUFFER_OPTIMIZE_GPU_SMALL_BATCH_BIT |
949 VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT;
950 info.sType = VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO;
Jeremy Hayese0c3b222015-01-14 16:17:08 -0700951 info.pNext = &graphics_cmd_buf_info;
952
953 begin(&info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800954}
955
956void CmdBuffer::begin()
957{
Courtney Goeltzenleuchter382489d2015-04-10 08:34:15 -0600958 VkCmdBufferBeginInfo info = {};
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600959 info.flags = VK_CMD_BUFFER_OPTIMIZE_GPU_SMALL_BATCH_BIT |
960 VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT;
961 info.sType = VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO;
Jeremy Hayese0c3b222015-01-14 16:17:08 -0700962
963 begin(&info);
Chia-I Wu82bff272014-12-27 14:12:52 +0800964}
965
966void CmdBuffer::end()
967{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600968 EXPECT(vkEndCommandBuffer(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800969}
970
971void CmdBuffer::reset()
972{
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600973 EXPECT(vkResetCommandBuffer(obj()) == VK_SUCCESS);
Chia-I Wu82bff272014-12-27 14:12:52 +0800974}
975
Courtney Goeltzenleuchter9cc421e2015-04-08 15:36:08 -0600976}; // namespace vk_testing