Add user-defined conversion operators

This commit is contained in:
spnda 2021-09-10 19:01:43 +02:00 committed by Charles Giessen
parent 81f542e119
commit f5f9b54f38
4 changed files with 91 additions and 33 deletions

View File

@ -55,9 +55,9 @@ int device_initialization (Init& init) {
}
init.instance = instance_ret.value ();
init.vk_lib.init(init.instance.instance);
init.vk_lib.init(init.instance);
init.surface = create_surface_glfw (init.instance.instance, init.window);
init.surface = create_surface_glfw (init.instance, init.window);
vkb::PhysicalDeviceSelector phys_device_selector (init.instance);
auto phys_device_ret = phys_device_selector.set_surface (init.surface).select ();
@ -74,7 +74,7 @@ int device_initialization (Init& init) {
return -1;
}
init.device = device_ret.value ();
init.vk_lib.init(init.device.device);
init.vk_lib.init(init.device);
return 0;
}
@ -146,7 +146,7 @@ int create_render_pass (Init& init, RenderData& data) {
render_pass_info.dependencyCount = 1;
render_pass_info.pDependencies = &dependency;
if (init->vkCreateRenderPass (init.device.device, &render_pass_info, nullptr, &data.render_pass) != VK_SUCCESS) {
if (init->vkCreateRenderPass (init.device, &render_pass_info, nullptr, &data.render_pass) != VK_SUCCESS) {
std::cout << "failed to create render pass\n";
return -1; // failed to create render pass!
}
@ -178,7 +178,7 @@ VkShaderModule createShaderModule (Init& init, const std::vector<char>& code) {
create_info.pCode = reinterpret_cast<const uint32_t*> (code.data ());
VkShaderModule shaderModule;
if (init->vkCreateShaderModule (init.device.device, &create_info, nullptr, &shaderModule) != VK_SUCCESS) {
if (init->vkCreateShaderModule (init.device, &create_info, nullptr, &shaderModule) != VK_SUCCESS) {
return VK_NULL_HANDLE; // failed to create shader module
}
@ -276,7 +276,7 @@ int create_graphics_pipeline (Init& init, RenderData& data) {
pipeline_layout_info.pushConstantRangeCount = 0;
if (init->vkCreatePipelineLayout (
init.device.device, &pipeline_layout_info, nullptr, &data.pipeline_layout) != VK_SUCCESS) {
init.device, &pipeline_layout_info, nullptr, &data.pipeline_layout) != VK_SUCCESS) {
std::cout << "failed to create pipeline layout\n";
return -1; // failed to create pipeline layout
}
@ -305,13 +305,13 @@ int create_graphics_pipeline (Init& init, RenderData& data) {
pipeline_info.basePipelineHandle = VK_NULL_HANDLE;
if (init->vkCreateGraphicsPipelines (
init.device.device, VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &data.graphics_pipeline) != VK_SUCCESS) {
init.device, VK_NULL_HANDLE, 1, &pipeline_info, nullptr, &data.graphics_pipeline) != VK_SUCCESS) {
std::cout << "failed to create pipline\n";
return -1; // failed to create graphics pipeline
}
init->vkDestroyShaderModule (init.device.device, frag_module, nullptr);
init->vkDestroyShaderModule (init.device.device, vert_module, nullptr);
init->vkDestroyShaderModule (init.device, frag_module, nullptr);
init->vkDestroyShaderModule (init.device, vert_module, nullptr);
return 0;
}
@ -333,7 +333,7 @@ int create_framebuffers (Init& init, RenderData& data) {
framebuffer_info.height = init.swapchain.extent.height;
framebuffer_info.layers = 1;
if (init->vkCreateFramebuffer (init.device.device, &framebuffer_info, nullptr, &data.framebuffers[i]) != VK_SUCCESS) {
if (init->vkCreateFramebuffer (init.device, &framebuffer_info, nullptr, &data.framebuffers[i]) != VK_SUCCESS) {
return -1; // failed to create framebuffer
}
}
@ -345,7 +345,7 @@ int create_command_pool (Init& init, RenderData& data) {
pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
pool_info.queueFamilyIndex = init.device.get_queue_index (vkb::QueueType::graphics).value ();
if (init->vkCreateCommandPool (init.device.device, &pool_info, nullptr, &data.command_pool) != VK_SUCCESS) {
if (init->vkCreateCommandPool (init.device, &pool_info, nullptr, &data.command_pool) != VK_SUCCESS) {
std::cout << "failed to create command pool\n";
return -1; // failed to create command pool
}
@ -361,7 +361,7 @@ int create_command_buffers (Init& init, RenderData& data) {
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocInfo.commandBufferCount = (uint32_t)data.command_buffers.size ();
if (init->vkAllocateCommandBuffers (init.device.device, &allocInfo, data.command_buffers.data ()) != VK_SUCCESS) {
if (init->vkAllocateCommandBuffers (init.device, &allocInfo, data.command_buffers.data ()) != VK_SUCCESS) {
return -1; // failed to allocate command buffers;
}
@ -428,9 +428,9 @@ int create_sync_objects (Init& init, RenderData& data) {
fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
if (init->vkCreateSemaphore (init.device.device, &semaphore_info, nullptr, &data.available_semaphores[i]) != VK_SUCCESS ||
init->vkCreateSemaphore (init.device.device, &semaphore_info, nullptr, &data.finished_semaphore[i]) != VK_SUCCESS ||
init->vkCreateFence (init.device.device, &fence_info, nullptr, &data.in_flight_fences[i]) != VK_SUCCESS) {
if (init->vkCreateSemaphore (init.device, &semaphore_info, nullptr, &data.available_semaphores[i]) != VK_SUCCESS ||
init->vkCreateSemaphore (init.device, &semaphore_info, nullptr, &data.finished_semaphore[i]) != VK_SUCCESS ||
init->vkCreateFence (init.device, &fence_info, nullptr, &data.in_flight_fences[i]) != VK_SUCCESS) {
std::cout << "failed to create sync objects\n";
return -1; // failed to create synchronization objects for a frame
}
@ -439,12 +439,12 @@ int create_sync_objects (Init& init, RenderData& data) {
}
int recreate_swapchain (Init& init, RenderData& data) {
init->vkDeviceWaitIdle (init.device.device);
init->vkDeviceWaitIdle (init.device);
init->vkDestroyCommandPool (init.device.device, data.command_pool, nullptr);
init->vkDestroyCommandPool (init.device, data.command_pool, nullptr);
for (auto framebuffer : data.framebuffers) {
init->vkDestroyFramebuffer (init.device.device, framebuffer, nullptr);
init->vkDestroyFramebuffer (init.device, framebuffer, nullptr);
}
init.swapchain.destroy_image_views (data.swapchain_image_views);
@ -457,11 +457,11 @@ int recreate_swapchain (Init& init, RenderData& data) {
}
int draw_frame (Init& init, RenderData& data) {
init->vkWaitForFences (init.device.device, 1, &data.in_flight_fences[data.current_frame], VK_TRUE, UINT64_MAX);
init->vkWaitForFences (init.device, 1, &data.in_flight_fences[data.current_frame], VK_TRUE, UINT64_MAX);
uint32_t image_index = 0;
VkResult result = init->vkAcquireNextImageKHR (init.device.device,
init.swapchain.swapchain,
VkResult result = init->vkAcquireNextImageKHR (init.device,
init.swapchain,
UINT64_MAX,
data.available_semaphores[data.current_frame],
VK_NULL_HANDLE,
@ -475,7 +475,7 @@ int draw_frame (Init& init, RenderData& data) {
}
if (data.image_in_flight[image_index] != VK_NULL_HANDLE) {
init->vkWaitForFences (init.device.device, 1, &data.image_in_flight[image_index], VK_TRUE, UINT64_MAX);
init->vkWaitForFences (init.device, 1, &data.image_in_flight[image_index], VK_TRUE, UINT64_MAX);
}
data.image_in_flight[image_index] = data.in_flight_fences[data.current_frame];
@ -495,7 +495,7 @@ int draw_frame (Init& init, RenderData& data) {
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signal_semaphores;
init->vkResetFences (init.device.device, 1, &data.in_flight_fences[data.current_frame]);
init->vkResetFences (init.device, 1, &data.in_flight_fences[data.current_frame]);
if (init->vkQueueSubmit (data.graphics_queue, 1, &submitInfo, data.in_flight_fences[data.current_frame]) != VK_SUCCESS) {
std::cout << "failed to submit draw command buffer\n";
@ -508,7 +508,7 @@ int draw_frame (Init& init, RenderData& data) {
present_info.waitSemaphoreCount = 1;
present_info.pWaitSemaphores = signal_semaphores;
VkSwapchainKHR swapChains[] = { init.swapchain.swapchain };
VkSwapchainKHR swapChains[] = { init.swapchain };
present_info.swapchainCount = 1;
present_info.pSwapchains = swapChains;
@ -528,20 +528,20 @@ int draw_frame (Init& init, RenderData& data) {
void cleanup (Init& init, RenderData& data) {
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
init->vkDestroySemaphore (init.device.device, data.finished_semaphore[i], nullptr);
init->vkDestroySemaphore (init.device.device, data.available_semaphores[i], nullptr);
init->vkDestroyFence (init.device.device, data.in_flight_fences[i], nullptr);
init->vkDestroySemaphore (init.device, data.finished_semaphore[i], nullptr);
init->vkDestroySemaphore (init.device, data.available_semaphores[i], nullptr);
init->vkDestroyFence (init.device, data.in_flight_fences[i], nullptr);
}
init->vkDestroyCommandPool (init.device.device, data.command_pool, nullptr);
init->vkDestroyCommandPool (init.device, data.command_pool, nullptr);
for (auto framebuffer : data.framebuffers) {
init->vkDestroyFramebuffer (init.device.device, framebuffer, nullptr);
init->vkDestroyFramebuffer (init.device, framebuffer, nullptr);
}
init->vkDestroyPipeline (init.device.device, data.graphics_pipeline, nullptr);
init->vkDestroyPipelineLayout (init.device.device, data.pipeline_layout, nullptr);
init->vkDestroyRenderPass (init.device.device, data.render_pass, nullptr);
init->vkDestroyPipeline (init.device, data.graphics_pipeline, nullptr);
init->vkDestroyPipelineLayout (init.device, data.pipeline_layout, nullptr);
init->vkDestroyRenderPass (init.device, data.render_pass, nullptr);
init.swapchain.destroy_image_views (data.swapchain_image_views);
@ -574,7 +574,7 @@ int main () {
return -1;
}
}
init->vkDeviceWaitIdle (init.device.device);
init->vkDeviceWaitIdle (init.device);
cleanup (init, render_data);
return 0;

View File

@ -550,6 +550,10 @@ void destroy_instance(Instance instance) {
}
}
Instance::operator VkInstance() const {
return this->instance;
}
InstanceBuilder::InstanceBuilder(PFN_vkGetInstanceProcAddr fp_vkGetInstanceProcAddr) {
info.fp_vkGetInstanceProcAddr = fp_vkGetInstanceProcAddr;
}
@ -1329,6 +1333,10 @@ std::vector<VkQueueFamilyProperties> PhysicalDevice::get_queue_families() const
return queue_families;
}
PhysicalDevice::operator VkPhysicalDevice() const {
return this->physical_device;
}
// ---- Queues ---- //
detail::Result<uint32_t> Device::get_queue_index(QueueType type) const {
@ -1399,6 +1407,10 @@ DispatchTable Device::make_table() const { return { device, fp_vkGetDeviceProcAd
// ---- Device ---- //
Device::operator VkDevice() const {
return this->device;
}
CustomQueueDescription::CustomQueueDescription(uint32_t index, uint32_t count, std::vector<float> priorities)
: index(index), count(count), priorities(priorities) {
assert(count == priorities.size());
@ -1826,6 +1838,9 @@ void Swapchain::destroy_image_views(std::vector<VkImageView> const& image_views)
internal_table.fp_vkDestroyImageView(device, image_view, allocation_callbacks);
}
}
Swapchain::operator VkSwapchainKHR() const {
return this->swapchain;
}
SwapchainBuilder& SwapchainBuilder::set_old_swapchain(VkSwapchainKHR old_swapchain) {
info.old_swapchain = old_swapchain;
return *this;

View File

@ -236,6 +236,10 @@ struct Instance {
PFN_vkGetInstanceProcAddr fp_vkGetInstanceProcAddr = nullptr;
PFN_vkGetDeviceProcAddr fp_vkGetDeviceProcAddr = nullptr;
// A conversion function which allows this Instance to be used
// in places where VkInstance would have been used.
operator VkInstance() const;
private:
bool headless = false;
bool supports_properties2_ext = false;
@ -412,6 +416,10 @@ struct PhysicalDevice {
// Advanced: Get the VkQueueFamilyProperties of the device if special queue setup is needed
std::vector<VkQueueFamilyProperties> get_queue_families() const;
// A conversion function which allows this PhysicalDevice to be used
// in places where VkPhysicalDevice would have been used.
operator VkPhysicalDevice() const;
private:
uint32_t instance_version = VK_MAKE_VERSION(1, 0, 0);
std::vector<const char*> extensions_to_enable;
@ -596,6 +604,10 @@ struct Device {
// Return a loaded dispatch table
DispatchTable make_table() const;
// A conversion function which allows this Device to be used
// in places where VkDevice would have been used.
operator VkDevice() const;
private:
struct {
PFN_vkGetDeviceQueue fp_vkGetDeviceQueue = nullptr;
@ -663,6 +675,10 @@ struct Swapchain {
detail::Result<std::vector<VkImageView>> get_image_views();
void destroy_image_views(std::vector<VkImageView> const& image_views);
// A conversion function which allows this Swapchain to be used
// in places where VkSwapchainKHR would have been used.
operator VkSwapchainKHR() const;
private:
struct {
PFN_vkGetSwapchainImagesKHR fp_vkGetSwapchainImagesKHR = nullptr;

View File

@ -491,6 +491,33 @@ TEST_CASE("Querying Required Extension Features", "[VkBootstrap.select_features]
}
}
TEST_CASE("Passing vkb classes to Vulkan handles", "[VkBootstrap.pass_class_to_handle") {
GIVEN("A working instance") {
auto instance = get_instance();
// Check if we can get instance functions.
PFN_vkVoidFunction instanceFunction = instance.fp_vkGetInstanceProcAddr(instance, "vkSetDebugUtilsObjectNameEXT"); // validation layers should be provided.
REQUIRE(instanceFunction != NULL);
auto window = create_window_glfw("Conversion operators");
auto surface = create_surface_glfw(instance, window);
vkb::PhysicalDeviceSelector physicalDeviceSelector(instance);
auto physicalDevice = physicalDeviceSelector
.add_required_extension(VK_KHR_SWAPCHAIN_EXTENSION_NAME)
.set_surface(surface)
.select();
REQUIRE(physicalDevice.has_value());
vkb::DeviceBuilder deviceBuilder(physicalDevice.value());
auto device = deviceBuilder.build();
REQUIRE(device.has_value());
// Check if we can get a device function address, passing vkb::Device to the function.
PFN_vkVoidFunction deviceFunction = instance.fp_vkGetDeviceProcAddr(device.value(), "vkAcquireNextImageKHR");
REQUIRE(deviceFunction != NULL);
}
}
#if defined(VK_API_VERSION_1_1)
TEST_CASE("Querying Required Extension Features in 1.1", "[VkBootstrap.version]") {
GIVEN("A working instance") {