summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_vulkan/renderer_vulkan.cpp
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2021-02-13 07:22:18 +0100
committerGitHub <noreply@github.com>2021-02-13 07:22:18 +0100
commitd3c7a7e7cf4bcabb171c98fe55e6e0291f8ee980 (patch)
tree5c900d10847e1768a4951c1e6bec35f2618b5991 /src/video_core/renderer_vulkan/renderer_vulkan.cpp
parentMerge pull request #5877 from ameerj/res-limit-usage (diff)
parentconfig: Make high GPU accuracy the default (diff)
downloadyuzu-d3c7a7e7cf4bcabb171c98fe55e6e0291f8ee980.tar
yuzu-d3c7a7e7cf4bcabb171c98fe55e6e0291f8ee980.tar.gz
yuzu-d3c7a7e7cf4bcabb171c98fe55e6e0291f8ee980.tar.bz2
yuzu-d3c7a7e7cf4bcabb171c98fe55e6e0291f8ee980.tar.lz
yuzu-d3c7a7e7cf4bcabb171c98fe55e6e0291f8ee980.tar.xz
yuzu-d3c7a7e7cf4bcabb171c98fe55e6e0291f8ee980.tar.zst
yuzu-d3c7a7e7cf4bcabb171c98fe55e6e0291f8ee980.zip
Diffstat (limited to 'src/video_core/renderer_vulkan/renderer_vulkan.cpp')
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp153
1 files changed, 53 insertions, 100 deletions
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index 61796e33a..1cc720ddd 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -80,17 +80,50 @@ std::string BuildCommaSeparatedExtensions(std::vector<std::string> available_ext
return separated_extensions;
}
+Device CreateDevice(const vk::Instance& instance, const vk::InstanceDispatch& dld,
+ VkSurfaceKHR surface) {
+ const std::vector<VkPhysicalDevice> devices = instance.EnumeratePhysicalDevices();
+ const s32 device_index = Settings::values.vulkan_device.GetValue();
+ if (device_index < 0 || device_index >= static_cast<s32>(devices.size())) {
+ LOG_ERROR(Render_Vulkan, "Invalid device index {}!", device_index);
+ throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
+ }
+ const vk::PhysicalDevice physical_device(devices[device_index], dld);
+ return Device(*instance, physical_device, surface, dld);
+}
} // Anonymous namespace
RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_,
Core::Frontend::EmuWindow& emu_window,
Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_,
- std::unique_ptr<Core::Frontend::GraphicsContext> context_)
- : RendererBase{emu_window, std::move(context_)}, telemetry_session{telemetry_session_},
- cpu_memory{cpu_memory_}, gpu{gpu_} {}
+ std::unique_ptr<Core::Frontend::GraphicsContext> context_) try
+ : RendererBase(emu_window, std::move(context_)),
+ telemetry_session(telemetry_session_),
+ cpu_memory(cpu_memory_),
+ gpu(gpu_),
+ library(OpenLibrary()),
+ instance(CreateInstance(library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type,
+ true, Settings::values.renderer_debug)),
+ debug_callback(Settings::values.renderer_debug ? CreateDebugCallback(instance) : nullptr),
+ surface(CreateSurface(instance, render_window)),
+ device(CreateDevice(instance, dld, *surface)),
+ memory_allocator(device, false),
+ state_tracker(gpu),
+ scheduler(device, state_tracker),
+ swapchain(*surface, device, scheduler, render_window.GetFramebufferLayout().width,
+ render_window.GetFramebufferLayout().height, false),
+ blit_screen(cpu_memory, render_window, device, memory_allocator, swapchain, scheduler,
+ screen_info),
+ rasterizer(render_window, gpu, gpu.MemoryManager(), cpu_memory, screen_info, device,
+ memory_allocator, state_tracker, scheduler) {
+ Report();
+} catch (const vk::Exception& exception) {
+ LOG_ERROR(Render_Vulkan, "Vulkan initialization failed with error: {}", exception.what());
+ throw std::runtime_error{fmt::format("Vulkan initialization error {}", exception.what())};
+}
RendererVulkan::~RendererVulkan() {
- ShutDown();
+ void(device.GetLogical().WaitIdle());
}
void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
@@ -101,101 +134,38 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
if (layout.width > 0 && layout.height > 0 && render_window.IsShown()) {
const VAddr framebuffer_addr = framebuffer->address + framebuffer->offset;
const bool use_accelerated =
- rasterizer->AccelerateDisplay(*framebuffer, framebuffer_addr, framebuffer->stride);
+ rasterizer.AccelerateDisplay(*framebuffer, framebuffer_addr, framebuffer->stride);
const bool is_srgb = use_accelerated && screen_info.is_srgb;
- if (swapchain->HasFramebufferChanged(layout) || swapchain->GetSrgbState() != is_srgb) {
- swapchain->Create(layout.width, layout.height, is_srgb);
- blit_screen->Recreate();
+ if (swapchain.HasFramebufferChanged(layout) || swapchain.GetSrgbState() != is_srgb) {
+ swapchain.Create(layout.width, layout.height, is_srgb);
+ blit_screen.Recreate();
}
- scheduler->WaitWorker();
+ scheduler.WaitWorker();
- swapchain->AcquireNextImage();
- const VkSemaphore render_semaphore = blit_screen->Draw(*framebuffer, use_accelerated);
+ swapchain.AcquireNextImage();
+ const VkSemaphore render_semaphore = blit_screen.Draw(*framebuffer, use_accelerated);
- scheduler->Flush(render_semaphore);
+ scheduler.Flush(render_semaphore);
- if (swapchain->Present(render_semaphore)) {
- blit_screen->Recreate();
+ if (swapchain.Present(render_semaphore)) {
+ blit_screen.Recreate();
}
-
- rasterizer->TickFrame();
+ rasterizer.TickFrame();
}
render_window.OnFrameDisplayed();
}
-bool RendererVulkan::Init() try {
- library = OpenLibrary();
- instance = CreateInstance(library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type,
- true, Settings::values.renderer_debug);
- if (Settings::values.renderer_debug) {
- debug_callback = CreateDebugCallback(instance);
- }
- surface = CreateSurface(instance, render_window);
-
- InitializeDevice();
- Report();
-
- memory_allocator = std::make_unique<MemoryAllocator>(*device);
-
- state_tracker = std::make_unique<StateTracker>(gpu);
-
- scheduler = std::make_unique<VKScheduler>(*device, *state_tracker);
-
- const auto& framebuffer = render_window.GetFramebufferLayout();
- swapchain = std::make_unique<VKSwapchain>(*surface, *device, *scheduler);
- swapchain->Create(framebuffer.width, framebuffer.height, false);
-
- rasterizer = std::make_unique<RasterizerVulkan>(render_window, gpu, gpu.MemoryManager(),
- cpu_memory, screen_info, *device,
- *memory_allocator, *state_tracker, *scheduler);
-
- blit_screen =
- std::make_unique<VKBlitScreen>(cpu_memory, render_window, *rasterizer, *device,
- *memory_allocator, *swapchain, *scheduler, screen_info);
- return true;
-
-} catch (const vk::Exception& exception) {
- LOG_ERROR(Render_Vulkan, "Vulkan initialization failed with error: {}", exception.what());
- return false;
-}
-
-void RendererVulkan::ShutDown() {
- if (!device) {
- return;
- }
- if (const auto& dev = device->GetLogical()) {
- dev.WaitIdle();
- }
- rasterizer.reset();
- blit_screen.reset();
- scheduler.reset();
- swapchain.reset();
- memory_allocator.reset();
- device.reset();
-}
-
-void RendererVulkan::InitializeDevice() {
- const std::vector<VkPhysicalDevice> devices = instance.EnumeratePhysicalDevices();
- const s32 device_index = Settings::values.vulkan_device.GetValue();
- if (device_index < 0 || device_index >= static_cast<s32>(devices.size())) {
- LOG_ERROR(Render_Vulkan, "Invalid device index {}!", device_index);
- throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
- }
- const vk::PhysicalDevice physical_device(devices[static_cast<size_t>(device_index)], dld);
- device = std::make_unique<Device>(*instance, physical_device, *surface, dld);
-}
-
void RendererVulkan::Report() const {
- const std::string vendor_name{device->GetVendorName()};
- const std::string model_name{device->GetModelName()};
- const std::string driver_version = GetDriverVersion(*device);
+ const std::string vendor_name{device.GetVendorName()};
+ const std::string model_name{device.GetModelName()};
+ const std::string driver_version = GetDriverVersion(device);
const std::string driver_name = fmt::format("{} {}", vendor_name, driver_version);
- const std::string api_version = GetReadableVersion(device->ApiVersion());
+ const std::string api_version = GetReadableVersion(device.ApiVersion());
- const std::string extensions = BuildCommaSeparatedExtensions(device->GetAvailableExtensions());
+ const std::string extensions = BuildCommaSeparatedExtensions(device.GetAvailableExtensions());
LOG_INFO(Render_Vulkan, "Driver: {}", driver_name);
LOG_INFO(Render_Vulkan, "Device: {}", model_name);
@@ -209,21 +179,4 @@ void RendererVulkan::Report() const {
telemetry_session.AddField(field, "GPU_Vulkan_Extensions", extensions);
}
-std::vector<std::string> RendererVulkan::EnumerateDevices() try {
- vk::InstanceDispatch dld;
- const Common::DynamicLibrary library = OpenLibrary();
- const vk::Instance instance = CreateInstance(library, dld, VK_API_VERSION_1_0);
- const std::vector<VkPhysicalDevice> physical_devices = instance.EnumeratePhysicalDevices();
- std::vector<std::string> names;
- names.reserve(physical_devices.size());
- for (const VkPhysicalDevice device : physical_devices) {
- names.push_back(vk::PhysicalDevice(device, dld).GetProperties().deviceName);
- }
- return names;
-
-} catch (const vk::Exception& exception) {
- LOG_ERROR(Render_Vulkan, "Failed to enumerate devices with error: {}", exception.what());
- return {};
-}
-
} // namespace Vulkan