From daa3a8c06f375d5002159e7cbf343b71982fce27 Mon Sep 17 00:00:00 2001 From: Attila Uygun Date: Tue, 16 May 2023 11:26:57 +0200 Subject: [PATCH] Try Vulkan renderer first, fallback to OpenGL if it fails. --- src/engine/engine.cc | 5 +-- src/engine/platform/platform.cc | 14 +++---- src/engine/renderer/opengl/renderer_opengl.h | 2 + src/engine/renderer/renderer.h | 2 + src/engine/renderer/vulkan/renderer_vulkan.cc | 41 ++++++++++--------- src/engine/renderer/vulkan/renderer_vulkan.h | 6 ++- .../vulkan/renderer_vulkan_android.cc | 6 +-- .../renderer/vulkan/renderer_vulkan_linux.cc | 6 +-- 8 files changed, 39 insertions(+), 43 deletions(-) diff --git a/src/engine/engine.cc b/src/engine/engine.cc index 60240ab..82233ea 100644 --- a/src/engine/engine.cc +++ b/src/engine/engine.cc @@ -507,10 +507,7 @@ std::unique_ptr Engine::PrintStats() { line = "fps: "; line += std::to_string(fps_); lines.push_back(line); - // line = "cmd: "; - // line += std::to_string(renderer_->global_queue_size() + - // renderer_->render_queue_size()); - // lines.push_back(line); + lines.push_back(renderer_->GetDebugName()); constexpr int margin = 5; int line_height = system_font_->GetLineHeight(); diff --git a/src/engine/platform/platform.cc b/src/engine/platform/platform.cc index 2f64235..2093b40 100644 --- a/src/engine/platform/platform.cc +++ b/src/engine/platform/platform.cc @@ -7,8 +7,6 @@ #include "engine/renderer/opengl/renderer_opengl.h" #include "engine/renderer/vulkan/renderer_vulkan.h" -#define USE_VULKAN_RENDERER 1 - using namespace base; namespace eng { @@ -31,11 +29,13 @@ void Platform::InitializeCommon() { throw internal_error; } -#if (USE_VULKAN_RENDERER == 1) - renderer_ = std::make_unique(); -#else - renderer_ = std::make_unique(); -#endif + auto context = std::make_unique(); + if (context->Initialize()) { + renderer_ = std::make_unique(std::move(context)); + } else { + LOG << "Failed to initialize Vulkan context. Fallback to OpenGL."; + renderer_ = std::make_unique(); + } } void Platform::ShutdownCommon() { diff --git a/src/engine/renderer/opengl/renderer_opengl.h b/src/engine/renderer/opengl/renderer_opengl.h index 04646d0..4dd8f4e 100644 --- a/src/engine/renderer/opengl/renderer_opengl.h +++ b/src/engine/renderer/opengl/renderer_opengl.h @@ -87,6 +87,8 @@ class RendererOpenGL final : public Renderer { size_t GetAndResetFPS() final; + const char* GetDebugName() final { return "OpenGL"; } + #if defined(__linux__) && !defined(__ANDROID__) XVisualInfo* GetXVisualInfo(Display* display) final; #endif diff --git a/src/engine/renderer/renderer.h b/src/engine/renderer/renderer.h index 1eef944..e6bed68 100644 --- a/src/engine/renderer/renderer.h +++ b/src/engine/renderer/renderer.h @@ -92,6 +92,8 @@ class Renderer { virtual size_t GetAndResetFPS() = 0; + virtual const char* GetDebugName() = 0; + #if defined(__linux__) && !defined(__ANDROID__) virtual XVisualInfo* GetXVisualInfo(Display* display) = 0; #endif diff --git a/src/engine/renderer/vulkan/renderer_vulkan.cc b/src/engine/renderer/vulkan/renderer_vulkan.cc index b0d4170..4687e91 100644 --- a/src/engine/renderer/vulkan/renderer_vulkan.cc +++ b/src/engine/renderer/vulkan/renderer_vulkan.cc @@ -370,7 +370,8 @@ std::pair GetNumBlocksForImageFormat(VkFormat format, namespace eng { -RendererVulkan::RendererVulkan() = default; +RendererVulkan::RendererVulkan(std::unique_ptr context) + : context_{std::move(context)} {} RendererVulkan::~RendererVulkan() = default; @@ -706,7 +707,7 @@ uint64_t RendererVulkan::CreateShader( pipeline_info.pDepthStencilState = &depth_stencil; pipeline_info.pDynamicState = &dynamic_state_create_info; pipeline_info.layout = shader.pipeline_layout; - pipeline_info.renderPass = context_.GetRenderPass(); + pipeline_info.renderPass = context_->GetRenderPass(); pipeline_info.subpass = 0; pipeline_info.basePipelineHandle = VK_NULL_HANDLE; @@ -827,7 +828,7 @@ void RendererVulkan::UploadUniforms(uint64_t resource_id) { } void RendererVulkan::PrepareForDrawing() { - context_.PrepareBuffers(); + context_->PrepareBuffers(); DrawListBegin(); } @@ -839,20 +840,20 @@ void RendererVulkan::Present() { bool RendererVulkan::InitializeInternal() { glslang::InitializeProcess(); - device_ = context_.GetDevice(); + device_ = context_->GetDevice(); // Allocate one extra frame to ensure it's unused at any time without having // to use a fence. - int frame_count = context_.GetSwapchainImageCount() + 1; + int frame_count = context_->GetSwapchainImageCount() + 1; frames_.resize(frame_count); frames_drawn_ = frame_count; // Initialize allocator VmaAllocatorCreateInfo allocator_info; memset(&allocator_info, 0, sizeof(VmaAllocatorCreateInfo)); - allocator_info.physicalDevice = context_.GetPhysicalDevice(); + allocator_info.physicalDevice = context_->GetPhysicalDevice(); allocator_info.device = device_; - allocator_info.instance = context_.GetInstance(); + allocator_info.instance = context_->GetInstance(); vmaCreateAllocator(&allocator_info, &allocator_); for (size_t i = 0; i < frames_.size(); i++) { @@ -860,7 +861,7 @@ bool RendererVulkan::InitializeInternal() { VkCommandPoolCreateInfo cmd_pool_info; cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; cmd_pool_info.pNext = nullptr; - cmd_pool_info.queueFamilyIndex = context_.GetGraphicsQueue(); + cmd_pool_info.queueFamilyIndex = context_->GetGraphicsQueue(); cmd_pool_info.flags = 0; VkResult err = vkCreateCommandPool(device_, &cmd_pool_info, nullptr, @@ -1013,8 +1014,8 @@ void RendererVulkan::Shutdown() { current_staging_buffer_ = 0; staging_buffer_used_ = false; - context_.DestroyWindow(); - context_.Shutdown(); + context_->DestroyWindow(); + context_->Shutdown(); glslang::FinalizeProcess(); } @@ -1022,8 +1023,8 @@ void RendererVulkan::Shutdown() { void RendererVulkan::BeginFrame() { FreePendingResources(current_frame_); - context_.AppendCommandBuffer(frames_[current_frame_].setup_command_buffer); - context_.AppendCommandBuffer(frames_[current_frame_].draw_command_buffer); + context_->AppendCommandBuffer(frames_[current_frame_].setup_command_buffer); + context_->AppendCommandBuffer(frames_[current_frame_].draw_command_buffer); vkResetCommandPool(device_, frames_[current_frame_].setup_command_pool, 0); vkResetCommandPool(device_, frames_[current_frame_].draw_command_pool, 0); @@ -1062,7 +1063,7 @@ void RendererVulkan::BeginFrame() { void RendererVulkan::FlushSetupBuffer() { vkEndCommandBuffer(frames_[current_frame_].setup_command_buffer); - context_.Flush(false); + context_->Flush(false); vkResetCommandPool(device_, frames_[current_frame_].setup_command_pool, 0); @@ -1078,8 +1079,8 @@ void RendererVulkan::FlushSetupBuffer() { DLOG << "vkBeginCommandBuffer failed with error " << string_VkResult(err); return; } - context_.AppendCommandBuffer(frames_[current_frame_].setup_command_buffer, - true); + context_->AppendCommandBuffer(frames_[current_frame_].setup_command_buffer, + true); } void RendererVulkan::FreePendingResources(int frame) { @@ -1906,8 +1907,8 @@ void RendererVulkan::DrawListBegin() { VkRenderPassBeginInfo render_pass_begin; render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; render_pass_begin.pNext = nullptr; - render_pass_begin.renderPass = context_.GetRenderPass(); - render_pass_begin.framebuffer = context_.GetFramebuffer(); + render_pass_begin.renderPass = context_->GetRenderPass(); + render_pass_begin.framebuffer = context_->GetFramebuffer(); render_pass_begin.renderArea.extent.width = screen_width_; render_pass_begin.renderArea.extent.height = screen_height_; @@ -1973,7 +1974,7 @@ void RendererVulkan::SwapBuffers() { vkEndCommandBuffer(frames_[current_frame_].setup_command_buffer); vkEndCommandBuffer(frames_[current_frame_].draw_command_buffer); - context_.SwapBuffers(); + context_->SwapBuffers(); current_frame_ = (current_frame_ + 1) % frames_.size(); active_pipeline_ = VK_NULL_HANDLE; @@ -2032,13 +2033,13 @@ bool RendererVulkan::SetUniformInternal(ShaderVulkan& shader, bool RendererVulkan::IsFormatSupported(VkFormat format) { VkFormatProperties properties; - vkGetPhysicalDeviceFormatProperties(context_.GetPhysicalDevice(), format, + vkGetPhysicalDeviceFormatProperties(context_->GetPhysicalDevice(), format, &properties); return properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT; } size_t RendererVulkan::GetAndResetFPS() { - return context_.GetAndResetFPS(); + return context_->GetAndResetFPS(); } void RendererVulkan::DestroyAllResources() { diff --git a/src/engine/renderer/vulkan/renderer_vulkan.h b/src/engine/renderer/vulkan/renderer_vulkan.h index bb333fc..2d5fb60 100644 --- a/src/engine/renderer/vulkan/renderer_vulkan.h +++ b/src/engine/renderer/vulkan/renderer_vulkan.h @@ -22,7 +22,7 @@ class Image; class RendererVulkan final : public Renderer { public: - RendererVulkan(); + RendererVulkan(std::unique_ptr context); ~RendererVulkan() final; #if defined(__ANDROID__) @@ -72,6 +72,8 @@ class RendererVulkan final : public Renderer { size_t GetAndResetFPS() final; + const char* GetDebugName() final { return "Vulkan"; } + #if defined(__linux__) && !defined(__ANDROID__) XVisualInfo* GetXVisualInfo(Display* display) final; #endif @@ -154,7 +156,7 @@ class RendererVulkan final : public Renderer { bool context_lost_ = false; - VulkanContext context_; + std::unique_ptr context_; VmaAllocator allocator_ = nullptr; diff --git a/src/engine/renderer/vulkan/renderer_vulkan_android.cc b/src/engine/renderer/vulkan/renderer_vulkan_android.cc index 8106fb4..6f7c2d3 100644 --- a/src/engine/renderer/vulkan/renderer_vulkan_android.cc +++ b/src/engine/renderer/vulkan/renderer_vulkan_android.cc @@ -12,11 +12,7 @@ bool RendererVulkan::Initialize(ANativeWindow* window) { screen_width_ = ANativeWindow_getWidth(window); screen_height_ = ANativeWindow_getHeight(window); - if (!context_.Initialize()) { - LOG << "Failed to initialize Vulkan context."; - return false; - } - if (!context_.CreateWindow(window, screen_width_, screen_height_)) { + if (!context_->CreateWindow(window, screen_width_, screen_height_)) { LOG << "Vulkan context failed to create window."; return false; } diff --git a/src/engine/renderer/vulkan/renderer_vulkan_linux.cc b/src/engine/renderer/vulkan/renderer_vulkan_linux.cc index 4cb66bd..e51c0d6 100644 --- a/src/engine/renderer/vulkan/renderer_vulkan_linux.cc +++ b/src/engine/renderer/vulkan/renderer_vulkan_linux.cc @@ -12,11 +12,7 @@ bool RendererVulkan::Initialize(Display* display, Window window) { screen_width_ = xwa.width; screen_height_ = xwa.height; - if (!context_.Initialize()) { - LOG << "Failed to initialize Vulkan context."; - return false; - } - if (!context_.CreateWindow(display, window, screen_width_, screen_height_)) { + if (!context_->CreateWindow(display, window, screen_width_, screen_height_)) { LOG << "Vulkan context failed to create window."; return false; }