1#define VOLK_IMPLEMENTATION
2
3#include "taichi/rhi/impl_support.h"
4
5#include "taichi/rhi/vulkan/vulkan_api.h"
6#include "taichi/rhi/vulkan/vulkan_loader.h"
7
8namespace vkapi {
9
10DeviceObjVkDescriptorSetLayout::~DeviceObjVkDescriptorSetLayout() {
11 vkDestroyDescriptorSetLayout(device, layout, nullptr);
12}
13
14DeviceObjVkDescriptorPool::~DeviceObjVkDescriptorPool() {
15 vkDestroyDescriptorPool(device, pool, nullptr);
16}
17
18DeviceObjVkDescriptorSet::~DeviceObjVkDescriptorSet() {
19}
20
21DeviceObjVkCommandPool::~DeviceObjVkCommandPool() {
22 vkDestroyCommandPool(device, pool, nullptr);
23}
24
25DeviceObjVkCommandBuffer::~DeviceObjVkCommandBuffer() {
26 if (this->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) {
27 ref_pool->free_primary.push(buffer);
28 } else {
29 ref_pool->free_secondary.push(buffer);
30 }
31}
32
33DeviceObjVkRenderPass::~DeviceObjVkRenderPass() {
34 vkDestroyRenderPass(device, renderpass, nullptr);
35}
36
37DeviceObjVkPipelineLayout::~DeviceObjVkPipelineLayout() {
38 vkDestroyPipelineLayout(device, layout, nullptr);
39}
40
41DeviceObjVkPipeline::~DeviceObjVkPipeline() {
42 vkDestroyPipeline(device, pipeline, nullptr);
43}
44
45DeviceObjVkSampler::~DeviceObjVkSampler() {
46 vkDestroySampler(device, sampler, nullptr);
47}
48
49DeviceObjVkImage::~DeviceObjVkImage() {
50 if (allocation) {
51 vmaDestroyImage(allocator, image, allocation);
52 }
53}
54
55DeviceObjVkImageView::~DeviceObjVkImageView() {
56 vkDestroyImageView(device, view, nullptr);
57}
58
59DeviceObjVkFramebuffer::~DeviceObjVkFramebuffer() {
60 vkDestroyFramebuffer(device, framebuffer, nullptr);
61}
62
63DeviceObjVkSemaphore::~DeviceObjVkSemaphore() {
64 vkDestroySemaphore(device, semaphore, nullptr);
65}
66
67DeviceObjVkFence::~DeviceObjVkFence() {
68 vkDestroyFence(device, fence, nullptr);
69}
70
71DeviceObjVkPipelineCache::~DeviceObjVkPipelineCache() {
72 vkDestroyPipelineCache(device, cache, nullptr);
73}
74
75DeviceObjVkBuffer::~DeviceObjVkBuffer() {
76 if (allocation) {
77 vmaDestroyBuffer(allocator, buffer, allocation);
78 }
79}
80
81DeviceObjVkBufferView::~DeviceObjVkBufferView() {
82 vkDestroyBufferView(device, view, nullptr);
83}
84
85DeviceObjVkAccelerationStructureKHR::~DeviceObjVkAccelerationStructureKHR() {
86 PFN_vkDestroyAccelerationStructureKHR destroy_raytracing_pipeline_khr =
87 PFN_vkDestroyAccelerationStructureKHR(vkGetInstanceProcAddr(
88 taichi::lang::vulkan::VulkanLoader::instance().get_instance(),
89 "vkDestroyAccelerationStructureKHR"));
90
91 destroy_raytracing_pipeline_khr(device, accel, nullptr);
92}
93DeviceObjVkQueryPool::~DeviceObjVkQueryPool() {
94 vkDestroyQueryPool(device, query_pool, nullptr);
95}
96
97IDeviceObj create_device_obj(VkDevice device) {
98 IDeviceObj obj = std::make_shared<DeviceObj>();
99 obj->device = device;
100 return obj;
101}
102
103IVkSemaphore create_semaphore(VkDevice device,
104 VkSemaphoreCreateFlags flags,
105 void *pnext) {
106 IVkSemaphore obj = std::make_shared<DeviceObjVkSemaphore>();
107 obj->device = device;
108
109 VkSemaphoreCreateInfo info{};
110 info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
111 info.pNext = pnext;
112 info.flags = flags;
113
114 VkResult res = vkCreateSemaphore(device, &info, nullptr, &obj->semaphore);
115 BAIL_ON_VK_BAD_RESULT_NO_RETURN(res, "failed to create semaphore");
116 return obj;
117}
118
119IVkFence create_fence(VkDevice device, VkFenceCreateFlags flags, void *pnext) {
120 IVkFence obj = std::make_shared<DeviceObjVkFence>();
121 obj->device = device;
122
123 VkFenceCreateInfo info{};
124 info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
125 info.pNext = pnext;
126 info.flags = flags;
127
128 VkResult res = vkCreateFence(device, &info, nullptr, &obj->fence);
129 BAIL_ON_VK_BAD_RESULT_NO_RETURN(res, "failed to create fence");
130 return obj;
131}
132
133IVkDescriptorSetLayout create_descriptor_set_layout(
134 VkDevice device,
135 VkDescriptorSetLayoutCreateInfo *create_info) {
136 IVkDescriptorSetLayout obj =
137 std::make_shared<DeviceObjVkDescriptorSetLayout>();
138 obj->device = device;
139 VkResult res =
140 vkCreateDescriptorSetLayout(device, create_info, nullptr, &obj->layout);
141 BAIL_ON_VK_BAD_RESULT_NO_RETURN(res,
142 "failed to create descriptor set layout");
143 return obj;
144}
145
146IVkDescriptorPool create_descriptor_pool(
147 VkDevice device,
148 VkDescriptorPoolCreateInfo *create_info) {
149 IVkDescriptorPool obj = std::make_shared<DeviceObjVkDescriptorPool>();
150 obj->device = device;
151 VkResult res =
152 vkCreateDescriptorPool(device, create_info, nullptr, &obj->pool);
153 if (res != VK_SUCCESS) {
154 // All failure condition listed in spec are OOM
155 return nullptr;
156 }
157 return obj;
158}
159
160IVkDescriptorSet allocate_descriptor_sets(IVkDescriptorPool pool,
161 IVkDescriptorSetLayout layout,
162 void *pnext) {
163 IVkDescriptorSet obj = std::make_shared<DeviceObjVkDescriptorSet>();
164 obj->device = pool->device;
165 obj->ref_layout = layout;
166 obj->ref_pool = pool;
167
168 VkDescriptorSetAllocateInfo info{};
169 info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
170 info.pNext = pnext;
171 info.descriptorPool = pool->pool;
172 info.descriptorSetCount = 1;
173 info.pSetLayouts = &layout->layout;
174
175 if (vkAllocateDescriptorSets(pool->device, &info, &obj->set) ==
176 VK_ERROR_OUT_OF_POOL_MEMORY) {
177 return nullptr;
178 }
179
180 return obj;
181}
182
183IVkCommandPool create_command_pool(VkDevice device,
184 VkCommandPoolCreateFlags flags,
185 uint32_t queue_family_index) {
186 IVkCommandPool obj = std::make_shared<DeviceObjVkCommandPool>();
187 obj->device = device;
188 obj->queue_family_index = queue_family_index;
189
190 VkCommandPoolCreateInfo info{};
191 info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
192 info.pNext = nullptr;
193 info.flags = flags;
194 info.queueFamilyIndex = queue_family_index;
195
196 VkResult res = vkCreateCommandPool(device, &info, nullptr, &obj->pool);
197 BAIL_ON_VK_BAD_RESULT_NO_RETURN(res, "failed to create command pool");
198
199 return obj;
200}
201
202IVkCommandBuffer allocate_command_buffer(IVkCommandPool pool,
203 VkCommandBufferLevel level) {
204 VkCommandBuffer cmdbuf{VK_NULL_HANDLE};
205
206 if (level == VK_COMMAND_BUFFER_LEVEL_PRIMARY && pool->free_primary.size()) {
207 cmdbuf = pool->free_primary.top();
208 pool->free_primary.pop();
209 } else if (level == VK_COMMAND_BUFFER_LEVEL_SECONDARY &&
210 pool->free_secondary.size()) {
211 cmdbuf = pool->free_secondary.top();
212 pool->free_secondary.pop();
213 } else {
214 VkCommandBufferAllocateInfo info{};
215 info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
216 info.pNext = nullptr;
217 info.commandPool = pool->pool;
218 info.level = level;
219 info.commandBufferCount = 1;
220
221 VkResult res = vkAllocateCommandBuffers(pool->device, &info, &cmdbuf);
222 if (res != VK_SUCCESS) {
223 return nullptr;
224 }
225 }
226
227 IVkCommandBuffer obj = std::make_shared<DeviceObjVkCommandBuffer>();
228 obj->device = pool->device;
229 obj->level = level;
230 obj->ref_pool = pool;
231 obj->buffer = cmdbuf;
232
233 return obj;
234}
235
236IVkRenderPass create_render_pass(VkDevice device,
237 VkRenderPassCreateInfo *create_info) {
238 IVkRenderPass obj = std::make_shared<DeviceObjVkRenderPass>();
239 obj->device = device;
240 VkResult res =
241 vkCreateRenderPass(device, create_info, nullptr, &obj->renderpass);
242 BAIL_ON_VK_BAD_RESULT_NO_RETURN(res, "failed to create render pass");
243 return obj;
244}
245
246IVkPipelineLayout create_pipeline_layout(
247 VkDevice device,
248 std::vector<IVkDescriptorSetLayout> &set_layouts,
249 uint32_t push_constant_range_count,
250 VkPushConstantRange *push_constant_ranges) {
251 IVkPipelineLayout obj = std::make_shared<DeviceObjVkPipelineLayout>();
252 obj->device = device;
253 obj->ref_desc_layouts = set_layouts;
254
255 std::vector<VkDescriptorSetLayout> layouts;
256 layouts.reserve(set_layouts.size());
257 for (auto &l : set_layouts) {
258 layouts.push_back(l->layout);
259 }
260
261 VkPipelineLayoutCreateInfo info{};
262 info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
263 info.pNext = nullptr;
264 info.setLayoutCount = uint32_t(layouts.size());
265 info.pSetLayouts = layouts.data();
266 info.pushConstantRangeCount = push_constant_range_count;
267 info.pPushConstantRanges = push_constant_ranges;
268
269 VkResult res = vkCreatePipelineLayout(device, &info, nullptr, &obj->layout);
270 BAIL_ON_VK_BAD_RESULT_NO_RETURN(res, "failed to create pipeline layout");
271
272 return obj;
273}
274
275IVkPipelineCache create_pipeline_cache(VkDevice device,
276 VkPipelineCacheCreateFlags flags,
277 size_t initial_size,
278 const void *initial_data) {
279 IVkPipelineCache obj = std::make_shared<DeviceObjVkPipelineCache>();
280 obj->device = device;
281
282 VkPipelineCacheCreateInfo info{};
283 info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
284 info.pNext = nullptr;
285 info.flags = flags;
286 info.initialDataSize = initial_size;
287 info.pInitialData = initial_data;
288
289 VkResult res = vkCreatePipelineCache(device, &info, nullptr, &obj->cache);
290 BAIL_ON_VK_BAD_RESULT_NO_RETURN(res, "failed to create pipeline cache");
291
292 return obj;
293}
294
295IVkPipeline create_compute_pipeline(VkDevice device,
296 VkPipelineCreateFlags flags,
297 VkPipelineShaderStageCreateInfo &stage,
298 IVkPipelineLayout layout,
299 IVkPipelineCache cache,
300 IVkPipeline base_pipeline) {
301 IVkPipeline obj = std::make_shared<DeviceObjVkPipeline>();
302 obj->device = device;
303 obj->ref_layout = layout;
304 obj->ref_cache = cache;
305
306 VkComputePipelineCreateInfo info{};
307 info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
308 info.pNext = nullptr;
309 info.flags = flags;
310 info.stage = stage;
311 info.layout = layout->layout;
312 if (base_pipeline) {
313 info.basePipelineHandle = base_pipeline->pipeline;
314 info.basePipelineIndex = -1;
315 } else {
316 info.basePipelineHandle = VK_NULL_HANDLE;
317 info.basePipelineIndex = 0;
318 }
319
320 VkResult res =
321 vkCreateComputePipelines(device, cache ? cache->cache : VK_NULL_HANDLE, 1,
322 &info, nullptr, &obj->pipeline);
323 RHI_THROW_UNLESS(res == VK_SUCCESS,
324 std::runtime_error("vkCreateComputePipelines failed"));
325
326 return obj;
327}
328
329IVkPipeline create_graphics_pipeline(VkDevice device,
330 VkGraphicsPipelineCreateInfo *create_info,
331 IVkRenderPass renderpass,
332 IVkPipelineLayout layout,
333 IVkPipelineCache cache,
334 IVkPipeline base_pipeline) {
335 IVkPipeline obj = std::make_shared<DeviceObjVkPipeline>();
336 obj->device = device;
337 obj->ref_layout = layout;
338 obj->ref_cache = cache;
339 obj->ref_renderpass = renderpass;
340
341 create_info->renderPass = renderpass->renderpass;
342 create_info->layout = layout->layout;
343
344 if (base_pipeline) {
345 create_info->basePipelineHandle = base_pipeline->pipeline;
346 create_info->basePipelineIndex = -1;
347 } else {
348 create_info->basePipelineHandle = VK_NULL_HANDLE;
349 create_info->basePipelineIndex = 0;
350 }
351
352 VkResult res =
353 vkCreateGraphicsPipelines(device, cache ? cache->cache : VK_NULL_HANDLE,
354 1, create_info, nullptr, &obj->pipeline);
355 BAIL_ON_VK_BAD_RESULT_NO_RETURN(res, "failed to create graphics pipeline");
356
357 return obj;
358}
359
360IVkPipeline create_graphics_pipeline_dynamic(
361 VkDevice device,
362 VkGraphicsPipelineCreateInfo *create_info,
363 VkPipelineRenderingCreateInfoKHR *rendering_info,
364 IVkPipelineLayout layout,
365 IVkPipelineCache cache,
366 IVkPipeline base_pipeline) {
367 IVkPipeline obj = std::make_shared<DeviceObjVkPipeline>();
368 obj->device = device;
369 obj->ref_layout = layout;
370 obj->ref_cache = cache;
371 obj->ref_renderpass = nullptr;
372
373 create_info->pNext = rendering_info;
374 create_info->layout = layout->layout;
375
376 if (base_pipeline) {
377 create_info->basePipelineHandle = base_pipeline->pipeline;
378 create_info->basePipelineIndex = -1;
379 } else {
380 create_info->basePipelineHandle = VK_NULL_HANDLE;
381 create_info->basePipelineIndex = 0;
382 }
383
384 VkResult res =
385 vkCreateGraphicsPipelines(device, cache ? cache->cache : VK_NULL_HANDLE,
386 1, create_info, nullptr, &obj->pipeline);
387 BAIL_ON_VK_BAD_RESULT_NO_RETURN(res, "failed to create graphics pipeline");
388
389 return obj;
390}
391
392IVkPipeline create_raytracing_pipeline(
393 VkDevice device,
394 VkRayTracingPipelineCreateInfoKHR *create_info,
395 IVkPipelineLayout layout,
396 std::vector<IVkPipeline> &pipeline_libraries,
397 VkDeferredOperationKHR deferredOperation,
398 IVkPipelineCache cache,
399 IVkPipeline base_pipeline) {
400 IVkPipeline obj = std::make_shared<DeviceObjVkPipeline>();
401 obj->device = device;
402 obj->ref_layout = layout;
403 obj->ref_cache = cache;
404 obj->ref_pipeline_libraries = pipeline_libraries;
405
406 create_info->layout = layout->layout;
407
408 if (base_pipeline) {
409 create_info->basePipelineHandle = base_pipeline->pipeline;
410 create_info->basePipelineIndex = -1;
411 } else {
412 create_info->basePipelineHandle = VK_NULL_HANDLE;
413 create_info->basePipelineIndex = 0;
414 }
415
416 PFN_vkCreateRayTracingPipelinesKHR create_raytracing_pipeline_khr =
417 PFN_vkCreateRayTracingPipelinesKHR(vkGetInstanceProcAddr(
418 taichi::lang::vulkan::VulkanLoader::instance().get_instance(),
419 "vkCreateRayTracingPipelinesKHR"));
420
421 VkResult res = create_raytracing_pipeline_khr(
422 device, deferredOperation, cache ? cache->cache : VK_NULL_HANDLE, 1,
423 create_info, nullptr, &obj->pipeline);
424 BAIL_ON_VK_BAD_RESULT_NO_RETURN(res, "failed to create raytracing pipeline");
425
426 return obj;
427}
428
429IVkSampler create_sampler(VkDevice device, const VkSamplerCreateInfo &info) {
430 IVkSampler sampler = std::make_shared<DeviceObjVkSampler>();
431 sampler->device = device;
432
433 BAIL_ON_VK_BAD_RESULT_NO_RETURN(
434 vkCreateSampler(device, &info, nullptr, &sampler->sampler),
435 "failed to create texture sampler!");
436
437 return sampler;
438}
439
440IVkImage create_image(VkDevice device,
441 VmaAllocator allocator,
442 VkImageCreateInfo *image_info,
443 VmaAllocationCreateInfo *alloc_info) {
444 IVkImage image = std::make_shared<DeviceObjVkImage>();
445 image->device = device;
446 image->allocator = allocator;
447 image->format = image_info->format;
448 image->type = image_info->imageType;
449 image->width = image_info->extent.width;
450 image->height = image_info->extent.height;
451 image->depth = image_info->extent.depth;
452 image->mip_levels = image_info->mipLevels;
453 image->array_layers = image_info->arrayLayers;
454 image->usage = image_info->usage;
455
456 VkResult res = vmaCreateImage(allocator, image_info, alloc_info,
457 &image->image, &image->allocation, nullptr);
458 BAIL_ON_VK_BAD_RESULT_NO_RETURN(res, "failed to create image");
459
460 return image;
461}
462
463IVkImage create_image(VkDevice device,
464 VkImage image,
465 VkFormat format,
466 VkImageType type,
467 VkExtent3D extent,
468 uint32_t mip_levels,
469 uint32_t array_layers,
470 VkImageUsageFlags usage) {
471 IVkImage obj = std::make_shared<DeviceObjVkImage>();
472 obj->device = device;
473 obj->image = image;
474 obj->format = format;
475 obj->type = type;
476 obj->width = extent.width;
477 obj->height = extent.height;
478 obj->depth = extent.depth;
479 obj->mip_levels = mip_levels;
480 obj->array_layers = array_layers;
481 obj->usage = usage;
482
483 return obj;
484}
485
486IVkImageView create_image_view(VkDevice device,
487 IVkImage image,
488 VkImageViewCreateInfo *create_info) {
489 IVkImageView view = std::make_shared<DeviceObjVkImageView>();
490 view->device = device;
491 view->ref_image = image;
492 view->subresource_range = create_info->subresourceRange;
493 view->type = create_info->viewType;
494
495 create_info->image = image->image;
496
497 VkResult res = vkCreateImageView(device, create_info, nullptr, &view->view);
498 BAIL_ON_VK_BAD_RESULT_NO_RETURN(res, "failed to create image view");
499
500 return view;
501}
502
503IVkFramebuffer create_framebuffer(VkFramebufferCreateFlags flags,
504 IVkRenderPass renderpass,
505 const std::vector<IVkImageView> &attachments,
506 uint32_t width,
507 uint32_t height,
508 uint32_t layers,
509 void *pnext) {
510 IVkFramebuffer obj = std::make_shared<DeviceObjVkFramebuffer>();
511 obj->device = renderpass->device;
512 obj->ref_attachments = attachments;
513 obj->ref_renderpass = renderpass;
514
515 std::vector<VkImageView> views(attachments.size());
516 for (int i = 0; i < attachments.size(); i++) {
517 views[i] = attachments[i]->view;
518 }
519
520 VkFramebufferCreateInfo info{};
521 info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
522 info.pNext = pnext;
523 info.flags = flags;
524 info.renderPass = renderpass->renderpass;
525 info.attachmentCount = uint32_t(attachments.size());
526 info.pAttachments = views.data();
527 info.width = width;
528 info.height = height;
529 info.layers = layers;
530
531 VkResult res = vkCreateFramebuffer(renderpass->device, &info, nullptr,
532 &obj->framebuffer);
533 BAIL_ON_VK_BAD_RESULT_NO_RETURN(res, "failed to create framebuffer");
534
535 return obj;
536}
537
538IVkBuffer create_buffer(VkDevice device,
539 VmaAllocator allocator,
540 VkBufferCreateInfo *buffer_info,
541 VmaAllocationCreateInfo *alloc_info) {
542 IVkBuffer buffer = std::make_shared<DeviceObjVkBuffer>();
543 buffer->device = device;
544 buffer->allocator = allocator;
545 buffer->usage = buffer_info->usage;
546
547 VkResult res = vmaCreateBuffer(allocator, buffer_info, alloc_info,
548 &buffer->buffer, &buffer->allocation, nullptr);
549 if (res == VK_ERROR_OUT_OF_DEVICE_MEMORY) {
550 throw std::bad_alloc();
551 } // FIXME: (damnkk) Should be removed when RHI error codes are ready
552 BAIL_ON_VK_BAD_RESULT_NO_RETURN(res, "failed to create buffer");
553
554 return buffer;
555}
556
557IVkBuffer create_buffer(VkDevice device,
558 VkBuffer buffer,
559 VkBufferUsageFlags usage) {
560 IVkBuffer obj = std::make_shared<DeviceObjVkBuffer>();
561 obj->device = device;
562 obj->buffer = buffer;
563 obj->usage = usage;
564
565 return obj;
566}
567
568IVkBufferView create_buffer_view(IVkBuffer buffer,
569 VkBufferViewCreateFlags flags,
570 VkFormat format,
571 VkDeviceSize offset,
572 VkDeviceSize range) {
573 IVkBufferView view = std::make_shared<DeviceObjVkBufferView>();
574 view->device = buffer->device;
575 view->ref_buffer = buffer;
576 view->format = format;
577 view->offset = offset;
578 view->range = range;
579
580 VkBufferViewCreateInfo info{};
581 info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
582 info.pNext = nullptr;
583 info.flags = flags;
584 info.buffer = buffer->buffer;
585 info.format = format;
586 info.offset = offset;
587 info.range = range;
588
589 VkResult res =
590 vkCreateBufferView(buffer->device, &info, nullptr, &view->view);
591 BAIL_ON_VK_BAD_RESULT_NO_RETURN(res, "failed to create buffer view");
592
593 return view;
594}
595
596IVkAccelerationStructureKHR create_acceleration_structure(
597 VkAccelerationStructureCreateFlagsKHR flags,
598 IVkBuffer buffer,
599 VkDeviceSize offset,
600 VkDeviceSize size,
601 VkAccelerationStructureTypeKHR type) {
602 IVkAccelerationStructureKHR obj =
603 std::make_shared<DeviceObjVkAccelerationStructureKHR>();
604 obj->device = buffer->device;
605 obj->ref_buffer = buffer;
606 obj->offset = offset;
607 obj->size = size;
608 obj->type = type;
609
610 VkAccelerationStructureCreateInfoKHR info{};
611 info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR;
612 info.pNext = nullptr;
613 info.createFlags = flags;
614 info.buffer = buffer->buffer;
615 info.offset = offset;
616 info.size = size;
617 info.type = type;
618 info.deviceAddress = 0;
619
620 PFN_vkCreateAccelerationStructureKHR create_acceleration_structure_khr =
621 PFN_vkCreateAccelerationStructureKHR(vkGetInstanceProcAddr(
622 taichi::lang::vulkan::VulkanLoader::instance().get_instance(),
623 "vkCreateAccelerationStructureKHR"));
624
625 VkResult res = create_acceleration_structure_khr(buffer->device, &info,
626 nullptr, &obj->accel);
627 BAIL_ON_VK_BAD_RESULT_NO_RETURN(res,
628 "failed to create acceleration structure");
629
630 return obj;
631}
632
633IVkQueryPool create_query_pool(VkDevice device) {
634 VkQueryPoolCreateInfo info{};
635 info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
636 info.pNext = nullptr;
637 info.queryCount = 2;
638 info.queryType = VK_QUERY_TYPE_TIMESTAMP;
639
640 VkQueryPool query_pool;
641 VkResult res = vkCreateQueryPool(device, &info, nullptr, &query_pool);
642 BAIL_ON_VK_BAD_RESULT_NO_RETURN(res, "failed to create query pool");
643
644 IVkQueryPool obj = std::make_shared<DeviceObjVkQueryPool>();
645 obj->device = device;
646 obj->query_pool = query_pool;
647
648 return obj;
649}
650
651} // namespace vkapi
652