static void cleanup_vulkan() { vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator); for (int i = 0; i < IMGUI_VK_QUEUED_FRAMES; i++) { vkDestroyFence(g_Device, g_Fence[i], g_Allocator); vkFreeCommandBuffers(g_Device, g_CommandPool[i], 1, &g_CommandBuffer[i]); vkDestroyCommandPool(g_Device, g_CommandPool[i], g_Allocator); vkDestroySemaphore(g_Device, g_PresentCompleteSemaphore[i], g_Allocator); vkDestroySemaphore(g_Device, g_RenderCompleteSemaphore[i], g_Allocator); } for (uint32_t i = 0; i < g_BackBufferCount; i++) { vkDestroyImageView(g_Device, g_BackBufferView[i], g_Allocator); vkDestroyFramebuffer(g_Device, g_Framebuffer[i], g_Allocator); } vkDestroyRenderPass(g_Device, g_RenderPass, g_Allocator); vkDestroySwapchainKHR(g_Device, g_Swapchain, g_Allocator); vkDestroySurfaceKHR(g_Instance, g_Surface, g_Allocator); #ifdef IMGUI_VULKAN_DEBUG_REPORT // get the proc address of the function pointer, required for used extensions auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); vkDestroyDebugReportCallbackEXT(g_Instance, g_Debug_Report, g_Allocator); #endif // IMGUI_VULKAN_DEBUG_REPORT vkDestroyDevice(g_Device, g_Allocator); vkDestroyInstance(g_Instance, g_Allocator); }
void VulkanTexturedQuad::ShutdownImpl() { vkDestroyPipeline(device_, pipeline_, nullptr); vkDestroyPipelineLayout(device_, pipelineLayout_, nullptr); vkDestroyBuffer(device_, vertexBuffer_, nullptr); vkDestroyBuffer(device_, indexBuffer_, nullptr); vkFreeMemory(device_, deviceBufferMemory_, nullptr); vkDestroyImageView (device_, rubyImageView_, nullptr); vkDestroyImage (device_, rubyImage_, nullptr); vkFreeMemory (device_, deviceImageMemory_, nullptr); vkDestroyBuffer (device_, uploadImageBuffer_, nullptr); vkFreeMemory (device_, uploadImageMemory_, nullptr); vkDestroyBuffer (device_, uploadBufferBuffer_, nullptr); vkFreeMemory (device_, uploadBufferMemory_, nullptr); vkDestroyDescriptorSetLayout (device_, descriptorSetLayout_, nullptr); vkDestroyDescriptorPool (device_, descriptorPool_, nullptr); vkDestroySampler (device_, sampler_, nullptr); vkDestroyShaderModule(device_, vertexShader_, nullptr); vkDestroyShaderModule(device_, fragmentShader_, nullptr); VulkanSample::ShutdownImpl(); }
void CommandBufferManager::DestroyCommandBuffers() { VkDevice device = g_vulkan_context->GetDevice(); for (FrameResources& resources : m_frame_resources) { // The Vulkan spec section 5.2 says: "When a pool is destroyed, all command buffers allocated // from the pool are freed.". So we don't need to free the command buffers, just the pools. // We destroy the command pool first, to avoid any warnings from the validation layers about // objects which are pending destruction being in-use. if (resources.command_pool != VK_NULL_HANDLE) vkDestroyCommandPool(device, resources.command_pool, nullptr); // Destroy any pending objects. for (auto& it : resources.cleanup_resources) it(); if (resources.semaphore != VK_NULL_HANDLE) vkDestroySemaphore(device, resources.semaphore, nullptr); if (resources.fence != VK_NULL_HANDLE) vkDestroyFence(device, resources.fence, nullptr); if (resources.descriptor_pool != VK_NULL_HANDLE) vkDestroyDescriptorPool(device, resources.descriptor_pool, nullptr); } vkDestroySemaphore(device, m_present_semaphore, nullptr); }
void Application::deInitGraphicsDescriptor() { //vkFreeDescriptorSets(renderer.getVkDevice(), descriptorPool, 1, &descriptorSet); vkDestroyDescriptorPool(renderer.getVkDevice(), graphicsDescriptorPool, nullptr); vkDestroyDescriptorSetLayout(renderer.getVkDevice(), graphicsDescriptorSetLayout, nullptr); }
void CommandBufferManager::DestroyCommandBuffers() { VkDevice device = g_vulkan_context->GetDevice(); for (FrameResources& resources : m_frame_resources) { for (auto& it : resources.cleanup_resources) it(); resources.cleanup_resources.clear(); if (resources.fence != VK_NULL_HANDLE) { vkDestroyFence(device, resources.fence, nullptr); resources.fence = VK_NULL_HANDLE; } if (resources.descriptor_pool != VK_NULL_HANDLE) { vkDestroyDescriptorPool(device, resources.descriptor_pool, nullptr); resources.descriptor_pool = VK_NULL_HANDLE; } if (resources.command_buffers[0] != VK_NULL_HANDLE) { vkFreeCommandBuffers(device, resources.command_pool, static_cast<u32>(resources.command_buffers.size()), resources.command_buffers.data()); resources.command_buffers.fill(VK_NULL_HANDLE); } if (resources.command_pool != VK_NULL_HANDLE) { vkDestroyCommandPool(device, resources.command_pool, nullptr); resources.command_pool = VK_NULL_HANDLE; } } }
/** * Destroy the graphics pipeline. */ VkcPipeline::~VkcPipeline() { if (logicalDevice != VK_NULL_HANDLE) { if (descriptorSet != VK_NULL_HANDLE) vkFreeDescriptorSets(logicalDevice, descriptorPool, 1, &descriptorSet); if (setLayout != VK_NULL_HANDLE) vkDestroyDescriptorSetLayout(logicalDevice, setLayout, nullptr); if (descriptorPool != VK_NULL_HANDLE) vkDestroyDescriptorPool(logicalDevice, descriptorPool, nullptr); if (vertShader != VK_NULL_HANDLE) vkDestroyShaderModule(logicalDevice, vertShader, nullptr); if (fragShader != VK_NULL_HANDLE) vkDestroyShaderModule(logicalDevice, fragShader, nullptr); if (layout != VK_NULL_HANDLE) vkDestroyPipelineLayout(logicalDevice, layout, nullptr); if (handle != VK_NULL_HANDLE) vkDestroyPipeline(logicalDevice, handle, nullptr); } }
void VKDevice::destroy_desc_pool (VkDescriptorPool pool) { XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_dev_id)); XCAM_ASSERT (XCAM_IS_VALID_VK_ID (pool)); vkDestroyDescriptorPool (_dev_id, pool, _allocator.ptr ()); }
/* Please see header for specification */ void Anvil::DescriptorPool::bake() { VkDescriptorPoolCreateInfo descriptor_pool_create_info; VkDescriptorPoolSize descriptor_pool_sizes[VK_DESCRIPTOR_TYPE_RANGE_SIZE]; uint32_t n_descriptor_types_used = 0; VkResult result_vk; if (m_pool != VK_NULL_HANDLE) { vkDestroyDescriptorPool(m_device_ptr->get_device_vk(), m_pool, nullptr /* pAllocator */); m_pool = VK_NULL_HANDLE; } /* Convert the counters to an arrayed, linear representation */ for (uint32_t n_descriptor_type = 0; n_descriptor_type < VK_DESCRIPTOR_TYPE_RANGE_SIZE; ++n_descriptor_type) { if (m_descriptor_count[n_descriptor_type] > 0) { uint32_t current_index = n_descriptor_types_used; descriptor_pool_sizes[current_index].descriptorCount = m_descriptor_count[n_descriptor_type]; descriptor_pool_sizes[current_index].type = (VkDescriptorType) n_descriptor_type; n_descriptor_types_used++; } } if (n_descriptor_types_used == 0) { /* If an empty pool is needed, request space for a single dummy descriptor. */ descriptor_pool_sizes[0].descriptorCount = 1; descriptor_pool_sizes[0].type = VK_DESCRIPTOR_TYPE_SAMPLER; n_descriptor_types_used = 1; } /* Set up the descriptor pool instance */ descriptor_pool_create_info.flags = (m_releaseable_sets) ? VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT : 0; descriptor_pool_create_info.maxSets = m_n_max_sets; descriptor_pool_create_info.pNext = nullptr; descriptor_pool_create_info.poolSizeCount = n_descriptor_types_used; descriptor_pool_create_info.pPoolSizes = descriptor_pool_sizes; descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; result_vk = vkCreateDescriptorPool(m_device_ptr->get_device_vk(), &descriptor_pool_create_info, nullptr, /* pAllocator */ &m_pool); anvil_assert_vk_call_succeeded(result_vk); m_baked = true; }
void VulkanUniformBuffer::FinalizeDescriptorPool() { if ( mVkDescriptorPool != VK_NULL_HANDLE ) { vkDestroyDescriptorPool ( mVulkanRenderer.GetDevice(), mVkDescriptorPool, nullptr ); mVkDescriptorPool = VK_NULL_HANDLE; } }
VulkanExampleBase::~VulkanExampleBase() { // Clean up Vulkan resources swapChain.cleanup(); if (descriptorPool != VK_NULL_HANDLE) { vkDestroyDescriptorPool(device, descriptorPool, nullptr); } if (setupCmdBuffer != VK_NULL_HANDLE) { vkFreeCommandBuffers(device, cmdPool, 1, &setupCmdBuffer); } destroyCommandBuffers(); vkDestroyRenderPass(device, renderPass, nullptr); for (uint32_t i = 0; i < frameBuffers.size(); i++) { vkDestroyFramebuffer(device, frameBuffers[i], nullptr); } for (auto& shaderModule : shaderModules) { vkDestroyShaderModule(device, shaderModule, nullptr); } vkDestroyImageView(device, depthStencil.view, nullptr); vkDestroyImage(device, depthStencil.image, nullptr); vkFreeMemory(device, depthStencil.mem, nullptr); vkDestroyPipelineCache(device, pipelineCache, nullptr); if (textureLoader) { delete textureLoader; } vkDestroyCommandPool(device, cmdPool, nullptr); vkDestroySemaphore(device, semaphores.presentComplete, nullptr); vkDestroySemaphore(device, semaphores.renderComplete, nullptr); vkDestroyDevice(device, nullptr); if (enableValidation) { vkDebug::freeDebugCallback(instance); } vkDestroyInstance(instance, nullptr); #if defined(__linux) #if defined(__ANDROID__) // todo : android cleanup (if required) #else xcb_destroy_window(connection, window); xcb_disconnect(connection); #endif #endif }
void DescriptorSetAllocator::destroy() { if(m_globalDPool) { vkDestroyDescriptorPool(m_dev, m_globalDPool, nullptr); m_globalDPool = VK_NULL_HANDLE; } m_layoutFactory.destroy(); }
void DescriptorSetAllocator::clear() { set_nodes.clear(); for (auto &pool : pools) { vkResetDescriptorPool(device->get_device(), pool, 0); vkDestroyDescriptorPool(device->get_device(), pool, nullptr); } pools.clear(); }
//------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ bool RendererVk::terminateGraphics() { if(!m_bValid) return true; // destroy the super-sampling pass system m_nvFBOBox.Finish(); // destroys commandBuffers: but not really needed since m_cmdPool later gets destroyed nvk.vkDestroyFence(m_sceneFence[0]); m_sceneFence[0] = NULL; nvk.vkDestroyFence(m_sceneFence[1]); m_sceneFence[1] = NULL; nvk.vkFreeCommandBuffer(m_cmdPool, m_cmdScene[0]); m_cmdScene[0] = NULL; nvk.vkFreeCommandBuffer(m_cmdPool, m_cmdScene[1]); m_cmdScene[1] = NULL; nvk.vkDestroyCommandPool(m_cmdPool); // destroys commands that are inside, obviously for(int i=0; i<DSET_TOTALAMOUNT; i++) { vkDestroyDescriptorSetLayout(nvk.m_device, m_descriptorSetLayouts[i], NULL); // general layout and objects layout m_descriptorSetLayouts[i] = 0; } //vkFreeDescriptorSets(nvk.m_device, m_descPool, 1, &m_descriptorSetGlobal); // no really necessary: we will destroy the pool after that m_descriptorSetGlobal = NULL; vkDestroyDescriptorPool(nvk.m_device, m_descPool, NULL); m_descPool = NULL; vkDestroyPipelineLayout(nvk.m_device, m_pipelineLayout, NULL); m_pipelineLayout = NULL; vkDestroyPipeline(nvk.m_device, m_pipelinefur, NULL); m_pipelinefur = NULL; m_furBuffer.release(); m_matrix.release(); deinitTimers(); nvk.vkDestroySemaphore(m_semOpenGLReadDone); nvk.vkDestroySemaphore(m_semVKRenderingDone); m_semOpenGLReadDone = NULL; m_semVKRenderingDone = NULL; //glGetVkInstanceProcAddrNV = NULL; glWaitVkSemaphoreNV = NULL; glSignalVkSemaphoreNV = NULL; glSignalVkFenceNV = NULL; glDrawVkImageNV = NULL; nvk.DestroyDevice(); m_bValid = false; return false; }
static void CleanupVulkan() { ImGui_ImplVulkanH_WindowData* wd = &g_WindowData; ImGui_ImplVulkanH_DestroyWindowData(g_Instance, g_Device, wd, g_Allocator); vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator); #ifdef IMGUI_VULKAN_DEBUG_REPORT // Remove the debug report callback auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator); #endif // IMGUI_VULKAN_DEBUG_REPORT vkDestroyDevice(g_Device, g_Allocator); vkDestroyInstance(g_Instance, g_Allocator); }
/* Please see header for specification */ Anvil::DescriptorPool::~DescriptorPool() { if (m_pool != VK_NULL_HANDLE) { vkDestroyDescriptorPool(m_device_ptr->get_device_vk(), m_pool, nullptr /* pAllocator */); m_pool = VK_NULL_HANDLE; } /* Unregister the instance */ Anvil::ObjectTracker::get()->unregister_object(Anvil::ObjectTracker::OBJECT_TYPE_DESCRIPTOR_POOL, this); }
/** * Default destructor, frees up all Vulkan resources acquired by the text overlay */ ~VulkanTextOverlay() { // Free up all Vulkan resources requested by the text overlay vertexBuffer.destroy(); vkDestroySampler(vulkanDevice->logicalDevice, sampler, nullptr); vkDestroyImage(vulkanDevice->logicalDevice, image, nullptr); vkDestroyImageView(vulkanDevice->logicalDevice, view, nullptr); vkFreeMemory(vulkanDevice->logicalDevice, imageMemory, nullptr); vkDestroyDescriptorSetLayout(vulkanDevice->logicalDevice, descriptorSetLayout, nullptr); vkDestroyDescriptorPool(vulkanDevice->logicalDevice, descriptorPool, nullptr); vkDestroyPipelineLayout(vulkanDevice->logicalDevice, pipelineLayout, nullptr); vkDestroyPipelineCache(vulkanDevice->logicalDevice, pipelineCache, nullptr); vkDestroyPipeline(vulkanDevice->logicalDevice, pipeline, nullptr); vkDestroyRenderPass(vulkanDevice->logicalDevice, renderPass, nullptr); vkFreeCommandBuffers(vulkanDevice->logicalDevice, commandPool, static_cast<uint32_t>(cmdBuffers.size()), cmdBuffers.data()); vkDestroyCommandPool(vulkanDevice->logicalDevice, commandPool, nullptr); vkDestroyFence(vulkanDevice->logicalDevice, fence, nullptr); }
void WMaterial::_DestroyResources() { VkDevice device = m_app->GetVulkanDevice(); W_SAFE_REMOVEREF(m_effect); for (int i = 0; i < m_uniformBuffers.size(); i++) { vkFreeMemory(device, m_uniformBuffers[i].memory, nullptr); vkDestroyBuffer(device, m_uniformBuffers[i].descriptor.buffer, nullptr); } m_uniformBuffers.clear(); for (int i = 0; i < m_sampler_info.size(); i++) { if (m_sampler_info[i].img) m_sampler_info[i].img->RemoveReference(); } m_sampler_info.clear(); if (m_descriptorPool) vkDestroyDescriptorPool(device, m_descriptorPool, nullptr); m_descriptorSet = VK_NULL_HANDLE; m_descriptorPool = VK_NULL_HANDLE; }
VulkanBase::~VulkanBase() { swapChain.cleanup(); vkDestroyDescriptorPool(device, descriptorPool, nullptr); if (setupCmdBuffer != VK_NULL_HANDLE) vkFreeCommandBuffers(device, cmdPool, 1, &setupCmdBuffer); destroyCommandBuffers(); vkDestroyRenderPass(device, renderPass, nullptr); for (uint32_t i = 0; i < frameBuffers.size(); i++) vkDestroyFramebuffer(device, frameBuffers[i], nullptr); for (auto& shaderModule : shaderModules) vkDestroyShaderModule(device, shaderModule, nullptr); vkDestroyImageView(device, depthStencil.view, nullptr); vkDestroyImage(device, depthStencil.image, nullptr); vkFreeMemory(device, depthStencil.mem, nullptr); vkDestroyPipelineCache(device, pipelineCache, nullptr); if (textureLoader) delete textureLoader; vkDestroyCommandPool(device, cmdPool, nullptr); vkDestroySemaphore(device, semaphores.presentComplete, nullptr); vkDestroySemaphore(device, semaphores.renderComplete, nullptr); vkDestroyDevice(device, nullptr); if (enableValidation) vkDebug::freeDebugCallback(instance); vkDestroyInstance(instance, nullptr); }
int sample_main(int argc, char *argv[]) { VkResult U_ASSERT_ONLY res; struct sample_info info = {}; char sample_title[] = "Multiple Descriptor Sets"; process_command_line_args(info, argc, argv); init_global_layer_properties(info); init_instance_extension_names(info); init_device_extension_names(info); init_instance(info, sample_title); init_enumerate_device(info); init_window_size(info, 500, 500); init_connection(info); init_window(info); init_swapchain_extension(info); init_device(info); init_command_pool(info); init_command_buffer(info); execute_begin_command_buffer(info); init_device_queue(info); init_swap_chain(info); init_depth_buffer(info); // Sample from a green texture to easily see that we've pulled correct texel // value const char *textureName = "green.ppm"; init_texture(info, textureName); init_uniform_buffer(info); init_renderpass(info, true); init_shaders(info, vertShaderText, fragShaderText); init_framebuffers(info, true); init_vertex_buffer(info, g_vb_texture_Data, sizeof(g_vb_texture_Data), sizeof(g_vb_texture_Data[0]), true); /* VULKAN_KEY_START */ // Set up two descriptor sets static const unsigned descriptor_set_count = 2; // Create first layout to contain uniform buffer data VkDescriptorSetLayoutBinding uniform_binding[1] = {}; uniform_binding[0].binding = 0; uniform_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; uniform_binding[0].descriptorCount = 1; uniform_binding[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; uniform_binding[0].pImmutableSamplers = NULL; VkDescriptorSetLayoutCreateInfo uniform_layout_info[1] = {}; uniform_layout_info[0].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; uniform_layout_info[0].pNext = NULL; uniform_layout_info[0].bindingCount = 1; uniform_layout_info[0].pBindings = uniform_binding; // Create second layout containing combined sampler/image data VkDescriptorSetLayoutBinding sampler2D_binding[1] = {}; sampler2D_binding[0].binding = 0; sampler2D_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; sampler2D_binding[0].descriptorCount = 1; sampler2D_binding[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; sampler2D_binding[0].pImmutableSamplers = NULL; VkDescriptorSetLayoutCreateInfo sampler2D_layout_info[1] = {}; sampler2D_layout_info[0].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; sampler2D_layout_info[0].pNext = NULL; sampler2D_layout_info[0].bindingCount = 1; sampler2D_layout_info[0].pBindings = sampler2D_binding; // Create multiple sets, using each createInfo static const unsigned uniform_set_index = 0; static const unsigned sampler_set_index = 1; VkDescriptorSetLayout descriptor_layouts[descriptor_set_count] = {}; res = vkCreateDescriptorSetLayout(info.device, uniform_layout_info, NULL, &descriptor_layouts[uniform_set_index]); assert(res == VK_SUCCESS); res = vkCreateDescriptorSetLayout(info.device, sampler2D_layout_info, NULL, &descriptor_layouts[sampler_set_index]); assert(res == VK_SUCCESS); // Create pipeline layout with multiple descriptor sets VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo[1] = {}; pipelineLayoutCreateInfo[0].sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipelineLayoutCreateInfo[0].pNext = NULL; pipelineLayoutCreateInfo[0].pushConstantRangeCount = 0; pipelineLayoutCreateInfo[0].pPushConstantRanges = NULL; pipelineLayoutCreateInfo[0].setLayoutCount = descriptor_set_count; pipelineLayoutCreateInfo[0].pSetLayouts = descriptor_layouts; res = vkCreatePipelineLayout(info.device, pipelineLayoutCreateInfo, NULL, &info.pipeline_layout); assert(res == VK_SUCCESS); // Create a single pool to contain data for our two descriptor sets VkDescriptorPoolSize type_count[2] = {}; type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; type_count[0].descriptorCount = 1; type_count[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; type_count[1].descriptorCount = 1; VkDescriptorPoolCreateInfo pool_info[1] = {}; pool_info[0].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; pool_info[0].pNext = NULL; pool_info[0].maxSets = descriptor_set_count; pool_info[0].poolSizeCount = sizeof(type_count) / sizeof(VkDescriptorPoolSize); pool_info[0].pPoolSizes = type_count; VkDescriptorPool descriptor_pool[1] = {}; res = vkCreateDescriptorPool(info.device, pool_info, NULL, descriptor_pool); assert(res == VK_SUCCESS); VkDescriptorSetAllocateInfo alloc_info[1]; alloc_info[0].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; alloc_info[0].pNext = NULL; alloc_info[0].descriptorPool = descriptor_pool[0]; alloc_info[0].descriptorSetCount = descriptor_set_count; alloc_info[0].pSetLayouts = descriptor_layouts; // Populate descriptor sets VkDescriptorSet descriptor_sets[descriptor_set_count] = {}; res = vkAllocateDescriptorSets(info.device, alloc_info, descriptor_sets); assert(res == VK_SUCCESS); // Using empty brace initializer on the next line triggers a bug in older // versions of gcc, so memset instead VkWriteDescriptorSet descriptor_writes[2]; memset(descriptor_writes, 0, sizeof(descriptor_writes)); // Populate with info about our uniform buffer descriptor_writes[0] = {}; descriptor_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptor_writes[0].pNext = NULL; descriptor_writes[0].dstSet = descriptor_sets[uniform_set_index]; descriptor_writes[0].descriptorCount = 1; descriptor_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; descriptor_writes[0].pBufferInfo = &info.uniform_data.buffer_info; // populated by init_uniform_buffer() descriptor_writes[0].dstArrayElement = 0; descriptor_writes[0].dstBinding = 0; // Populate with info about our sampled image descriptor_writes[1] = {}; descriptor_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptor_writes[1].pNext = NULL; descriptor_writes[1].dstSet = descriptor_sets[sampler_set_index]; descriptor_writes[1].descriptorCount = 1; descriptor_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; descriptor_writes[1].pImageInfo = &info.texture_data.image_info; // populated by init_texture() descriptor_writes[1].dstArrayElement = 0; descriptor_writes[1].dstBinding = 0; vkUpdateDescriptorSets(info.device, descriptor_set_count, descriptor_writes, 0, NULL); /* VULKAN_KEY_END */ // Call remaining boilerplate utils init_pipeline_cache(info); init_pipeline(info, true); // The remaining is identical to drawtexturedcube VkClearValue clear_values[2]; clear_values[0].color.float32[0] = 0.2f; clear_values[0].color.float32[1] = 0.2f; clear_values[0].color.float32[2] = 0.2f; clear_values[0].color.float32[3] = 0.2f; clear_values[1].depthStencil.depth = 1.0f; clear_values[1].depthStencil.stencil = 0; VkSemaphore imageAcquiredSemaphore; VkSemaphoreCreateInfo imageAcquiredSemaphoreCreateInfo; imageAcquiredSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; imageAcquiredSemaphoreCreateInfo.pNext = NULL; imageAcquiredSemaphoreCreateInfo.flags = 0; res = vkCreateSemaphore(info.device, &imageAcquiredSemaphoreCreateInfo, NULL, &imageAcquiredSemaphore); assert(res == VK_SUCCESS); // Get the index of the next available swapchain image: res = vkAcquireNextImageKHR(info.device, info.swap_chain, UINT64_MAX, imageAcquiredSemaphore, VK_NULL_HANDLE, &info.current_buffer); // TODO: Deal with the VK_SUBOPTIMAL_KHR and VK_ERROR_OUT_OF_DATE_KHR // return codes assert(res == VK_SUCCESS); VkRenderPassBeginInfo rp_begin; rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; rp_begin.pNext = NULL; rp_begin.renderPass = info.render_pass; rp_begin.framebuffer = info.framebuffers[info.current_buffer]; rp_begin.renderArea.offset.x = 0; rp_begin.renderArea.offset.y = 0; rp_begin.renderArea.extent.width = info.width; rp_begin.renderArea.extent.height = info.height; rp_begin.clearValueCount = 2; rp_begin.pClearValues = clear_values; vkCmdBeginRenderPass(info.cmd, &rp_begin, VK_SUBPASS_CONTENTS_INLINE); vkCmdBindPipeline(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline); vkCmdBindDescriptorSets(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline_layout, 0, descriptor_set_count, descriptor_sets, 0, NULL); const VkDeviceSize offsets[1] = {0}; vkCmdBindVertexBuffers(info.cmd, 0, 1, &info.vertex_buffer.buf, offsets); init_viewports(info); init_scissors(info); vkCmdDraw(info.cmd, 12 * 3, 1, 0, 0); vkCmdEndRenderPass(info.cmd); res = vkEndCommandBuffer(info.cmd); assert(res == VK_SUCCESS); const VkCommandBuffer cmd_bufs[] = {info.cmd}; VkFenceCreateInfo fenceInfo; VkFence drawFence; fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fenceInfo.pNext = NULL; fenceInfo.flags = 0; vkCreateFence(info.device, &fenceInfo, NULL, &drawFence); VkPipelineStageFlags pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkSubmitInfo submit_info[1] = {}; submit_info[0].pNext = NULL; submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submit_info[0].waitSemaphoreCount = 1; submit_info[0].pWaitSemaphores = &imageAcquiredSemaphore; submit_info[0].pWaitDstStageMask = &pipe_stage_flags; submit_info[0].commandBufferCount = 1; submit_info[0].pCommandBuffers = cmd_bufs; submit_info[0].signalSemaphoreCount = 0; submit_info[0].pSignalSemaphores = NULL; /* Queue the command buffer for execution */ res = vkQueueSubmit(info.graphics_queue, 1, submit_info, drawFence); assert(res == VK_SUCCESS); /* Now present the image in the window */ VkPresentInfoKHR present; present.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; present.pNext = NULL; present.swapchainCount = 1; present.pSwapchains = &info.swap_chain; present.pImageIndices = &info.current_buffer; present.pWaitSemaphores = NULL; present.waitSemaphoreCount = 0; present.pResults = NULL; /* Make sure command buffer is finished before presenting */ do { res = vkWaitForFences(info.device, 1, &drawFence, VK_TRUE, FENCE_TIMEOUT); } while (res == VK_TIMEOUT); assert(res == VK_SUCCESS); res = vkQueuePresentKHR(info.present_queue, &present); assert(res == VK_SUCCESS); wait_seconds(1); if (info.save_images) write_ppm(info, "multiple_sets"); vkDestroySemaphore(info.device, imageAcquiredSemaphore, NULL); vkDestroyFence(info.device, drawFence, NULL); destroy_pipeline(info); destroy_pipeline_cache(info); destroy_textures(info); // instead of destroy_descriptor_pool(info); vkDestroyDescriptorPool(info.device, descriptor_pool[0], NULL); destroy_vertex_buffer(info); destroy_framebuffers(info); destroy_shaders(info); destroy_renderpass(info); // instead of destroy_descriptor_and_pipeline_layouts(info); for (int i = 0; i < descriptor_set_count; i++) vkDestroyDescriptorSetLayout(info.device, descriptor_layouts[i], NULL); vkDestroyPipelineLayout(info.device, info.pipeline_layout, NULL); destroy_uniform_buffer(info); destroy_depth_buffer(info); destroy_swap_chain(info); destroy_command_buffer(info); destroy_command_pool(info); destroy_device(info); destroy_window(info); destroy_instance(info); return 0; }
DescriptorPool::~DescriptorPool() { // TODO: Make sure all descriptor sets allocated from pool have been destroyed vkDestroyDescriptorPool(m_Device->GetHandle(), m_Handle, nullptr); }
void VulkanDeleteList::PerformDeletes(VkDevice device) { for (auto &cmdPool : cmdPools_) { vkDestroyCommandPool(device, cmdPool, nullptr); } cmdPools_.clear(); for (auto &descPool : descPools_) { vkDestroyDescriptorPool(device, descPool, nullptr); } descPools_.clear(); for (auto &module : modules_) { vkDestroyShaderModule(device, module, nullptr); } modules_.clear(); for (auto &buf : buffers_) { vkDestroyBuffer(device, buf, nullptr); } buffers_.clear(); for (auto &bufView : bufferViews_) { vkDestroyBufferView(device, bufView, nullptr); } bufferViews_.clear(); for (auto &image : images_) { vkDestroyImage(device, image, nullptr); } images_.clear(); for (auto &imageView : imageViews_) { vkDestroyImageView(device, imageView, nullptr); } imageViews_.clear(); for (auto &mem : deviceMemory_) { vkFreeMemory(device, mem, nullptr); } deviceMemory_.clear(); for (auto &sampler : samplers_) { vkDestroySampler(device, sampler, nullptr); } samplers_.clear(); for (auto &pipeline : pipelines_) { vkDestroyPipeline(device, pipeline, nullptr); } pipelines_.clear(); for (auto &pcache : pipelineCaches_) { vkDestroyPipelineCache(device, pcache, nullptr); } pipelineCaches_.clear(); for (auto &renderPass : renderPasses_) { vkDestroyRenderPass(device, renderPass, nullptr); } renderPasses_.clear(); for (auto &framebuffer : framebuffers_) { vkDestroyFramebuffer(device, framebuffer, nullptr); } framebuffers_.clear(); for (auto &pipeLayout : pipelineLayouts_) { vkDestroyPipelineLayout(device, pipeLayout, nullptr); } pipelineLayouts_.clear(); for (auto &descSetLayout : descSetLayouts_) { vkDestroyDescriptorSetLayout(device, descSetLayout, nullptr); } descSetLayouts_.clear(); for (auto &callback : callbacks_) { callback.func(callback.userdata); } callbacks_.clear(); }
int sample_main(int argc, char *argv[]) { VkResult U_ASSERT_ONLY res; struct sample_info info = {}; char sample_title[] = "Separate Image Sampler"; const bool depthPresent = true; process_command_line_args(info, argc, argv); init_global_layer_properties(info); init_instance_extension_names(info); init_device_extension_names(info); init_instance(info, sample_title); init_enumerate_device(info); init_window_size(info, 500, 500); init_connection(info); init_window(info); init_swapchain_extension(info); init_device(info); init_command_pool(info); init_command_buffer(info); execute_begin_command_buffer(info); init_device_queue(info); init_swap_chain(info); init_depth_buffer(info); init_uniform_buffer(info); init_renderpass(info, depthPresent); init_shaders(info, vertShaderText, fragShaderText); init_framebuffers(info, depthPresent); init_vertex_buffer(info, g_vb_texture_Data, sizeof(g_vb_texture_Data), sizeof(g_vb_texture_Data[0]), true); /* VULKAN_KEY_START */ // Sample from a green texture to easily see that we've pulled correct texel // value // Create our separate image struct texture_object texObj; const char *textureName = "green.ppm"; init_image(info, texObj, textureName); info.textures.push_back(texObj); info.texture_data.image_info.sampler = 0; info.texture_data.image_info.imageView = info.textures[0].view; info.texture_data.image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; // Create our separate sampler VkSampler separateSampler = {}; init_sampler(info, separateSampler); VkDescriptorImageInfo samplerInfo = {}; samplerInfo.sampler = separateSampler; // Set up one descriptor set static const unsigned descriptor_set_count = 1; static const unsigned resource_count = 3; static const unsigned resource_type_count = 3; // Create binding and layout for the following, matching contents of shader // binding 0 = uniform buffer (MVP) // binding 1 = texture2D // binding 2 = sampler VkDescriptorSetLayoutBinding resource_binding[resource_count] = {}; resource_binding[0].binding = 0; resource_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; resource_binding[0].descriptorCount = 1; resource_binding[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; resource_binding[0].pImmutableSamplers = NULL; resource_binding[1].binding = 1; resource_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; resource_binding[1].descriptorCount = 1; resource_binding[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; resource_binding[1].pImmutableSamplers = NULL; resource_binding[2].binding = 2; resource_binding[2].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; resource_binding[2].descriptorCount = 1; resource_binding[2].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; resource_binding[2].pImmutableSamplers = NULL; VkDescriptorSetLayoutCreateInfo resource_layout_info[1] = {}; resource_layout_info[0].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; resource_layout_info[0].pNext = NULL; resource_layout_info[0].bindingCount = resource_count; resource_layout_info[0].pBindings = resource_binding; VkDescriptorSetLayout descriptor_layouts[1] = {}; res = vkCreateDescriptorSetLayout(info.device, resource_layout_info, NULL, &descriptor_layouts[0]); assert(res == VK_SUCCESS); // Create pipeline layout VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo[1] = {}; pipelineLayoutCreateInfo[0].sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipelineLayoutCreateInfo[0].pNext = NULL; pipelineLayoutCreateInfo[0].pushConstantRangeCount = 0; pipelineLayoutCreateInfo[0].pPushConstantRanges = NULL; pipelineLayoutCreateInfo[0].setLayoutCount = descriptor_set_count; pipelineLayoutCreateInfo[0].pSetLayouts = descriptor_layouts; res = vkCreatePipelineLayout(info.device, pipelineLayoutCreateInfo, NULL, &info.pipeline_layout); assert(res == VK_SUCCESS); // Create a single pool to contain data for our descriptor set VkDescriptorPoolSize pool_sizes[resource_type_count] = {}; pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; pool_sizes[0].descriptorCount = 1; pool_sizes[1].type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; pool_sizes[1].descriptorCount = 1; pool_sizes[2].type = VK_DESCRIPTOR_TYPE_SAMPLER; pool_sizes[2].descriptorCount = 1; VkDescriptorPoolCreateInfo pool_info[1] = {}; pool_info[0].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; pool_info[0].pNext = NULL; pool_info[0].maxSets = descriptor_set_count; pool_info[0].poolSizeCount = resource_type_count; pool_info[0].pPoolSizes = pool_sizes; VkDescriptorPool descriptor_pool[1] = {}; res = vkCreateDescriptorPool(info.device, pool_info, NULL, descriptor_pool); assert(res == VK_SUCCESS); VkDescriptorSetAllocateInfo alloc_info[1]; alloc_info[0].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; alloc_info[0].pNext = NULL; alloc_info[0].descriptorPool = descriptor_pool[0]; alloc_info[0].descriptorSetCount = descriptor_set_count; alloc_info[0].pSetLayouts = descriptor_layouts; // Populate descriptor sets VkDescriptorSet descriptor_sets[descriptor_set_count] = {}; res = vkAllocateDescriptorSets(info.device, alloc_info, descriptor_sets); assert(res == VK_SUCCESS); VkWriteDescriptorSet descriptor_writes[resource_count]; // Populate with info about our uniform buffer for MVP descriptor_writes[0] = {}; descriptor_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptor_writes[0].pNext = NULL; descriptor_writes[0].dstSet = descriptor_sets[0]; descriptor_writes[0].descriptorCount = 1; descriptor_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; descriptor_writes[0].pBufferInfo = &info.uniform_data.buffer_info; // populated by init_uniform_buffer() descriptor_writes[0].dstArrayElement = 0; descriptor_writes[0].dstBinding = 0; // Populate with info about our image descriptor_writes[1] = {}; descriptor_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptor_writes[1].pNext = NULL; descriptor_writes[1].dstSet = descriptor_sets[0]; descriptor_writes[1].descriptorCount = 1; descriptor_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; descriptor_writes[1].pImageInfo = &info.texture_data.image_info; // populated by init_texture() descriptor_writes[1].dstArrayElement = 0; descriptor_writes[1].dstBinding = 1; // Populate with info about our sampler descriptor_writes[2] = {}; descriptor_writes[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptor_writes[2].pNext = NULL; descriptor_writes[2].dstSet = descriptor_sets[0]; descriptor_writes[2].descriptorCount = 1; descriptor_writes[2].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; descriptor_writes[2].pImageInfo = &samplerInfo; descriptor_writes[2].dstArrayElement = 0; descriptor_writes[2].dstBinding = 2; vkUpdateDescriptorSets(info.device, resource_count, descriptor_writes, 0, NULL); /* VULKAN_KEY_END */ init_pipeline_cache(info); init_pipeline(info, depthPresent); init_presentable_image(info); VkClearValue clear_values[2]; init_clear_color_and_depth(info, clear_values); VkRenderPassBeginInfo rp_begin; init_render_pass_begin_info(info, rp_begin); rp_begin.clearValueCount = 2; rp_begin.pClearValues = clear_values; vkCmdBeginRenderPass(info.cmd, &rp_begin, VK_SUBPASS_CONTENTS_INLINE); vkCmdBindPipeline(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline); vkCmdBindDescriptorSets(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline_layout, 0, NUM_DESCRIPTOR_SETS, descriptor_sets, 0, NULL); const VkDeviceSize offsets[1] = {0}; vkCmdBindVertexBuffers(info.cmd, 0, 1, &info.vertex_buffer.buf, offsets); init_viewports(info); init_scissors(info); vkCmdDraw(info.cmd, 12 * 3, 1, 0, 0); vkCmdEndRenderPass(info.cmd); res = vkEndCommandBuffer(info.cmd); assert(res == VK_SUCCESS); VkFence drawFence = {}; init_fence(info, drawFence); VkPipelineStageFlags pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkSubmitInfo submit_info = {}; init_submit_info(info, submit_info, pipe_stage_flags); /* Queue the command buffer for execution */ res = vkQueueSubmit(info.graphics_queue, 1, &submit_info, drawFence); assert(res == VK_SUCCESS); /* Now present the image in the window */ VkPresentInfoKHR present = {}; init_present_info(info, present); /* Make sure command buffer is finished before presenting */ do { res = vkWaitForFences(info.device, 1, &drawFence, VK_TRUE, FENCE_TIMEOUT); } while (res == VK_TIMEOUT); assert(res == VK_SUCCESS); res = vkQueuePresentKHR(info.present_queue, &present); assert(res == VK_SUCCESS); wait_seconds(1); if (info.save_images) write_ppm(info, "separate_image_sampler"); vkDestroyFence(info.device, drawFence, NULL); vkDestroySemaphore(info.device, info.imageAcquiredSemaphore, NULL); destroy_pipeline(info); destroy_pipeline_cache(info); vkDestroySampler(info.device, separateSampler, NULL); vkDestroyImageView(info.device, info.textures[0].view, NULL); vkDestroyImage(info.device, info.textures[0].image, NULL); vkFreeMemory(info.device, info.textures[0].mem, NULL); // instead of destroy_descriptor_pool(info); vkDestroyDescriptorPool(info.device, descriptor_pool[0], NULL); destroy_vertex_buffer(info); destroy_framebuffers(info); destroy_shaders(info); destroy_renderpass(info); // instead of destroy_descriptor_and_pipeline_layouts(info); for (int i = 0; i < descriptor_set_count; i++) vkDestroyDescriptorSetLayout(info.device, descriptor_layouts[i], NULL); vkDestroyPipelineLayout(info.device, info.pipeline_layout, NULL); destroy_uniform_buffer(info); destroy_depth_buffer(info); destroy_swap_chain(info); destroy_command_buffer(info); destroy_command_pool(info); destroy_device(info); destroy_window(info); destroy_instance(info); return 0; }
int sample_main(int argc, char *argv[]) { VkResult U_ASSERT_ONLY res; struct sample_info info = {}; char sample_title[] = "Simple Push Constants"; const bool depthPresent = true; process_command_line_args(info, argc, argv); init_global_layer_properties(info); init_instance_extension_names(info); init_device_extension_names(info); init_instance(info, sample_title); init_enumerate_device(info); init_window_size(info, 500, 500); init_connection(info); init_window(info); init_swapchain_extension(info); init_device(info); init_command_pool(info); init_command_buffer(info); execute_begin_command_buffer(info); init_device_queue(info); init_swap_chain(info); init_depth_buffer(info); init_uniform_buffer(info); init_renderpass(info, depthPresent); init_shaders(info, vertShaderText, fragShaderText); init_framebuffers(info, depthPresent); init_vertex_buffer(info, g_vb_texture_Data, sizeof(g_vb_texture_Data), sizeof(g_vb_texture_Data[0]), true); // Set up one descriptor sets static const unsigned descriptor_set_count = 1; static const unsigned resource_count = 1; // Create binding and layout for the following, matching contents of shader // binding 0 = uniform buffer (MVP) VkDescriptorSetLayoutBinding resource_binding[resource_count] = {}; resource_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; resource_binding[0].descriptorCount = 1; resource_binding[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; resource_binding[0].pImmutableSamplers = NULL; VkDescriptorSetLayoutCreateInfo resource_layout_info[1] = {}; resource_layout_info[0].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; resource_layout_info[0].pNext = NULL; resource_layout_info[0].bindingCount = resource_count; resource_layout_info[0].pBindings = resource_binding; VkDescriptorSetLayout descriptor_layouts[1] = {}; res = vkCreateDescriptorSetLayout(info.device, resource_layout_info, NULL, &descriptor_layouts[0]); assert(res == VK_SUCCESS); /* VULKAN_KEY_START */ // Set up our push constant range, which mirrors the declaration of const unsigned push_constant_range_count = 1; VkPushConstantRange push_constant_ranges[push_constant_range_count] = {}; push_constant_ranges[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; push_constant_ranges[0].offset = 0; push_constant_ranges[0].size = 8; // Create pipeline layout, including push constant info. // Create pipeline layout with multiple descriptor sets VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo[1] = {}; pipelineLayoutCreateInfo[0].sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipelineLayoutCreateInfo[0].pNext = NULL; pipelineLayoutCreateInfo[0].pushConstantRangeCount = push_constant_range_count; pipelineLayoutCreateInfo[0].pPushConstantRanges = push_constant_ranges; pipelineLayoutCreateInfo[0].setLayoutCount = descriptor_set_count; pipelineLayoutCreateInfo[0].pSetLayouts = descriptor_layouts; res = vkCreatePipelineLayout(info.device, pipelineLayoutCreateInfo, NULL, &info.pipeline_layout); assert(res == VK_SUCCESS); // Create a single pool to contain data for our descriptor set VkDescriptorPoolSize type_count[2] = {}; type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; type_count[0].descriptorCount = 1; type_count[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; type_count[1].descriptorCount = 1; VkDescriptorPoolCreateInfo pool_info[1] = {}; pool_info[0].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; pool_info[0].pNext = NULL; pool_info[0].maxSets = descriptor_set_count; pool_info[0].poolSizeCount = sizeof(type_count) / sizeof(VkDescriptorPoolSize); pool_info[0].pPoolSizes = type_count; VkDescriptorPool descriptor_pool[1] = {}; res = vkCreateDescriptorPool(info.device, pool_info, NULL, descriptor_pool); assert(res == VK_SUCCESS); VkDescriptorSetAllocateInfo alloc_info[1]; alloc_info[0].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; alloc_info[0].pNext = NULL; alloc_info[0].descriptorPool = descriptor_pool[0]; alloc_info[0].descriptorSetCount = descriptor_set_count; alloc_info[0].pSetLayouts = descriptor_layouts; // Populate descriptor sets VkDescriptorSet descriptor_sets[descriptor_set_count] = {}; res = vkAllocateDescriptorSets(info.device, alloc_info, descriptor_sets); assert(res == VK_SUCCESS); // Using empty brace initializer on the next line triggers a bug in older // versions of gcc, so memset instead VkWriteDescriptorSet descriptor_writes[resource_count]; memset(descriptor_writes, 0, sizeof(descriptor_writes)); // Populate with info about our uniform buffer for MVP descriptor_writes[0] = {}; descriptor_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptor_writes[0].pNext = NULL; descriptor_writes[0].dstSet = descriptor_sets[0]; descriptor_writes[0].descriptorCount = 1; descriptor_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; descriptor_writes[0].pBufferInfo = &info.uniform_data.buffer_info; // populated by init_uniform_buffer() descriptor_writes[0].dstArrayElement = 0; descriptor_writes[0].dstBinding = 0; vkUpdateDescriptorSets(info.device, resource_count, descriptor_writes, 0, NULL); // Create our push constant data, which matches shader expectations unsigned pushConstants[2] = {}; pushConstants[0] = (unsigned)2; pushConstants[1] = (unsigned)0x3F800000; // Ensure we have enough room for push constant data if (sizeof(pushConstants) > info.gpu_props.limits.maxPushConstantsSize) assert(0 && "Too many push constants"); vkCmdPushConstants(info.cmd, info.pipeline_layout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(pushConstants), pushConstants); /* VULKAN_KEY_END */ init_pipeline_cache(info); init_pipeline(info, depthPresent); init_presentable_image(info); VkClearValue clear_values[2]; init_clear_color_and_depth(info, clear_values); VkRenderPassBeginInfo rp_begin; init_render_pass_begin_info(info, rp_begin); rp_begin.clearValueCount = 2; rp_begin.pClearValues = clear_values; vkCmdBeginRenderPass(info.cmd, &rp_begin, VK_SUBPASS_CONTENTS_INLINE); vkCmdBindPipeline(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline); vkCmdBindDescriptorSets(info.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, info.pipeline_layout, 0, NUM_DESCRIPTOR_SETS, descriptor_sets, 0, NULL); const VkDeviceSize offsets[1] = {0}; vkCmdBindVertexBuffers(info.cmd, 0, 1, &info.vertex_buffer.buf, offsets); init_viewports(info); init_scissors(info); vkCmdDraw(info.cmd, 12 * 3, 1, 0, 0); vkCmdEndRenderPass(info.cmd); res = vkEndCommandBuffer(info.cmd); assert(res == VK_SUCCESS); VkFence drawFence = {}; init_fence(info, drawFence); VkPipelineStageFlags pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkSubmitInfo submit_info = {}; init_submit_info(info, submit_info, pipe_stage_flags); /* Queue the command buffer for execution */ res = vkQueueSubmit(info.graphics_queue, 1, &submit_info, drawFence); assert(res == VK_SUCCESS); /* Now present the image in the window */ VkPresentInfoKHR present = {}; init_present_info(info, present); /* Make sure command buffer is finished before presenting */ do { res = vkWaitForFences(info.device, 1, &drawFence, VK_TRUE, FENCE_TIMEOUT); } while (res == VK_TIMEOUT); assert(res == VK_SUCCESS); res = vkQueuePresentKHR(info.present_queue, &present); assert(res == VK_SUCCESS); wait_seconds(1); if (info.save_images) write_ppm(info, "push_constants"); vkDestroyFence(info.device, drawFence, NULL); vkDestroySemaphore(info.device, info.imageAcquiredSemaphore, NULL); destroy_pipeline(info); destroy_pipeline_cache(info); // instead of destroy_descriptor_pool(info); vkDestroyDescriptorPool(info.device, descriptor_pool[0], NULL); destroy_vertex_buffer(info); destroy_framebuffers(info); destroy_shaders(info); destroy_renderpass(info); // instead of destroy_descriptor_and_pipeline_layouts(info); for (int i = 0; i < descriptor_set_count; i++) vkDestroyDescriptorSetLayout(info.device, descriptor_layouts[i], NULL); vkDestroyPipelineLayout(info.device, info.pipeline_layout, NULL); destroy_uniform_buffer(info); destroy_depth_buffer(info); destroy_swap_chain(info); destroy_command_buffer(info); destroy_command_pool(info); destroy_device(info); destroy_window(info); destroy_instance(info); return 0; }
void Renderer::_DeInitDescriptorPool() { vkDestroyDescriptorPool(_device, _descriptor_pool, nullptr); _descriptor_pool = nullptr; }
void BaseImage::ValidateContent(RandomNumberGenerator& rand) { /* dstBuf has following layout: For each of texels to be sampled, [0..valueCount): struct { in uint32_t pixelX; in uint32_t pixelY; out uint32_t pixelColor; } */ const uint32_t valueCount = 128; VkBufferCreateInfo dstBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; dstBufCreateInfo.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; dstBufCreateInfo.size = valueCount * sizeof(uint32_t) * 3; VmaAllocationCreateInfo dstBufAllocCreateInfo = {}; dstBufAllocCreateInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; dstBufAllocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_TO_CPU; VkBuffer dstBuf = nullptr; VmaAllocation dstBufAlloc = nullptr; VmaAllocationInfo dstBufAllocInfo = {}; TEST( vmaCreateBuffer(g_hAllocator, &dstBufCreateInfo, &dstBufAllocCreateInfo, &dstBuf, &dstBufAlloc, &dstBufAllocInfo) == VK_SUCCESS ); // Fill dstBuf input data. { uint32_t* dstBufContent = (uint32_t*)dstBufAllocInfo.pMappedData; for(uint32_t i = 0; i < valueCount; ++i) { const uint32_t x = rand.Generate() % m_CreateInfo.extent.width; const uint32_t y = rand.Generate() % m_CreateInfo.extent.height; dstBufContent[i * 3 ] = x; dstBufContent[i * 3 + 1] = y; dstBufContent[i * 3 + 2] = 0; } } VkSamplerCreateInfo samplerCreateInfo = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; samplerCreateInfo.magFilter = VK_FILTER_NEAREST; samplerCreateInfo.minFilter = VK_FILTER_NEAREST; samplerCreateInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; samplerCreateInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; samplerCreateInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; samplerCreateInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; samplerCreateInfo.unnormalizedCoordinates = VK_TRUE; VkSampler sampler = nullptr; TEST( vkCreateSampler( g_hDevice, &samplerCreateInfo, nullptr, &sampler) == VK_SUCCESS ); VkDescriptorSetLayoutBinding bindings[2] = {}; bindings[0].binding = 0; bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; bindings[0].descriptorCount = 1; bindings[0].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; bindings[0].pImmutableSamplers = &sampler; bindings[1].binding = 1; bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; bindings[1].descriptorCount = 1; bindings[1].stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; VkDescriptorSetLayoutCreateInfo descSetLayoutCreateInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; descSetLayoutCreateInfo.bindingCount = 2; descSetLayoutCreateInfo.pBindings = bindings; VkDescriptorSetLayout descSetLayout = nullptr; TEST( vkCreateDescriptorSetLayout(g_hDevice, &descSetLayoutCreateInfo, nullptr, &descSetLayout) == VK_SUCCESS ); VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; pipelineLayoutCreateInfo.setLayoutCount = 1; pipelineLayoutCreateInfo.pSetLayouts = &descSetLayout; VkPipelineLayout pipelineLayout = nullptr; TEST( vkCreatePipelineLayout(g_hDevice, &pipelineLayoutCreateInfo, nullptr, &pipelineLayout) == VK_SUCCESS ); std::vector<char> shaderCode; LoadShader(shaderCode, "SparseBindingTest.comp.spv"); VkShaderModuleCreateInfo shaderModuleCreateInfo = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; shaderModuleCreateInfo.codeSize = shaderCode.size(); shaderModuleCreateInfo.pCode = (const uint32_t*)shaderCode.data(); VkShaderModule shaderModule = nullptr; TEST( vkCreateShaderModule(g_hDevice, &shaderModuleCreateInfo, nullptr, &shaderModule) == VK_SUCCESS ); VkComputePipelineCreateInfo pipelineCreateInfo = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO }; pipelineCreateInfo.stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; pipelineCreateInfo.stage.stage = VK_SHADER_STAGE_COMPUTE_BIT; pipelineCreateInfo.stage.module = shaderModule; pipelineCreateInfo.stage.pName = "main"; pipelineCreateInfo.layout = pipelineLayout; VkPipeline pipeline = nullptr; TEST( vkCreateComputePipelines(g_hDevice, nullptr, 1, &pipelineCreateInfo, nullptr, &pipeline) == VK_SUCCESS ); VkDescriptorPoolSize poolSizes[2] = {}; poolSizes[0].type = bindings[0].descriptorType; poolSizes[0].descriptorCount = bindings[0].descriptorCount; poolSizes[1].type = bindings[1].descriptorType; poolSizes[1].descriptorCount = bindings[1].descriptorCount; VkDescriptorPoolCreateInfo descPoolCreateInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; descPoolCreateInfo.maxSets = 1; descPoolCreateInfo.poolSizeCount = 2; descPoolCreateInfo.pPoolSizes = poolSizes; VkDescriptorPool descPool = nullptr; TEST( vkCreateDescriptorPool(g_hDevice, &descPoolCreateInfo, nullptr, &descPool) == VK_SUCCESS ); VkDescriptorSetAllocateInfo descSetAllocInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO }; descSetAllocInfo.descriptorPool = descPool; descSetAllocInfo.descriptorSetCount = 1; descSetAllocInfo.pSetLayouts = &descSetLayout; VkDescriptorSet descSet = nullptr; TEST( vkAllocateDescriptorSets(g_hDevice, &descSetAllocInfo, &descSet) == VK_SUCCESS ); VkImageViewCreateInfo imageViewCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO }; imageViewCreateInfo.image = m_Image; imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; imageViewCreateInfo.format = m_CreateInfo.format; imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; imageViewCreateInfo.subresourceRange.layerCount = 1; imageViewCreateInfo.subresourceRange.levelCount = 1; VkImageView imageView = nullptr; TEST( vkCreateImageView(g_hDevice, &imageViewCreateInfo, nullptr, &imageView) == VK_SUCCESS ); VkDescriptorImageInfo descImageInfo = {}; descImageInfo.imageView = imageView; descImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; VkDescriptorBufferInfo descBufferInfo = {}; descBufferInfo.buffer = dstBuf; descBufferInfo.offset = 0; descBufferInfo.range = VK_WHOLE_SIZE; VkWriteDescriptorSet descWrites[2] = {}; descWrites[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descWrites[0].dstSet = descSet; descWrites[0].dstBinding = bindings[0].binding; descWrites[0].dstArrayElement = 0; descWrites[0].descriptorCount = 1; descWrites[0].descriptorType = bindings[0].descriptorType; descWrites[0].pImageInfo = &descImageInfo; descWrites[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descWrites[1].dstSet = descSet; descWrites[1].dstBinding = bindings[1].binding; descWrites[1].dstArrayElement = 0; descWrites[1].descriptorCount = 1; descWrites[1].descriptorType = bindings[1].descriptorType; descWrites[1].pBufferInfo = &descBufferInfo; vkUpdateDescriptorSets(g_hDevice, 2, descWrites, 0, nullptr); BeginSingleTimeCommands(); vkCmdBindPipeline(g_hTemporaryCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); vkCmdBindDescriptorSets(g_hTemporaryCommandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0, 1, &descSet, 0, nullptr); vkCmdDispatch(g_hTemporaryCommandBuffer, valueCount, 1, 1); EndSingleTimeCommands(); // Validate dstBuf output data. { const uint32_t* dstBufContent = (const uint32_t*)dstBufAllocInfo.pMappedData; for(uint32_t i = 0; i < valueCount; ++i) { const uint32_t x = dstBufContent[i * 3 ]; const uint32_t y = dstBufContent[i * 3 + 1]; const uint32_t color = dstBufContent[i * 3 + 2]; const uint8_t a = (uint8_t)(color >> 24); const uint8_t b = (uint8_t)(color >> 16); const uint8_t g = (uint8_t)(color >> 8); const uint8_t r = (uint8_t)color; TEST(r == (uint8_t)x && g == (uint8_t)y && b == 13 && a == 25); } } vkDestroyImageView(g_hDevice, imageView, nullptr); vkDestroyDescriptorPool(g_hDevice, descPool, nullptr); vmaDestroyBuffer(g_hAllocator, dstBuf, dstBufAlloc); vkDestroyPipeline(g_hDevice, pipeline, nullptr); vkDestroyShaderModule(g_hDevice, shaderModule, nullptr); vkDestroyPipelineLayout(g_hDevice, pipelineLayout, nullptr); vkDestroyDescriptorSetLayout(g_hDevice, descSetLayout, nullptr); vkDestroySampler(g_hDevice, sampler, nullptr); }
void Arguments::destroy() { vkFreeDescriptorSets(device, descriptorPool, 1, &descriptorSet); vkDestroyDescriptorPool(device, descriptorPool, nullptr); }
// // Vulkan termination. // void Example::terminate(const vkts::IUpdateThreadContext& updateContext) { if (device.get()) { terminateResources(updateContext); // if (swapchain.get()) { swapchain->destroy(); } if (pipelineLayout.get()) { pipelineLayout->destroy(); } if (pipelineCache.get()) { pipelineCache->destroy(); } if (vertexShaderModule.get()) { vertexShaderModule->destroy(); } if (fragmentShaderModule.get()) { fragmentShaderModule->destroy(); } if (vertexBuffer.get()) { vertexBuffer->destroy(); } if (deviceMemoryVertexBuffer.get()) { deviceMemoryVertexBuffer->destroy(); } if (descriptorSet != VK_NULL_HANDLE) { vkFreeDescriptorSets(device->getDevice(), descriptorPool, 1, &descriptorSet); descriptorSet = VK_NULL_HANDLE; } if (descriptorPool != VK_NULL_HANDLE) { vkDestroyDescriptorPool(device->getDevice(), descriptorPool, nullptr); descriptorPool = VK_NULL_HANDLE; } if (descriptorSetLayout != VK_NULL_HANDLE) { vkDestroyDescriptorSetLayout(device->getDevice(), descriptorSetLayout, nullptr); descriptorSetLayout = VK_NULL_HANDLE; } if (imageView.get()) { imageView->destroy(); } if (sampler.get()) { sampler->destroy(); } destroyTexture(image, deviceMemoryImage); if (renderingCompleteSemaphore.get()) { renderingCompleteSemaphore->destroy(); } if (imageAcquiredSemaphore.get()) { imageAcquiredSemaphore->destroy(); } if (commandPool.get()) { commandPool->destroy(); } if (surface.get()) { surface->destroy(); } device->destroy(); } if (instance.get()) { instance->destroy(); } }