vulkan oit: fix imgui overlay

re-init imgui with the oit render pass when running game. use regular
render pass otherwise.
This commit is contained in:
Flyinghead 2019-11-26 18:28:48 +01:00
parent ed538f7dce
commit dae0908735
6 changed files with 38 additions and 19 deletions

View File

@ -41,6 +41,7 @@ static VkQueue g_Queue = VK_NULL_HANDLE;
static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE;
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
static VkRenderPass g_RenderPass = VK_NULL_HANDLE;
static int g_RenderSubpass = 0;
static void (*g_CheckVkResultFn)(VkResult err) = NULL;
static VkDeviceSize g_BufferMemoryAlignment = 256;
@ -527,6 +528,7 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
}
// Create Descriptor Set:
if (!g_DescriptorSet)
{
VkDescriptorSetAllocateInfo alloc_info = {};
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
@ -555,6 +557,13 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
check_vk_result(err);
}
if (g_Pipeline)
{
// Avoid destroying the in-flight pipeline
vkDeviceWaitIdle(g_Device);
vkDestroyPipeline(g_Device, g_Pipeline, g_Allocator);
g_Pipeline = VK_NULL_HANDLE;
}
VkPipelineShaderStageCreateInfo stage[2] = {};
stage[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
stage[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
@ -649,6 +658,7 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
info.pDynamicState = &dynamic_state;
info.layout = g_PipelineLayout;
info.renderPass = g_RenderPass;
info.subpass = g_RenderSubpass;
err = vkCreateGraphicsPipelines(g_Device, g_PipelineCache, 1, &info, g_Allocator, &g_Pipeline);
check_vk_result(err);
@ -694,8 +704,12 @@ void ImGui_ImplVulkan_InvalidateDeviceObjects()
if (g_Pipeline) { vkDestroyPipeline(g_Device, g_Pipeline, g_Allocator); g_Pipeline = VK_NULL_HANDLE; }
}
bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass)
bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass, int subpass)
{
IM_ASSERT(render_pass != VK_NULL_HANDLE);
if (g_RenderPass == render_pass && g_RenderSubpass == subpass)
return true;
ImGuiIO& io = ImGui::GetIO();
io.BackendRendererName = "imgui_impl_vulkan";
@ -704,7 +718,6 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
IM_ASSERT(info->Device != VK_NULL_HANDLE);
IM_ASSERT(info->Queue != VK_NULL_HANDLE);
IM_ASSERT(info->DescriptorPool != VK_NULL_HANDLE);
IM_ASSERT(render_pass != VK_NULL_HANDLE);
g_Instance = info->Instance;
g_PhysicalDevice = info->PhysicalDevice;
@ -712,6 +725,7 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass rend
g_QueueFamily = info->QueueFamily;
g_Queue = info->Queue;
g_RenderPass = render_pass;
g_RenderSubpass = subpass;
g_PipelineCache = info->PipelineCache;
g_DescriptorPool = info->DescriptorPool;
g_Allocator = info->Allocator;

View File

@ -32,7 +32,7 @@ struct ImGui_ImplVulkan_InitInfo
};
// Called by user code
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass);
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass, int subpass = 0);
IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame();
IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer);

View File

@ -63,7 +63,7 @@ public:
pixelCounterReset->upload(sizeof(zero), &zero);
}
// We need to wait until this buffer is not used before deleting it
VulkanContext::Instance()->GetGraphicsQueue().waitIdle();
context->GetGraphicsQueue().waitIdle();
abufferPointerAttachment.reset();
abufferPointerAttachment = std::unique_ptr<FramebufferAttachment>(
new FramebufferAttachment(context->GetPhysicalDevice(), context->GetDevice()));

View File

@ -577,6 +577,7 @@ void OITTextureDrawer::EndFrame()
vk::CommandBuffer OITScreenDrawer::NewFrame()
{
GetContext()->NewFrame();
GetContext()->InitImgui(GetRenderPass(), 2);
vk::CommandBuffer commandBuffer = GetContext()->GetCurrentCommandBuffer();
viewport.offset.x = 0;

View File

@ -40,6 +40,7 @@ public:
bool Init();
bool InitInstance(const char** extensions, uint32_t extensions_count);
bool InitDevice();
void InitImgui(vk::RenderPass renderPass, int subpass = 0);
void CreateSwapChain();
void Term();
void SetWindow(void *window, void *display) { this->window = window; this->display = display; }
@ -95,7 +96,6 @@ public:
private:
vk::Format InitDepthBuffer();
void InitImgui();
void DoSwapAutomation();
vk::SurfaceKHR GetSurface() {
#ifdef USE_SDL

View File

@ -281,7 +281,7 @@ vk::Format VulkanContext::InitDepthBuffer()
return depthFormat;
}
void VulkanContext::InitImgui()
void VulkanContext::InitImgui(vk::RenderPass renderPass, int subpass)
{
gui_init();
ImGui_ImplVulkan_InitInfo initInfo = {};
@ -296,22 +296,25 @@ void VulkanContext::InitImgui()
initInfo.CheckVkResultFn = &CheckImGuiResult;
#endif
if (!ImGui_ImplVulkan_Init(&initInfo, (VkRenderPass)*renderPass))
if (!ImGui_ImplVulkan_Init(&initInfo, (VkRenderPass)renderPass, subpass))
{
die("ImGui initialization failed");
}
// Upload Fonts
device->resetFences(1, &(*drawFences.front()));
device->resetCommandPool(*commandPools.front(), vk::CommandPoolResetFlagBits::eReleaseResources);
vk::CommandBuffer& commandBuffer = *commandBuffers.front();
commandBuffer.begin(vk::CommandBufferBeginInfo(vk::CommandBufferUsageFlagBits::eOneTimeSubmit));
ImGui_ImplVulkan_CreateFontsTexture((VkCommandBuffer)commandBuffer);
commandBuffer.end();
vk::SubmitInfo submitInfo(0, nullptr, nullptr, 1, &commandBuffer);
graphicsQueue.submit(1, &submitInfo, *drawFences.front());
if (ImGui::GetIO().Fonts->TexID == 0)
{
// Upload Fonts
device->resetFences(1, &(*drawFences.front()));
device->resetCommandPool(*commandPools.front(), vk::CommandPoolResetFlagBits::eReleaseResources);
vk::CommandBuffer& commandBuffer = *commandBuffers.front();
commandBuffer.begin(vk::CommandBufferBeginInfo(vk::CommandBufferUsageFlagBits::eOneTimeSubmit));
ImGui_ImplVulkan_CreateFontsTexture((VkCommandBuffer)commandBuffer);
commandBuffer.end();
vk::SubmitInfo submitInfo(0, nullptr, nullptr, 1, &commandBuffer);
graphicsQueue.submit(1, &submitInfo, *drawFences.front());
device->waitIdle();
ImGui_ImplVulkan_InvalidateFontUploadObjects();
device->waitIdle();
ImGui_ImplVulkan_InvalidateFontUploadObjects();
}
}
bool VulkanContext::InitDevice()
@ -604,7 +607,7 @@ void VulkanContext::CreateSwapChain()
imageAcquiredSemaphores.push_back(device->createSemaphoreUnique(vk::SemaphoreCreateInfo()));
}
InitImgui();
InitImgui(*renderPass);
INFO_LOG(RENDERER, "Vulkan swap chain created: %d x %d, swap chain size %d", width, height, (int)imageViews.size());
}
@ -677,6 +680,7 @@ void VulkanContext::NewFrame()
void VulkanContext::BeginRenderPass()
{
InitImgui(*renderPass);
const vk::ClearValue clear_colors[] = { vk::ClearColorValue(std::array<float, 4>{0.f, 0.f, 0.f, 1.f}), vk::ClearDepthStencilValue{ 0.f, 0 } };
vk::CommandBuffer commandBuffer = *commandBuffers[currentImage];
commandBuffer.beginRenderPass(vk::RenderPassBeginInfo(*renderPass, *framebuffers[currentImage], vk::Rect2D({0, 0}, {width, height}), 2, clear_colors),