diff --git a/vita3k/gui/include/gui/imgui_impl_sdl_vulkan.h b/vita3k/gui/include/gui/imgui_impl_sdl_vulkan.h index 1124c90771..f749c5b6ef 100644 --- a/vita3k/gui/include/gui/imgui_impl_sdl_vulkan.h +++ b/vita3k/gui/include/gui/imgui_impl_sdl_vulkan.h @@ -139,10 +139,10 @@ struct ImGui_VulkanState : public ImGui_State { vk::PipelineCreateFlags PipelineCreateFlags{}; vk::DescriptorSetLayout DescriptorSetLayout{}; vk::PipelineLayout PipelineLayout{}; - vk::Pipeline Pipeline{}; + VkPipeline Pipeline{}; uint32_t Subpass{}; - vk::ShaderModule ShaderModuleVert{}; - vk::ShaderModule ShaderModuleFrag{}; + VkShaderModule ShaderModuleVert{}; + VkShaderModule ShaderModuleFrag{}; // Font data vk::Sampler FontSampler{}; diff --git a/vita3k/gui/src/gui.cpp b/vita3k/gui/src/gui.cpp index 3ba15ef345..0f632a1c14 100644 --- a/vita3k/gui/src/gui.cpp +++ b/vita3k/gui/src/gui.cpp @@ -738,6 +738,13 @@ void pre_init(GuiState &gui, EmuEnvState &emuenv) { init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT; // init_info.Allocator = g_Allocator; // init_info.CheckVkResultFn = check_vk_result; + +#if VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1 + ImGui_ImplVulkan_LoadFunctions([](const char *function, void *user_data) { + return VULKAN_HPP_DEFAULT_DISPATCHER.vkGetInstanceProcAddr((VkInstance)user_data, function); + }, init_info.Instance); +#endif + gui.imgui_state.reset(ImGui_ImplVulkan_Init(emuenv.renderer.get(), &init_info)); ImGui_ImplVulkan_CreateDeviceObjects(dynamic_cast(*gui.imgui_state)); } else { diff --git a/vita3k/gui/src/imgui_impl_sdl_vulkan.cpp b/vita3k/gui/src/imgui_impl_sdl_vulkan.cpp index a8b4e210ee..3369a97299 100644 --- a/vita3k/gui/src/imgui_impl_sdl_vulkan.cpp +++ b/vita3k/gui/src/imgui_impl_sdl_vulkan.cpp @@ -430,28 +430,28 @@ static void ImGui_ImplVulkan_SetupRenderState(ImGui_VulkanState &state, ImDrawDa // Bind pipeline: { - command_buffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline); + vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); } // Bind Vertex And Index Buffer: if (draw_data->TotalVtxCount > 0) { - vk::DeviceSize vertex_offset = 0; - command_buffer.bindVertexBuffers(0, rb->VertexBuffer, vertex_offset); - command_buffer.bindIndexBuffer(rb->IndexBuffer, 0, sizeof(ImDrawIdx) == 2 ? vk::IndexType::eUint16 : vk::IndexType::eUint32); + VkBuffer vertex_buffers[1] = { rb->VertexBuffer }; + VkDeviceSize vertex_offset[1] = { 0 }; + vkCmdBindVertexBuffers(command_buffer, 0, 1, vertex_buffers, vertex_offset); + vkCmdBindIndexBuffer(command_buffer, rb->IndexBuffer, 0, sizeof(ImDrawIdx) == 2 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32); } // Setup viewport: { - vk::Viewport viewport{ - .x = 0, - .y = 0, - .width = static_cast(fb_width), - .height = static_cast(fb_height), - .minDepth = 0.f, - .maxDepth = 1.f - }; - command_buffer.setViewport(0, viewport); + VkViewport viewport; + viewport.x = 0; + viewport.y = 0; + viewport.width = (float)fb_width; + viewport.height = (float)fb_height; + viewport.minDepth = 0.0f; + viewport.maxDepth = 1.0f; + vkCmdSetViewport(command_buffer, 0, 1, &viewport); } // Setup scale and translation: @@ -463,8 +463,8 @@ static void ImGui_ImplVulkan_SetupRenderState(ImGui_VulkanState &state, ImDrawDa float translate[2]; translate[0] = -1.0f - draw_data->DisplayPos.x * scale[0]; translate[1] = -1.0f - draw_data->DisplayPos.y * scale[1]; - command_buffer.pushConstants(state.PipelineLayout, vk::ShaderStageFlagBits::eVertex, sizeof(float) * 0, sizeof(float) * 2, scale); - command_buffer.pushConstants(state.PipelineLayout, vk::ShaderStageFlagBits::eVertex, sizeof(float) * 2, sizeof(float) * 2, translate); + vkCmdPushConstants(command_buffer, state.PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 0, sizeof(float) * 2, scale); + vkCmdPushConstants(command_buffer, state.PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 2, sizeof(float) * 2, translate); } } @@ -473,7 +473,7 @@ static void ImGui_ImplVulkan_DeletePipeline(ImGui_VulkanState &state) dynamic_cast(*state.renderer).device.destroy(state.Pipeline); } -static void ImGui_ImplVulkan_CreatePipeline(ImGui_VulkanState &state); +static void ImGui_ImplVulkan_CreatePipeline(ImGui_VulkanState &state, const VkAllocationCallbacks* allocator, VkRenderPass renderPass, VkSampleCountFlagBits MSAASamples, VkPipeline* pipeline); // Render function void ImGui_ImplVulkan_RenderDrawData(ImGui_VulkanState &state, ImDrawData* draw_data, vk::CommandBuffer command_buffer, VkPipeline pipeline) @@ -481,7 +481,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImGui_VulkanState &state, ImDrawData* draw_ auto &vk_state = dynamic_cast(*state.renderer); if (vk_state.screen_renderer.need_rebuild) { ImGui_ImplVulkan_DeletePipeline(state); - ImGui_ImplVulkan_CreatePipeline(state); + ImGui_ImplVulkan_CreatePipeline(state, nullptr, vk_state.screen_renderer.default_render_pass, VK_SAMPLE_COUNT_1_BIT, &state.Pipeline); vk_state.screen_renderer.need_rebuild = false; } @@ -494,7 +494,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImGui_VulkanState &state, ImDrawData* draw_ ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; if (pipeline == VK_NULL_HANDLE) - pipeline = static_cast(state.Pipeline); + pipeline = state.Pipeline; // Allocate array to store enough vertex/index buffers ImGui_ImplVulkanH_WindowRenderBuffers* wrb = &state.MainWindowRenderBuffers; @@ -561,7 +561,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImGui_VulkanState &state, ImDrawData* draw_ // User callback, registered via ImDrawList::AddCallback() // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) - ImGui_ImplVulkan_SetupRenderState(state, draw_data, static_cast(state.Pipeline), state.CommandBuffer, rb, fb_width, fb_height); + ImGui_ImplVulkan_SetupRenderState(state, draw_data, static_cast(state.Pipeline), command_buffer, rb, fb_width, fb_height); else pcmd->UserCallback(cmd_list, pcmd); } @@ -580,11 +580,12 @@ void ImGui_ImplVulkan_RenderDrawData(ImGui_VulkanState &state, ImDrawData* draw_ continue; // Apply scissor/clipping rectangle - vk::Rect2D scissor{ - .offset = { static_cast(clip_min.x), static_cast(clip_min.y) }, - .extent = { static_cast(clip_max.x - clip_min.x), static_cast(clip_max.y - clip_min.y) } - }; - state.CommandBuffer.setScissor(0, scissor); + VkRect2D scissor; + scissor.offset.x = (int32_t)(clip_min.x); + scissor.offset.y = (int32_t)(clip_min.y); + scissor.extent.width = (uint32_t)(clip_max.x - clip_min.x); + scissor.extent.height = (uint32_t)(clip_max.y - clip_min.y); + vkCmdSetScissor(command_buffer, 0, 1, &scissor); // Bind DescriptorSet with font or user texture TextureState *texture; @@ -598,7 +599,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImGui_VulkanState &state, ImDrawData* draw_ state.CommandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, state.PipelineLayout, 0, texture->descriptor_set, {}); // Draw - state.CommandBuffer.drawIndexed(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0); + vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0); } } global_idx_offset += cmd_list->IdxBuffer.Size; @@ -974,119 +975,109 @@ static void ImGui_ImplVulkan_CreateShaderModules(ImGui_VulkanState &state) } } -static void ImGui_ImplVulkan_CreatePipeline(ImGui_VulkanState &state) +static void ImGui_ImplVulkan_CreatePipeline(ImGui_VulkanState &state, const VkAllocationCallbacks* allocator, VkRenderPass renderPass, VkSampleCountFlagBits MSAASamples, VkPipeline* pipeline) { ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); - auto &vk_state = dynamic_cast(*state.renderer); - - std::vector shader_stage_infos = { - vk::PipelineShaderStageCreateInfo{ - .stage = vk::ShaderStageFlagBits::eVertex, - .module = state.ShaderModuleVert, - .pName = "main" }, - vk::PipelineShaderStageCreateInfo{ - .stage = vk::ShaderStageFlagBits::eFragment, - .module = state.ShaderModuleFrag, - .pName = "main" }, - }; - - std::vector gui_pipeline_bindings = { - vk::VertexInputBindingDescription{ - .binding = 0, - .stride = sizeof(ImDrawVert) }, - }; - - std::vector gui_pipeline_attributes = { - vk::VertexInputAttributeDescription{ - .location = 0, - .binding = 0, - .format = vk::Format::eR32G32Sfloat, - .offset = 0 }, - vk::VertexInputAttributeDescription{ - .location = 1, - .binding = 0, - .format = vk::Format::eR32G32Sfloat, - .offset = sizeof(ImVec2) }, - vk::VertexInputAttributeDescription{ - .location = 2, - .binding = 0, - .format = vk::Format::eR8G8B8A8Unorm, - .offset = sizeof(ImVec2) * 2 }, - }; - - vk::PipelineVertexInputStateCreateInfo gui_pipeline_vertex_info{ - .vertexBindingDescriptionCount = static_cast(gui_pipeline_bindings.size()), - .pVertexBindingDescriptions = gui_pipeline_bindings.data(), // Bindings - .vertexAttributeDescriptionCount = static_cast(gui_pipeline_attributes.size()), - .pVertexAttributeDescriptions = gui_pipeline_attributes.data() // Attributes - }; - - vk::PipelineInputAssemblyStateCreateInfo gui_pipeline_assembly_info{ - .topology = vk::PrimitiveTopology::eTriangleList, - .primitiveRestartEnable = false - }; - - vk::PipelineViewportStateCreateInfo gui_pipeline_viewport_info{ - .viewportCount = 1, - .scissorCount = 1, - }; - vk::PipelineRasterizationStateCreateInfo gui_pipeline_rasterization_info{ - .polygonMode = vk::PolygonMode::eFill, // Fill Polygons - .cullMode = vk::CullModeFlagBits::eNone, - .frontFace = vk::FrontFace::eCounterClockwise, // Counter Clockwise Face Forwards - .lineWidth = 1.0f // Line Width - }; - - vk::PipelineMultisampleStateCreateInfo gui_pipeline_multisample_info{ - .rasterizationSamples = vk::SampleCountFlagBits::e1, // No Multisampling - }; - - vk::PipelineDepthStencilStateCreateInfo gui_pipeline_depth_stencil_info{ - .depthCompareOp = vk::CompareOp::eAlways, - .minDepthBounds = 0.0f, - .maxDepthBounds = 1.0f - }; - - vk::PipelineColorBlendAttachmentState attachment_blending{ - true, // Enable Blending - vk::BlendFactor::eSrcAlpha, // Src Color - vk::BlendFactor::eOneMinusSrcAlpha, // Dst Color - vk::BlendOp::eAdd, // Color Blend Op - vk::BlendFactor::eOne, // Src Alpha - vk::BlendFactor::eOneMinusSrcAlpha, // Dst Alpha - vk::BlendOp::eAdd, // Alpha Blend Op - vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA - }; + VkPipelineShaderStageCreateInfo stage[2] = {}; + stage[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stage[0].stage = VK_SHADER_STAGE_VERTEX_BIT; + stage[0].module = state.ShaderModuleVert; + stage[0].pName = "main"; + stage[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stage[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; + stage[1].module = state.ShaderModuleFrag; + stage[1].pName = "main"; + + VkVertexInputBindingDescription binding_desc[1] = {}; + binding_desc[0].stride = sizeof(ImDrawVert); + binding_desc[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX; + + VkVertexInputAttributeDescription attribute_desc[3] = {}; + attribute_desc[0].location = 0; + attribute_desc[0].binding = binding_desc[0].binding; + attribute_desc[0].format = VK_FORMAT_R32G32_SFLOAT; + attribute_desc[0].offset = offsetof(ImDrawVert, pos); + attribute_desc[1].location = 1; + attribute_desc[1].binding = binding_desc[0].binding; + attribute_desc[1].format = VK_FORMAT_R32G32_SFLOAT; + attribute_desc[1].offset = offsetof(ImDrawVert, uv); + attribute_desc[2].location = 2; + attribute_desc[2].binding = binding_desc[0].binding; + attribute_desc[2].format = VK_FORMAT_R8G8B8A8_UNORM; + attribute_desc[2].offset = offsetof(ImDrawVert, col); + + VkPipelineVertexInputStateCreateInfo vertex_info = {}; + vertex_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + vertex_info.vertexBindingDescriptionCount = 1; + vertex_info.pVertexBindingDescriptions = binding_desc; + vertex_info.vertexAttributeDescriptionCount = 3; + vertex_info.pVertexAttributeDescriptions = attribute_desc; + + VkPipelineInputAssemblyStateCreateInfo ia_info = {}; + ia_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + ia_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + + VkPipelineViewportStateCreateInfo viewport_info = {}; + viewport_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + viewport_info.viewportCount = 1; + viewport_info.scissorCount = 1; + + VkPipelineRasterizationStateCreateInfo raster_info = {}; + raster_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + raster_info.polygonMode = VK_POLYGON_MODE_FILL; + raster_info.cullMode = VK_CULL_MODE_NONE; + raster_info.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; + raster_info.lineWidth = 1.0f; + + VkPipelineMultisampleStateCreateInfo ms_info = {}; + ms_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + ms_info.rasterizationSamples = (MSAASamples != 0) ? MSAASamples : VK_SAMPLE_COUNT_1_BIT; + + VkPipelineColorBlendAttachmentState color_attachment[1] = {}; + color_attachment[0].blendEnable = VK_TRUE; + color_attachment[0].srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; + color_attachment[0].dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + color_attachment[0].colorBlendOp = VK_BLEND_OP_ADD; + color_attachment[0].srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; + color_attachment[0].dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + color_attachment[0].alphaBlendOp = VK_BLEND_OP_ADD; + color_attachment[0].colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + + VkPipelineDepthStencilStateCreateInfo depth_info = {}; + depth_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + + VkPipelineColorBlendStateCreateInfo blend_info = {}; + blend_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + blend_info.attachmentCount = 1; + blend_info.pAttachments = color_attachment; + + VkDynamicState dynamic_states[2] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; + VkPipelineDynamicStateCreateInfo dynamic_state = {}; + dynamic_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynamic_state.dynamicStateCount = (uint32_t)IM_ARRAYSIZE(dynamic_states); + dynamic_state.pDynamicStates = dynamic_states; - vk::PipelineColorBlendStateCreateInfo gui_pipeline_blend_info{ - .attachmentCount = 1, - .pAttachments = &attachment_blending - }; + auto &vk_state = dynamic_cast(*state.renderer); - std::array dynamic_states = { - vk::DynamicState::eScissor, - vk::DynamicState::eViewport, - }; + VkGraphicsPipelineCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + info.flags = bd->PipelineCreateFlags; + info.stageCount = 2; + info.pStages = stage; + info.pVertexInputState = &vertex_info; + info.pInputAssemblyState = &ia_info; + info.pViewportState = &viewport_info; + info.pRasterizationState = &raster_info; + info.pMultisampleState = &ms_info; + info.pDepthStencilState = &depth_info; + info.pColorBlendState = &blend_info; + info.pDynamicState = &dynamic_state; + info.layout = state.PipelineLayout; + info.renderPass = renderPass; + //info.subpass = subpass; - vk::PipelineDynamicStateCreateInfo gui_pipeline_dynamic_info{}; - gui_pipeline_dynamic_info.setDynamicStates(dynamic_states); - - vk::GraphicsPipelineCreateInfo gui_pipeline_info{ - .pVertexInputState = &gui_pipeline_vertex_info, - .pInputAssemblyState = &gui_pipeline_assembly_info, - .pViewportState = &gui_pipeline_viewport_info, - .pRasterizationState = &gui_pipeline_rasterization_info, - .pMultisampleState = &gui_pipeline_multisample_info, - .pDepthStencilState = &gui_pipeline_depth_stencil_info, - .pColorBlendState = &gui_pipeline_blend_info, - .pDynamicState = &gui_pipeline_dynamic_info, - .layout = state.PipelineLayout, - .renderPass = vk_state.screen_renderer.default_render_pass, - }; - gui_pipeline_info.setStages(shader_stage_infos); - -#if 0 +#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING if (bd->VulkanInitInfo.UseDynamicRendering) { IM_ASSERT(bd->VulkanInitInfo.PipelineRenderingCreateInfo.sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR && "PipelineRenderingCreateInfo sType must be VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR"); @@ -1096,7 +1087,8 @@ static void ImGui_ImplVulkan_CreatePipeline(ImGui_VulkanState &state) } #endif - state.Pipeline = vk_state.device.createGraphicsPipeline(vk::PipelineCache(), gui_pipeline_info, nullptr).value; + VkResult err = vkCreateGraphicsPipelines(vk_state.device, vk::PipelineCache(), 1, &info, nullptr, pipeline); + check_vk_result(err); } bool ImGui_ImplVulkan_CreateDeviceObjects(ImGui_VulkanState &state) @@ -1150,7 +1142,7 @@ bool ImGui_ImplVulkan_CreateDeviceObjects(ImGui_VulkanState &state) state.PipelineLayout = vk_state.device.createPipelineLayout(layout_info); } - ImGui_ImplVulkan_CreatePipeline(state); + ImGui_ImplVulkan_CreatePipeline(state, nullptr, vk_state.screen_renderer.default_render_pass, VK_SAMPLE_COUNT_1_BIT, &state.Pipeline); { vk::DescriptorPoolSize pool_size{