CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/libretro/LibretroVulkanContext.cpp
Views: 1401
1#include "Common/GPU/Vulkan/VulkanLoader.h"2#include "Common/GPU/Vulkan/VulkanContext.h"3#include "Common/GPU/Vulkan/VulkanDebug.h"4#include "Common/Log.h"5#include "Core/Config.h"6#include "Core/ConfigValues.h"7#include "Core/System.h"8#include "GPU/GPUInterface.h"9#include "Common/Data/Text/Parsers.h"1011#include "libretro/LibretroVulkanContext.h"12#include "libretro/libretro_vulkan.h"13#include <GPU/Vulkan/VulkanRenderManager.h>1415static VulkanContext *vk;1617void vk_libretro_init(VkInstance instance, VkPhysicalDevice gpu, VkSurfaceKHR surface, PFN_vkGetInstanceProcAddr get_instance_proc_addr, const char **required_device_extensions, unsigned num_required_device_extensions, const char **required_device_layers, unsigned num_required_device_layers, const VkPhysicalDeviceFeatures *required_features);18void vk_libretro_shutdown();19void vk_libretro_set_hwrender_interface(retro_hw_render_interface *hw_render_interface);20void vk_libretro_wait_for_presentation();2122LibretroVulkanContext::LibretroVulkanContext()23: LibretroHWRenderContext(RETRO_HW_CONTEXT_VULKAN, VK_MAKE_VERSION(1, 0, 18)) {}2425void LibretroVulkanContext::SwapBuffers() {26vk_libretro_wait_for_presentation();27LibretroHWRenderContext::SwapBuffers();28}2930static bool create_device(retro_vulkan_context *context, VkInstance instance, VkPhysicalDevice gpu, VkSurfaceKHR surface, PFN_vkGetInstanceProcAddr get_instance_proc_addr, const char **required_device_extensions, unsigned num_required_device_extensions, const char **required_device_layers, unsigned num_required_device_layers, const VkPhysicalDeviceFeatures *required_features) {31init_glslang();3233vk = new VulkanContext();3435vk_libretro_init(instance, gpu, surface, get_instance_proc_addr, required_device_extensions, num_required_device_extensions, required_device_layers, num_required_device_layers, required_features);3637// TODO: Here we'll inject the instance and all of the stuff into the VulkanContext.3839vk->CreateInstance({});4041int physical_device = 0;42while (gpu && vk->GetPhysicalDevice(physical_device) != gpu) {43physical_device++;44}4546if (!gpu) {47physical_device = vk->GetBestPhysicalDevice();48}4950vk->CreateDevice(physical_device);51#ifdef _WIN3252vk->InitSurface(WINDOWSYSTEM_WIN32, nullptr, nullptr);53#elif defined(__ANDROID__)54vk->InitSurface(WINDOWSYSTEM_ANDROID, nullptr, nullptr);55#elif defined(VK_USE_PLATFORM_METAL_EXT)56vk->InitSurface(WINDOWSYSTEM_METAL_EXT, nullptr, nullptr);57#elif defined(VK_USE_PLATFORM_XLIB_KHR)58vk->InitSurface(WINDOWSYSTEM_XLIB, nullptr, nullptr);59#elif defined(VK_USE_PLATFORM_XCB_KHR)60vk->InitSurface(WINDOWSYSTEM_XCB, nullptr, nullptr);61#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)62vk->InitSurface(WINDOWSYSTEM_WAYLAND, nullptr, nullptr);63#elif defined(VK_USE_PLATFORM_DISPLAY_KHR)64vk->InitSurface(WINDOWSYSTEM_DISPLAY, nullptr, nullptr);65#endif6667context->gpu = vk->GetPhysicalDevice(physical_device);68context->device = vk->GetDevice();69context->queue = vk->GetGraphicsQueue();70context->queue_family_index = vk->GetGraphicsQueueFamilyIndex();71context->presentation_queue = context->queue;72context->presentation_queue_family_index = context->queue_family_index;73#ifdef _DEBUG74fflush(stdout);75#endif76return true;77}7879static const VkApplicationInfo *GetApplicationInfo(void) {80static VkApplicationInfo app_info{ VK_STRUCTURE_TYPE_APPLICATION_INFO };81app_info.pApplicationName = "PPSSPP";82app_info.applicationVersion = Version(PPSSPP_GIT_VERSION).ToInteger();83app_info.pEngineName = "PPSSPP";84app_info.engineVersion = 2;85app_info.apiVersion = VK_API_VERSION_1_0;86return &app_info;87}8889bool LibretroVulkanContext::Init() {90if (!LibretroHWRenderContext::Init(true)) {91return false;92}9394static const struct retro_hw_render_context_negotiation_interface_vulkan iface = {95RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN,96RETRO_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE_VULKAN_VERSION,97GetApplicationInfo,98create_device, // Callback above.99nullptr,100};101Libretro::environ_cb(RETRO_ENVIRONMENT_SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE, (void *)&iface);102103g_Config.iGPUBackend = (int)GPUBackend::VULKAN;104return true;105}106107void LibretroVulkanContext::ContextReset() {108retro_hw_render_interface *vulkan;109if (!Libretro::environ_cb(RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE, (void **)&vulkan) || !vulkan) {110ERROR_LOG(Log::G3D, "Failed to get HW rendering interface!\n");111return;112}113if (vulkan->interface_version != RETRO_HW_RENDER_INTERFACE_VULKAN_VERSION) {114ERROR_LOG(Log::G3D, "HW render interface mismatch, expected %u, got %u!\n", RETRO_HW_RENDER_INTERFACE_VULKAN_VERSION, vulkan->interface_version);115return;116}117vk_libretro_set_hwrender_interface(vulkan);118119LibretroHWRenderContext::ContextReset();120}121122void LibretroVulkanContext::ContextDestroy() {123INFO_LOG(Log::G3D, "LibretroVulkanContext::ContextDestroy()");124vk->WaitUntilQueueIdle();125LibretroHWRenderContext::ContextDestroy();126}127128void LibretroVulkanContext::CreateDrawContext() {129vk->ReinitSurface();130131if (!vk->InitSwapchain()) {132return;133}134135bool useMultiThreading = g_Config.bRenderMultiThreading;136if (g_Config.iInflightFrames == 1) {137useMultiThreading = false;138}139draw_ = Draw::T3DCreateVulkanContext(vk, useMultiThreading);140((VulkanRenderManager*)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER))->SetInflightFrames(g_Config.iInflightFrames);141SetGPUBackend(GPUBackend::VULKAN);142}143144void LibretroVulkanContext::Shutdown() {145if (!vk) {146return;147}148149if (draw_)150draw_->HandleEvent(Draw::Event::LOST_BACKBUFFER, vk->GetBackbufferWidth(), vk->GetBackbufferHeight());151152LibretroHWRenderContext::Shutdown();153154vk->WaitUntilQueueIdle();155156vk->DestroySwapchain();157vk->DestroySurface();158vk->DestroyDevice();159vk->DestroyInstance();160161delete vk;162vk = nullptr;163164finalize_glslang();165vk_libretro_shutdown();166}167168void *LibretroVulkanContext::GetAPIContext() { return vk; }169170171