Windows下vulkan开发流程分析

Windows下vulkan开发流程

blog.csdn.net/a2831942318

1、枚举实例扩展属性:

vkEnumerateInstanceExtensionProperties [0/17]VK_KHR_device_group_creation

vkEnumerateInstanceExtensionProperties [1/17]VK_KHR_display

vkEnumerateInstanceExtensionProperties [2/17]VK_KHR_external_fence_capabilities

vkEnumerateInstanceExtensionProperties [3/17]VK_KHR_external_memory_capabilities

vkEnumerateInstanceExtensionProperties [4/17]VK_KHR_external_semaphore_capabilities

vkEnumerateInstanceExtensionProperties [5/17]VK_KHR_get_display_properties2

vkEnumerateInstanceExtensionProperties [6/17]VK_KHR_get_physical_device_properties2

vkEnumerateInstanceExtensionProperties [7/17]VK_KHR_get_surface_capabilities2

vkEnumerateInstanceExtensionProperties [8/17]VK_KHR_surface

vkEnumerateInstanceExtensionProperties [9/17]VK_KHR_surface_protected_capabilities

vkEnumerateInstanceExtensionProperties [10/17]VK_KHR_win32_surface

vkEnumerateInstanceExtensionProperties [11/17]VK_EXT_debug_report

vkEnumerateInstanceExtensionProperties [12/17]VK_EXT_debug_utils

vkEnumerateInstanceExtensionProperties [13/17]VK_EXT_direct_mode_display

vkEnumerateInstanceExtensionProperties [14/17]VK_EXT_swapchain_colorspace

vkEnumerateInstanceExtensionProperties [15/17]VK_NV_external_memory_capabilities

vkEnumerateInstanceExtensionProperties [16/17]VK_KHR_portability_enumeration

2、通过实例信息结构VkInstanceCreateInfo创建一个实例

err = vkCreateInstance(&inst_info, NULL, &demo->inst);

失败日志ICD:

Cannot find a compatible Vulkan installable client driver (ICD).

3、枚举物理设备即显卡GPU

(1)、查询GPU数量

err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, NULL);

(2)、获取GPU设备句柄

VkPhysicalDevice *physical_devices = malloc(sizeof(VkPhysicalDevice) * gpu_count);

err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, physical_devices);

遍历获取显卡属性:

vkGetPhysicalDeviceProperties(physical_devices[i], &physicalDeviceProperties);

比如集成显卡与独立显卡:

Intel(R) UHD Graphics

NVIDIA GeForce RTX 3060 Laptop GPU

4、枚举选择的GPU扩展属性

Selected GPU 1: NVIDIA GeForce RTX 3060 Laptop GPU, type: DiscreteGpu

GPU根据接入系统的方式分为集成型GPU(Integrated GPU,iGPU)和离散型GPU(Discrete GPU ,dGPU)两种

typedef enum VkPhysicalDeviceType {

VK_PHYSICAL_DEVICE_TYPE_OTHER = 0,

VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = 1,

VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2,

VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3,

VK_PHYSICAL_DEVICE_TYPE_CPU = 4,

VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM = 0x7FFFFFFF

} VkPhysicalDeviceType;

176个:

err = vkEnumerateDeviceExtensionProperties(demo->gpu, NULL, &device_extension_count, NULL);

vkGetPhysicalDeviceProperties(demo->gpu, &demo->gpu_props);

/* Call with NULL data to get count */

vkGetPhysicalDeviceQueueFamilyProperties(demo->gpu, &demo->queue_family_count, NULL);

assert(demo->queue_family_count >= 1);

demo->queue_props = (VkQueueFamilyProperties *)malloc(demo->queue_family_count * sizeof(VkQueueFamilyProperties));

vkGetPhysicalDeviceQueueFamilyProperties(demo->gpu, &demo->queue_family_count, demo->queue_props);

显卡特性:

VkPhysicalDeviceFeatures physDevFeatures;

vkGetPhysicalDeviceFeatures(demo->gpu, &physDevFeatures);

5、创建Windows窗口

demo_create_window(&demo

6、创建交换链SwapChain

demo_init_vk_swapchain

(1)、err = vkCreateWin32SurfaceKHR(demo->inst, &createInfo, NULL, &demo->surface);

(2)、 // Iterate over each queue to learn whether it supports presenting:

VkBool32 *supportsPresent = (VkBool32 *)malloc(demo->queue_family_count * sizeof(VkBool32));

for (uint32_t i = 0; i < demo->queue_family_count; i++) {

demo->fpGetPhysicalDeviceSurfaceSupportKHR(demo->gpu, i, demo->surface, &supportsPresent[i]);

}

(3)、搜索队列

// Search for a graphics and a present queue in the array of queue

// families, try to find one that supports both

uint32_t graphicsQueueFamilyIndex = UINT32_MAX;

uint32_t presentQueueFamilyIndex = UINT32_MAX;

for (uint32_t i = 0; i < demo->queue_family_count; i++) {

if ((demo->queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0) {

if (graphicsQueueFamilyIndex == UINT32_MAX) {

graphicsQueueFamilyIndex = i;

}

if (supportsPresent[i] == VK_TRUE) {

graphicsQueueFamilyIndex = i;

presentQueueFamilyIndex = i;

break;

}

}

}

(4)、

err = vkCreateDevice(demo->gpu, &device, NULL, &demo->device);

vkGetDeviceQueue(demo->device, demo->graphics_queue_family_index, 0, &demo->graphics_queue);

err = demo->fpGetPhysicalDeviceSurfaceFormatsKHR(demo->gpu, demo->surface, &formatCount, NULL);

(5)、创建信号量同步显示

// Create semaphores to synchronize acquiring presentable buffers before

// rendering and waiting for drawing to be complete before presenting

VkSemaphoreCreateInfo semaphoreCreateInfo = {

.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,

.pNext = NULL,

.flags = 0,

};

// 创建围栏

err = vkCreateFence(demo->device, &fence_ci, NULL, &demo->fences[i]);

assert(!err);

err = vkCreateSemaphore(demo->device, &semaphoreCreateInfo, NULL, &demo->image_acquired_semaphores[i]);

// Get Memory information and properties

vkGetPhysicalDeviceMemoryProperties(demo->gpu, &demo->memory_properties);

7、渲染前的准备 demo_prepare

err = vkCreateCommandPool(demo->device, &cmd_pool_info, NULL, &demo->cmd_pool);

err = vkAllocateCommandBuffers(demo->device, &cmd, &demo->cmd);

err = vkBeginCommandBuffer(demo->cmd, &cmd_buf_info);

demo_prepare_depth(demo);

demo_prepare_textures(demo);

demo_prepare_cube_data_buffers(demo);

demo_prepare_descriptor_layout(demo);

demo_prepare_render_pass(demo);

demo_prepare_pipeline(demo);

/* create image */

err = vkCreateImage(demo->device, &image, NULL, &demo->depth.image);

/* allocate memory */

err = vkAllocateMemory(demo->device, &demo->depth.mem_alloc, NULL, &demo->depth.mem);

/* bind memory */

err = vkBindImageMemory(demo->device, demo->depth.image, demo->depth.mem, 0);

/* create image view */

view.image = demo->depth.image;

err = vkCreateImageView(demo->device, &view, NULL, &demo->depth.view);

demo_prepare_descriptor_pool(demo);

demo_prepare_descriptor_set(demo);

demo_prepare_framebuffers(demo);

for (uint32_t i = 0; i < demo->swapchainImageCount; i++) {

demo->current_buffer = i;

demo_draw_build_cmd(demo, demo->swapchain_image_resources[i].cmd);

}

err = vkBeginCommandBuffer(cmd_buf, &cmd_buf_info);

vkCmdBeginRenderPass(cmd_buf, &rp_begin, VK_SUBPASS_CONTENTS_INLINE);

viewport.height = viewport_dimension;

viewport.width = viewport_dimension;

viewport.minDepth = (float)0.0f;

viewport.maxDepth = (float)1.0f;

vkCmdSetViewport(cmd_buf, 0, 1, &viewport);

err = vkEndCommandBuffer(cmd_buf);

vulkan都是提前把渲染命令准备好。

8、渲染

case WM_PAINT:

// The validation callback calls MessageBox which can generate paint

// events - don't make more Vulkan calls if we got here from the

// callback

if (!in_callback) {

demo_run(&demo);

}

#if defined(VK_USE_PLATFORM_WIN32_KHR)

static void demo_run(struct demo *demo) {

if (!demo->prepared) return;

demo_draw(demo);

demo->curFrame++;

if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount) {

PostQuitMessage(validation_error);

}

}

// Ensure no more than FRAME_LAG renderings are outstanding

vkWaitForFences(demo->device, 1, &demo->fences[demo->frame_index], VK_TRUE, UINT64_MAX);

vkResetFences(demo->device, 1, &demo->fences[demo->frame_index]);

demo->fpAcquireNextImageKHR(demo->device, demo->swapchain, UINT64_MAX,

demo->image_acquired_semaphores[demo->frame_index], VK_NULL_HANDLE, &demo->current_buffer);

err = vkQueueSubmit(demo->graphics_queue, 1, &submit_info, demo->fences[demo->frame_index]);

err = demo->fpQueuePresentKHR(demo->present_queue, &present);

9、窗口大小缩放,重新准备

static void demo_resize(struct demo *demo) {

uint32_t i;

// Don't react to resize until after first initialization.

if (!demo->prepared) {

if (demo->is_minimized) {

demo_prepare(demo);

}

return;

}

// In order to properly resize the window, we must re-create the swapchain

// AND redo the command buffers, etc.

//

// First, perform part of the demo_cleanup() function:

demo->prepared = false;

vkDeviceWaitIdle(demo->device);

for (i = 0; i < demo->swapchainImageCount; i++) {

vkDestroyFramebuffer(demo->device, demo->swapchain_image_resources[i].framebuffer, NULL);

}

vkDestroyDescriptorPool(demo->device, demo->desc_pool, NULL);

vkDestroyPipeline(demo->device, demo->pipeline, NULL);

vkDestroyPipelineCache(demo->device, demo->pipelineCache, NULL);

vkDestroyRenderPass(demo->device, demo->render_pass, NULL);

vkDestroyPipelineLayout(demo->device, demo->pipeline_layout, NULL);

vkDestroyDescriptorSetLayout(demo->device, demo->desc_layout, NULL);

for (i = 0; i < DEMO_TEXTURE_COUNT; i++) {

vkDestroyImageView(demo->device, demo->textures[i].view, NULL);

vkDestroyImage(demo->device, demo->textures[i].image, NULL);

vkFreeMemory(demo->device, demo->textures[i].mem, NULL);

vkDestroySampler(demo->device, demo->textures[i].sampler, NULL);

}

vkDestroyImageView(demo->device, demo->depth.view, NULL);

vkDestroyImage(demo->device, demo->depth.image, NULL);

vkFreeMemory(demo->device, demo->depth.mem, NULL);

for (i = 0; i < demo->swapchainImageCount; i++) {

vkDestroyImageView(demo->device, demo->swapchain_image_resources[i].view, NULL);

vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, &demo->swapchain_image_resources[i].cmd);

vkDestroyBuffer(demo->device, demo->swapchain_image_resources[i].uniform_buffer, NULL);

vkUnmapMemory(demo->device, demo->swapchain_image_resources[i].uniform_memory);

vkFreeMemory(demo->device, demo->swapchain_image_resources[i].uniform_memory, NULL);

}

vkDestroyCommandPool(demo->device, demo->cmd_pool, NULL);

demo->cmd_pool = VK_NULL_HANDLE;

if (demo->separate_present_queue) {

vkDestroyCommandPool(demo->device, demo->present_cmd_pool, NULL);

}

free(demo->swapchain_image_resources);

// Second, re-perform the demo_prepare() function, which will re-create the

// swapchain:

demo_prepare(demo);

}

blog.csdn.net/a2831942318

猜你喜欢

转载自blog.csdn.net/a2831942318/article/details/129352885