diff --git a/src/citra/citra.cpp b/src/citra/citra.cpp index 7a7ed58a7..7192e41ee 100644 --- a/src/citra/citra.cpp +++ b/src/citra/citra.cpp @@ -7,10 +7,8 @@ #include #include #include - // This needs to be included before getopt.h because the latter #defines symbols used by it #include "common/microprofile.h" - #include "citra/config.h" #include "citra/emu_window/emu_window_sdl2.h" #include "citra/lodepng_image_interface.h" @@ -18,7 +16,6 @@ #include "common/detached_tasks.h" #include "common/file_util.h" #include "common/logging/backend.h" -#include "common/logging/filter.h" #include "common/logging/log.h" #include "common/scm_rev.h" #include "common/scope_exit.h" @@ -26,13 +23,10 @@ #include "common/string_util.h" #include "core/core.h" #include "core/dumping/backend.h" -#include "core/file_sys/cia_container.h" #include "core/frontend/applets/default_applets.h" #include "core/frontend/framebuffer_layout.h" -#include "core/gdbstub/gdbstub.h" #include "core/hle/service/am/am.h" #include "core/hle/service/cfg/cfg.h" -#include "core/loader/loader.h" #include "core/movie.h" #include "input_common/main.h" #include "network/network.h" @@ -47,7 +41,6 @@ #ifdef _WIN32 // windows.h needs to be included before shellapi.h #include - #include extern "C" { diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 8401d40b8..087a508f8 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include "citra_qt/bootmanager.h" @@ -121,8 +120,20 @@ public: /// Create the original context that should be shared from explicit OpenGLSharedContext(QSurface* surface) : surface(surface) { QSurfaceFormat format; - format.setVersion(4, 4); - format.setProfile(QSurfaceFormat::CoreProfile); + + if (Settings::values.graphics_api == Settings::GraphicsAPI::OpenGLES) { + QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); + format.setVersion(3, 2); + } else { + QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL); + format.setVersion(4, 4); + format.setProfile(QSurfaceFormat::CoreProfile); + } + + if (Settings::values.renderer_debug) { + format.setOption(QSurfaceFormat::FormatOption::DebugContext); + } + // TODO: expose a setting for buffer value (ie default/single/double/triple) format.setSwapBehavior(QSurfaceFormat::DefaultSwapBehavior); format.setSwapInterval(0); @@ -637,14 +648,6 @@ bool GRenderWindow::InitializeOpenGL() { child->SetContext( std::make_unique(context->GetShareContext(), child->windowHandle())); - // Check for OpenGL 4.3 support - if (!QOpenGLContext::globalShareContext()->versionFunctions()) { - QMessageBox::critical(this, tr("OpenGL 4.3 Unsupported"), - tr("Your GPU may not support OpenGL 4.3, or you do not " - "have the latest graphics driver.")); - return false; - } - return true; } diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp index 744f6422f..f510a3c3c 100644 --- a/src/citra_qt/configuration/config.cpp +++ b/src/citra_qt/configuration/config.cpp @@ -601,6 +601,7 @@ void Config::ReadPathValues() { void Config::ReadRendererValues() { qt_config->beginGroup(QStringLiteral("Renderer")); + ReadGlobalSetting(Settings::values.graphics_api); ReadGlobalSetting(Settings::values.use_hw_renderer); ReadGlobalSetting(Settings::values.use_hw_shader); #ifdef __APPLE__ @@ -622,6 +623,7 @@ void Config::ReadRendererValues() { ReadGlobalSetting(Settings::values.texture_filter_name); if (global) { + ReadBasicSetting(Settings::values.renderer_debug); ReadBasicSetting(Settings::values.use_shader_jit); } @@ -1077,6 +1079,7 @@ void Config::SavePathValues() { void Config::SaveRendererValues() { qt_config->beginGroup(QStringLiteral("Renderer")); + WriteGlobalSetting(Settings::values.graphics_api); WriteGlobalSetting(Settings::values.use_hw_renderer); WriteGlobalSetting(Settings::values.use_hw_shader); #ifdef __APPLE__ @@ -1097,6 +1100,7 @@ void Config::SaveRendererValues() { WriteGlobalSetting(Settings::values.texture_filter_name); if (global) { + WriteBasicSetting(Settings::values.renderer_debug); WriteSetting(QStringLiteral("use_shader_jit"), Settings::values.use_shader_jit.GetValue(), true); } diff --git a/src/citra_qt/configuration/configure_debug.cpp b/src/citra_qt/configuration/configure_debug.cpp index accc61b65..475d6ab70 100644 --- a/src/citra_qt/configuration/configure_debug.cpp +++ b/src/citra_qt/configuration/configure_debug.cpp @@ -25,6 +25,7 @@ ConfigureDebug::ConfigureDebug(QWidget* parent) const bool is_powered_on = Core::System::GetInstance().IsPoweredOn(); ui->toggle_cpu_jit->setEnabled(!is_powered_on); + ui->toggle_renderer_debug->setEnabled(!is_powered_on); } ConfigureDebug::~ConfigureDebug() = default; @@ -37,6 +38,7 @@ void ConfigureDebug::SetConfiguration() { ui->toggle_console->setChecked(UISettings::values.show_console.GetValue()); ui->log_filter_edit->setText(QString::fromStdString(Settings::values.log_filter.GetValue())); ui->toggle_cpu_jit->setChecked(Settings::values.use_cpu_jit.GetValue()); + ui->toggle_renderer_debug->setChecked(Settings::values.renderer_debug.GetValue()); } void ConfigureDebug::ApplyConfiguration() { @@ -49,6 +51,7 @@ void ConfigureDebug::ApplyConfiguration() { filter.ParseFilterString(Settings::values.log_filter.GetValue()); Log::SetGlobalFilter(filter); Settings::values.use_cpu_jit = ui->toggle_cpu_jit->isChecked(); + Settings::values.renderer_debug = ui->toggle_renderer_debug->isChecked(); } void ConfigureDebug::RetranslateUI() { diff --git a/src/citra_qt/configuration/configure_debug.ui b/src/citra_qt/configuration/configure_debug.ui index 2bf1a5f88..9edcfacaa 100644 --- a/src/citra_qt/configuration/configure_debug.ui +++ b/src/citra_qt/configuration/configure_debug.ui @@ -122,6 +122,16 @@ + + + + <html><head/><body><p>Enables debug reporting in the currently selected graphics API. Causes measurable performance loss, don't enable unless for debugging purposes</p></body></html> + + + Enable debug renderer + + + diff --git a/src/citra_qt/debugger/graphics/graphics_surface.cpp b/src/citra_qt/debugger/graphics/graphics_surface.cpp index b86d4e2d6..31aa544a9 100644 --- a/src/citra_qt/debugger/graphics/graphics_surface.cpp +++ b/src/citra_qt/debugger/graphics/graphics_surface.cpp @@ -16,7 +16,6 @@ #include "citra_qt/util/spinbox.h" #include "common/color.h" #include "core/core.h" -#include "core/hw/gpu.h" #include "core/memory.h" #include "video_core/pica_state.h" #include "video_core/regs_framebuffer.h" diff --git a/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp b/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp index 859a1448b..b0fe1c18d 100644 --- a/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp +++ b/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp @@ -407,8 +407,7 @@ GraphicsVertexShaderWidget::GraphicsVertexShaderWidget( static_cast(&QSignalMapper::map)); input_data_mapper->setMapping(input_data[i], i); } - connect(input_data_mapper, &QSignalMapper::mappedInt, this, - &GraphicsVertexShaderWidget::OnInputAttributeChanged); + connect(input_data_mapper, &QSignalMapper::mappedInt, this, &GraphicsVertexShaderWidget::OnInputAttributeChanged); auto main_widget = new QWidget; auto main_layout = new QVBoxLayout; @@ -515,7 +514,7 @@ void GraphicsVertexShaderWidget::Reload(bool replace_vertex_data, void* vertex_d int num_attributes = shader_config.max_input_attribute_index + 1; for (auto pattern : shader_setup.swizzle_data) { - const nihstro::SwizzleInfo swizzle_info = {.pattern = nihstro::SwizzlePattern{pattern}}; + const nihstro::SwizzleInfo swizzle_info = { .pattern = nihstro::SwizzlePattern{pattern} }; info.swizzle_info.push_back(swizzle_info); } diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index e06adb0da..d8fdb4b3a 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -59,10 +59,7 @@ #include "common/file_util.h" #include "common/literals.h" #include "common/logging/backend.h" -#include "common/logging/filter.h" #include "common/logging/log.h" -#include "common/logging/text_formatter.h" -#include "common/memory_detect.h" #include "common/microprofile.h" #include "common/scm_rev.h" #include "common/scope_exit.h" @@ -76,7 +73,6 @@ #include "core/file_sys/archive_extsavedata.h" #include "core/file_sys/archive_source_sd_savedata.h" #include "core/frontend/applets/default_applets.h" -#include "core/gdbstub/gdbstub.h" #include "core/hle/service/fs/archive.h" #include "core/hle/service/nfc/nfc.h" #include "core/loader/loader.h" @@ -86,7 +82,6 @@ #include "input_common/main.h" #include "network/network_settings.h" #include "ui_main.h" -#include "video_core/renderer_base.h" #include "video_core/video_core.h" #ifdef __APPLE__ diff --git a/src/common/settings.h b/src/common/settings.h index d6a780d3f..5d7ed0ed4 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -446,7 +446,8 @@ struct Values { Setting allow_plugin_loader{true, "allow_plugin_loader"}; // Renderer - SwitchableSetting graphics_api{GraphicsAPI::Vulkan, "graphics_api"}; + SwitchableSetting graphics_api{GraphicsAPI::OpenGL, "graphics_api"}; + Setting renderer_debug{false, "renderer_debug"}; SwitchableSetting use_hw_renderer{true, "use_hw_renderer"}; SwitchableSetting use_hw_shader{true, "use_hw_shader"}; SwitchableSetting separable_shader{false, "use_separable_shader"}; diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp index f7a7754e5..67fa086f1 100644 --- a/src/core/telemetry_session.cpp +++ b/src/core/telemetry_session.cpp @@ -3,8 +3,6 @@ // Refer to the license.txt file included. #include - -#include "common/assert.h" #include "common/common_types.h" #include "common/file_util.h" #include "common/logging/log.h" diff --git a/src/video_core/renderer_opengl/gl_driver.cpp b/src/video_core/renderer_opengl/gl_driver.cpp index 83dd57718..14d6c7064 100644 --- a/src/video_core/renderer_opengl/gl_driver.cpp +++ b/src/video_core/renderer_opengl/gl_driver.cpp @@ -69,7 +69,7 @@ static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum id, message); } -Driver::Driver(bool gles) : is_gles{gles} { +Driver::Driver(bool gles, bool enable_debug) : is_gles{gles} { #ifndef ANDROID if (!gladLoadGL()) { return; @@ -79,8 +79,10 @@ Driver::Driver(bool gles) : is_gles{gles} { * Qualcomm has some spammy info messages that are marked as errors but not important * https://developer.qualcomm.com/comment/11845 */ - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); - glDebugMessageCallback(DebugHandler, nullptr); + if (enable_debug) { + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + glDebugMessageCallback(DebugHandler, nullptr); + } #endif ReportDriverInfo(); diff --git a/src/video_core/renderer_opengl/gl_driver.h b/src/video_core/renderer_opengl/gl_driver.h index 0fa18e600..b8d491b7e 100644 --- a/src/video_core/renderer_opengl/gl_driver.h +++ b/src/video_core/renderer_opengl/gl_driver.h @@ -33,31 +33,37 @@ enum class DriverBug { */ class Driver { public: - Driver(bool gles); + Driver(bool gles, bool enable_debug); /// Returns true of the driver has a particular bug stated in the DriverBug enum bool HasBug(DriverBug bug) const; + /// Returns the vendor of the currently selected physical device Vendor GetVendor() const { return vendor; } + /// Returns true if the current context is ES compatible bool IsOpenGLES() const { return is_gles; } + /// Returns true if the implementation supports ARB_buffer_storage bool HasArbBufferStorage() const { return arb_buffer_storage; } + /// Returns true if the implementation supports EXT_buffer_storage bool HasExtBufferStorage() const { return ext_buffer_storage; } + /// Returns true if the implementation supports EXT_clip_cull_distance bool HasExtClipCullDistance() const { return ext_clip_cull_distance; } + /// Returns true if the implementation supports ARB_direct_state_access bool HasArbDirectStateAccess() const { return arb_direct_state_access; } diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 3f7910b7a..eebc08c8f 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -353,7 +353,8 @@ static std::array MakeOrthographicMatrix(const float width, cons } RendererOpenGL::RendererOpenGL(Frontend::EmuWindow& window, Frontend::EmuWindow* secondary_window) - : RendererBase{window, secondary_window}, driver{Settings::values.graphics_api == Settings::GraphicsAPI::OpenGLES}, + : RendererBase{window, secondary_window}, driver{Settings::values.graphics_api == Settings::GraphicsAPI::OpenGLES, + Settings::values.renderer_debug}, frame_dumper(Core::System::GetInstance().VideoDumper(), window) { window.mailbox = std::make_unique(); if (secondary_window) { diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index f8537e606..18b2a2e26 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -183,8 +183,9 @@ static std::array MakeOrthographicMatrix(float width, float height } RendererVulkan::RendererVulkan(Frontend::EmuWindow& window) - : RendererBase{window}, instance{window}, scheduler{instance, *this}, renderpass_cache{instance, scheduler}, - runtime{instance, scheduler, renderpass_cache}, swapchain{instance, renderpass_cache}, + : RendererBase{window}, instance{window, Settings::values.renderer_debug}, scheduler{instance, *this}, + renderpass_cache{instance, scheduler}, runtime{instance, scheduler, renderpass_cache}, + swapchain{instance, renderpass_cache}, vertex_buffer{instance, scheduler, VERTEX_BUFFER_SIZE, vk::BufferUsageFlagBits::eVertexBuffer, {}} { auto& telemetry_session = Core::System::GetInstance().TelemetrySession(); diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index 8c9a72a97..9c7172852 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -38,7 +38,7 @@ vk::Format ToVkFormat(VideoCore::PixelFormat format) { } } -Instance::Instance(Frontend::EmuWindow& window) { +Instance::Instance(Frontend::EmuWindow& window, bool enable_validation) { auto window_info = window.GetWindowInfo(); // Fetch instance independant function pointers @@ -64,9 +64,10 @@ Instance::Instance(Frontend::EmuWindow& window) { }; const std::array layers = {"VK_LAYER_KHRONOS_validation"}; + const u32 layer_count = enable_validation ? 1u : 0u; const vk::InstanceCreateInfo instance_info = { .pApplicationInfo = &application_info, - .enabledLayerCount = static_cast(layers.size()), + .enabledLayerCount = layer_count, .ppEnabledLayerNames = layers.data(), .enabledExtensionCount = static_cast(extensions.size()), .ppEnabledExtensionNames = extensions.data() diff --git a/src/video_core/renderer_vulkan/vk_instance.h b/src/video_core/renderer_vulkan/vk_instance.h index fec584608..f5476c7fe 100644 --- a/src/video_core/renderer_vulkan/vk_instance.h +++ b/src/video_core/renderer_vulkan/vk_instance.h @@ -27,7 +27,7 @@ struct FormatTraits { /// The global Vulkan instance class Instance { public: - Instance(Frontend::EmuWindow& window); + Instance(Frontend::EmuWindow& window, bool enable_validation); ~Instance(); /// Returns the FormatTraits struct for the provided pixel format