diff --git a/src/citra/citra.cpp b/src/citra/citra.cpp index ebb0726cc..c78a19dfd 100644 --- a/src/citra/citra.cpp +++ b/src/citra/citra.cpp @@ -8,7 +8,6 @@ #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" @@ -17,6 +16,7 @@ #include "common/file_util.h" #include "common/logging/backend.h" #include "common/logging/log.h" +#include "common/microprofile.h" #include "common/scm_rev.h" #include "common/scope_exit.h" #include "core/core.h" diff --git a/src/citra/config.cpp b/src/citra/config.cpp index a62e033c2..eee5bd8c3 100644 --- a/src/citra/config.cpp +++ b/src/citra/config.cpp @@ -110,7 +110,7 @@ void Config::ReadValues() { // Renderer Settings::values.graphics_api = - static_cast(sdl2_config->GetInteger("Renderer", "graphics_api", 0)); + static_cast(sdl2_config->GetInteger("Renderer", "graphics_api", 0)); Settings::values.use_hw_renderer = sdl2_config->GetBoolean("Renderer", "use_hw_renderer", true); Settings::values.use_hw_shader = sdl2_config->GetBoolean("Renderer", "use_hw_shader", true); #ifdef __APPLE__ diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index df40dab6b..c967b1478 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -545,7 +545,7 @@ void GRenderWindow::resizeEvent(QResizeEvent* event) { std::unique_ptr GRenderWindow::CreateSharedContext() const { const Settings::GraphicsAPI graphics_api = Settings::values.graphics_api; if (graphics_api == Settings::GraphicsAPI::OpenGL || - graphics_api == Settings::GraphicsAPI::OpenGLES) { + graphics_api == Settings::GraphicsAPI::OpenGLES) { auto c = static_cast(main_context.get()); // Bind the shared contexts to the main surface in case the backend wants to take over // presentation diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp index a802283f3..79e670fb4 100644 --- a/src/citra_qt/configuration/config.cpp +++ b/src/citra_qt/configuration/config.cpp @@ -484,7 +484,7 @@ void Config::ReadRendererValues() { Settings::values.graphics_api = static_cast( ReadSetting(QStringLiteral("graphics_api"), static_cast(Settings::GraphicsAPI::OpenGL)) - .toUInt()); + .toUInt()); Settings::values.physical_device = ReadSetting(QStringLiteral("physical_device"), 0).toUInt(); Settings::values.renderer_debug = ReadSetting(QStringLiteral("renderer_debug"), false).toBool(); Settings::values.use_hw_renderer = diff --git a/src/citra_qt/configuration/configure_camera.cpp b/src/citra_qt/configuration/configure_camera.cpp index 036959e60..1eb0c2604 100644 --- a/src/citra_qt/configuration/configure_camera.cpp +++ b/src/citra_qt/configuration/configure_camera.cpp @@ -98,11 +98,10 @@ void ConfigureCamera::ConnectEvents() { } }); connect(ui->camera_file, &QLineEdit::textChanged, this, [this] { StopPreviewing(); }); - connect(ui->system_camera, - qOverload(&QComboBox::currentIndexChanged), this, + connect(ui->system_camera, qOverload(&QComboBox::currentIndexChanged), this, + [this] { StopPreviewing(); }); + connect(ui->camera_flip, qOverload(&QComboBox::currentIndexChanged), this, [this] { StopPreviewing(); }); - connect(ui->camera_flip, qOverload(&QComboBox::currentIndexChanged), - this, [this] { StopPreviewing(); }); } void ConfigureCamera::UpdateCameraMode() { diff --git a/src/citra_qt/configuration/configure_graphics.cpp b/src/citra_qt/configuration/configure_graphics.cpp index ea4132c6a..d357c7024 100644 --- a/src/citra_qt/configuration/configure_graphics.cpp +++ b/src/citra_qt/configuration/configure_graphics.cpp @@ -92,7 +92,8 @@ void ConfigureGraphics::ApplyConfiguration() { Settings::values.use_shader_jit = ui->toggle_shader_jit->isChecked(); Settings::values.use_disk_shader_cache = ui->toggle_disk_shader_cache->isChecked(); Settings::values.use_vsync_new = ui->toggle_vsync_new->isChecked(); - Settings::values.graphics_api = static_cast(ui->graphics_api_combo->currentIndex()); + Settings::values.graphics_api = + static_cast(ui->graphics_api_combo->currentIndex()); Settings::values.physical_device = static_cast(ui->physical_device_combo->currentIndex()); } diff --git a/src/citra_qt/configuration/configure_input.cpp b/src/citra_qt/configuration/configure_input.cpp index 94f23129e..be89eee76 100644 --- a/src/citra_qt/configuration/configure_input.cpp +++ b/src/citra_qt/configuration/configure_input.cpp @@ -207,7 +207,7 @@ ConfigureInput::ConfigureInput(QWidget* parent) connect(button_map[button_id], &QPushButton::customContextMenuRequested, this, [this, button_id](const QPoint& menu_location) { QMenu context_menu; - context_menu.addAction(tr("Clear"), this, [&] { + context_menu.addAction(tr("Clear"), this, [&] { buttons_param[button_id].Clear(); button_map[button_id]->setText(tr("[not set]")); ApplyConfiguration(); @@ -230,19 +230,21 @@ ConfigureInput::ConfigureInput(QWidget* parent) continue; analog_map_buttons[analog_id][sub_button_id]->setContextMenuPolicy( Qt::CustomContextMenu); - connect(analog_map_buttons[analog_id][sub_button_id], &QPushButton::clicked, this, [this, analog_id, sub_button_id]() { - HandleClick( - analog_map_buttons[analog_id][sub_button_id], - [this, analog_id, sub_button_id](const Common::ParamPackage& params) { - SetAnalogButton(params, analogs_param[analog_id], - analog_sub_buttons[sub_button_id]); - ApplyConfiguration(); - Settings::SaveProfile(ui->profile->currentIndex()); - }, - InputCommon::Polling::DeviceType::Button); - }); + connect(analog_map_buttons[analog_id][sub_button_id], &QPushButton::clicked, this, + [this, analog_id, sub_button_id]() { + HandleClick( + analog_map_buttons[analog_id][sub_button_id], + [this, analog_id, sub_button_id](const Common::ParamPackage& params) { + SetAnalogButton(params, analogs_param[analog_id], + analog_sub_buttons[sub_button_id]); + ApplyConfiguration(); + Settings::SaveProfile(ui->profile->currentIndex()); + }, + InputCommon::Polling::DeviceType::Button); + }); connect(analog_map_buttons[analog_id][sub_button_id], - &QPushButton::customContextMenuRequested, this, [this, analog_id, sub_button_id](const QPoint& menu_location) { + &QPushButton::customContextMenuRequested, this, + [this, analog_id, sub_button_id](const QPoint& menu_location) { QMenu context_menu; context_menu.addAction(tr("Clear"), this, [&] { analogs_param[analog_id].Erase(analog_sub_buttons[sub_button_id]); @@ -280,21 +282,23 @@ ConfigureInput::ConfigureInput(QWidget* parent) InputCommon::Polling::DeviceType::Analog); } }); - connect(analog_map_deadzone_and_modifier_slider[analog_id], &QSlider::valueChanged, this, [this, analog_id] { - const int slider_value = analog_map_deadzone_and_modifier_slider[analog_id]->value(); - const auto engine = analogs_param[analog_id].Get("engine", ""); - if (engine == "sdl" || engine == "gcpad") { - analog_map_deadzone_and_modifier_slider_label[analog_id]->setText( - tr("Deadzone: %1%").arg(slider_value)); - analogs_param[analog_id].Set("deadzone", slider_value / 100.0f); - } else { - analog_map_deadzone_and_modifier_slider_label[analog_id]->setText( - tr("Modifier Scale: %1%").arg(slider_value)); - analogs_param[analog_id].Set("modifier_scale", slider_value / 100.0f); - } - ApplyConfiguration(); - Settings::SaveProfile(ui->profile->currentIndex()); - }); + connect(analog_map_deadzone_and_modifier_slider[analog_id], &QSlider::valueChanged, this, + [this, analog_id] { + const int slider_value = + analog_map_deadzone_and_modifier_slider[analog_id]->value(); + const auto engine = analogs_param[analog_id].Get("engine", ""); + if (engine == "sdl" || engine == "gcpad") { + analog_map_deadzone_and_modifier_slider_label[analog_id]->setText( + tr("Deadzone: %1%").arg(slider_value)); + analogs_param[analog_id].Set("deadzone", slider_value / 100.0f); + } else { + analog_map_deadzone_and_modifier_slider_label[analog_id]->setText( + tr("Modifier Scale: %1%").arg(slider_value)); + analogs_param[analog_id].Set("modifier_scale", slider_value / 100.0f); + } + ApplyConfiguration(); + Settings::SaveProfile(ui->profile->currentIndex()); + }); } // The Circle Mod button is common for both the sticks, so update the modifier settings @@ -356,13 +360,12 @@ ConfigureInput::ConfigureInput(QWidget* parent) connect(ui->buttonDelete, &QPushButton::clicked, this, &ConfigureInput::DeleteProfile); connect(ui->buttonRename, &QPushButton::clicked, this, &ConfigureInput::RenameProfile); - connect(ui->profile, qOverload(&QComboBox::currentIndexChanged), this, - [this](int i) { - ApplyConfiguration(); - Settings::SaveProfile(Settings::values.current_input_profile_index); - Settings::LoadProfile(i); - LoadConfiguration(); - }); + connect(ui->profile, qOverload(&QComboBox::currentIndexChanged), this, [this](int i) { + ApplyConfiguration(); + Settings::SaveProfile(Settings::values.current_input_profile_index); + Settings::LoadProfile(i); + LoadConfiguration(); + }); timeout_timer->setSingleShot(true); connect(timeout_timer.get(), &QTimer::timeout, this, [this]() { SetPollingResult({}, true); }); diff --git a/src/citra_qt/debugger/graphics/graphics_surface.cpp b/src/citra_qt/debugger/graphics/graphics_surface.cpp index 8a14af6cd..0a86d753d 100644 --- a/src/citra_qt/debugger/graphics/graphics_surface.cpp +++ b/src/citra_qt/debugger/graphics/graphics_surface.cpp @@ -316,56 +316,46 @@ void GraphicsSurfaceWidget::Pick(int x, int y) { case Format::RGBA8: { auto value = Color::DecodeRGBA8(pixel) / 255.0f; return QStringLiteral("Red: %1, Green: %2, Blue: %3, Alpha: %4") - .arg(QString::number(value.r(), 'f', 2), - QString::number(value.g(), 'f', 2), - QString::number(value.b(), 'f', 2), - QString::number(value.a(), 'f', 2)); + .arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2), + QString::number(value.b(), 'f', 2), QString::number(value.a(), 'f', 2)); } case Format::RGB8: { auto value = Color::DecodeRGB8(pixel) / 255.0f; return QStringLiteral("Red: %1, Green: %2, Blue: %3") - .arg(QString::number(value.r(), 'f', 2), - QString::number(value.g(), 'f', 2), + .arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2), QString::number(value.b(), 'f', 2)); } case Format::RGB5A1: { auto value = Color::DecodeRGB5A1(pixel) / 255.0f; return QStringLiteral("Red: %1, Green: %2, Blue: %3, Alpha: %4") - .arg(QString::number(value.r(), 'f', 2), - QString::number(value.g(), 'f', 2), - QString::number(value.b(), 'f', 2), - QString::number(value.a(), 'f', 2)); + .arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2), + QString::number(value.b(), 'f', 2), QString::number(value.a(), 'f', 2)); } case Format::RGB565: { auto value = Color::DecodeRGB565(pixel) / 255.0f; return QStringLiteral("Red: %1, Green: %2, Blue: %3") - .arg(QString::number(value.r(), 'f', 2), - QString::number(value.g(), 'f', 2), + .arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2), QString::number(value.b(), 'f', 2)); } case Format::RGBA4: { auto value = Color::DecodeRGBA4(pixel) / 255.0f; return QStringLiteral("Red: %1, Green: %2, Blue: %3, Alpha: %4") - .arg(QString::number(value.r(), 'f', 2), - QString::number(value.g(), 'f', 2), - QString::number(value.b(), 'f', 2), - QString::number(value.a(), 'f', 2)); + .arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2), + QString::number(value.b(), 'f', 2), QString::number(value.a(), 'f', 2)); } case Format::IA8: return QStringLiteral("Index: %1, Alpha: %2").arg(pixel[0], pixel[1]); case Format::RG8: { auto value = Color::DecodeRG8(pixel) / 255.0f; return QStringLiteral("Red: %1, Green: %2") - .arg(QString::number(value.r(), 'f', 2), - QString::number(value.g(), 'f', 2)); + .arg(QString::number(value.r(), 'f', 2), QString::number(value.g(), 'f', 2)); } case Format::I8: return QStringLiteral("Index: %1").arg(*pixel); case Format::A8: return QStringLiteral("Alpha: %1").arg(QString::number(*pixel / 255.0f, 'f', 2)); case Format::IA4: - return QStringLiteral("Index: %1, Alpha: %2") - .arg(*pixel & 0xF, (*pixel & 0xF0) >> 4); + return QStringLiteral("Index: %1, Alpha: %2").arg(*pixel & 0xF, (*pixel & 0xF0) >> 4); case Format::I4: { u8 i = (*pixel >> ((offset % 2) ? 4 : 0)) & 0xF; return QStringLiteral("Index: %1").arg(i); diff --git a/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp b/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp index b0fe1c18d..859a1448b 100644 --- a/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp +++ b/src/citra_qt/debugger/graphics/graphics_vertex_shader.cpp @@ -407,7 +407,8 @@ 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; @@ -514,7 +515,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/debugger/profiler.cpp b/src/citra_qt/debugger/profiler.cpp index 45e3aacb9..9f394a020 100644 --- a/src/citra_qt/debugger/profiler.cpp +++ b/src/citra_qt/debugger/profiler.cpp @@ -160,7 +160,8 @@ void MicroProfileWidget::mouseReleaseEvent(QMouseEvent* event) { } void MicroProfileWidget::wheelEvent(QWheelEvent* event) { - MicroProfileMousePosition(event->position().x() / x_scale, event->position().y() / y_scale, event->angleDelta().y() / 120); + MicroProfileMousePosition(event->position().x() / x_scale, event->position().y() / y_scale, + event->angleDelta().y() / 120); event->accept(); } diff --git a/src/citra_qt/game_list.cpp b/src/citra_qt/game_list.cpp index 95552c76f..43c6eaa78 100644 --- a/src/citra_qt/game_list.cpp +++ b/src/citra_qt/game_list.cpp @@ -169,8 +169,7 @@ GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} { * @return true if the haystack contains all words of userinput */ static bool ContainsAllWords(const QString& haystack, const QString& userinput) { - const QStringList userinput_split = - userinput.split(QLatin1Char{' '}, Qt::SkipEmptyParts); + const QStringList userinput_split = userinput.split(QLatin1Char{' '}, Qt::SkipEmptyParts); return std::all_of(userinput_split.begin(), userinput_split.end(), [&haystack](const QString& s) { return haystack.contains(s); }); diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 92ea7b21b..ba2a2a28e 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -146,7 +146,9 @@ static void InitializeLogging() { #endif } -GMainWindow::GMainWindow() : ui{std::make_unique()}, config{std::make_unique()}, emu_thread{nullptr} { +GMainWindow::GMainWindow() + : ui{std::make_unique()}, config{std::make_unique()}, emu_thread{ + nullptr} { InitializeLogging(); Debugger::ToggleConsole(); Settings::LogSettings(); @@ -2112,27 +2114,20 @@ void GMainWindow::ShowMouseCursor() { } void GMainWindow::UpdateAPIIndicator(bool override) { - static std::array graphics_apis = { - QStringLiteral("OPENGL"), - QStringLiteral("OPENGLES"), - QStringLiteral("VULKAN") - }; + static std::array graphics_apis = {QStringLiteral("OPENGL"), QStringLiteral("OPENGLES"), + QStringLiteral("VULKAN")}; - static std::array graphics_api_colors = { - QStringLiteral("#00ccdd"), - QStringLiteral("#ba2a8d"), - QStringLiteral("#91242a") - }; + static std::array graphics_api_colors = {QStringLiteral("#00ccdd"), QStringLiteral("#ba2a8d"), + QStringLiteral("#91242a")}; u32 api_index = static_cast(Settings::values.graphics_api); if (override) { api_index = (api_index + 1) % graphics_apis.size(); - Settings::values.graphics_api = - static_cast(api_index); + Settings::values.graphics_api = static_cast(api_index); } - const QString style_sheet = - QStringLiteral("QPushButton { font-weight: bold; color: %0; }").arg(graphics_api_colors[api_index]); + const QString style_sheet = QStringLiteral("QPushButton { font-weight: bold; color: %0; }") + .arg(graphics_api_colors[api_index]); graphics_api_button->setText(graphics_apis[api_index]); graphics_api_button->setStyleSheet(style_sheet); diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h index 483476cc1..ffa26c424 100644 --- a/src/citra_qt/main.h +++ b/src/citra_qt/main.h @@ -7,9 +7,9 @@ #include #include #include +#include #include #include -#include #include "citra_qt/compatibility_list.h" #include "citra_qt/hotkeys.h" #include "common/announce_multiplayer_room.h" diff --git a/src/common/hash.h b/src/common/hash.h index 44da9e25d..d1f073e9b 100644 --- a/src/common/hash.h +++ b/src/common/hash.h @@ -4,9 +4,9 @@ #pragma once +#include #include #include -#include #include "common/cityhash.h" #include "common/common_types.h" diff --git a/src/common/logging/formatter.h b/src/common/logging/formatter.h index 3d4d70902..ad6adb143 100644 --- a/src/common/logging/formatter.h +++ b/src/common/logging/formatter.h @@ -4,8 +4,8 @@ #pragma once -#include #include +#include // adapted from https://github.com/fmtlib/fmt/issues/2704 // a generic formatter for enum classes diff --git a/src/common/math_util.h b/src/common/math_util.h index 623f7f39b..c42f45fe5 100644 --- a/src/common/math_util.h +++ b/src/common/math_util.h @@ -4,8 +4,8 @@ #pragma once -#include #include +#include #include namespace Common { diff --git a/src/common/memory_ref.h b/src/common/memory_ref.h index 04002d6a2..083193ec4 100644 --- a/src/common/memory_ref.h +++ b/src/common/memory_ref.h @@ -3,8 +3,8 @@ // Refer to the license.txt file included. #pragma once -#include #include +#include #include #include #include diff --git a/src/core/arm/dyncom/arm_dyncom_trans.cpp b/src/core/arm/dyncom/arm_dyncom_trans.cpp index 77dafbac7..729c40797 100644 --- a/src/core/arm/dyncom/arm_dyncom_trans.cpp +++ b/src/core/arm/dyncom/arm_dyncom_trans.cpp @@ -63,7 +63,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index) { return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index) { +static ARM_INST_PTR INTERPRETER_TRANSLATE (and)(unsigned int inst, int index) { arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst)); and_inst* inst_cream = (and_inst*)inst_base->component; diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index a37c5f905..c7203771a 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp @@ -851,7 +851,7 @@ static void ReadMemory() { auto& memory = Core::System::GetInstance().Memory(); if (!memory.IsValidVirtualAddress(*Core::System::GetInstance().Kernel().GetCurrentProcess(), - addr)) { + addr)) { return SendReply("E00"); } @@ -875,7 +875,7 @@ static void WriteMemory() { auto& memory = Core::System::GetInstance().Memory(); if (!memory.IsValidVirtualAddress(*Core::System::GetInstance().Kernel().GetCurrentProcess(), - addr)) { + addr)) { return SendReply("E00"); } diff --git a/src/core/hle/kernel/ipc.cpp b/src/core/hle/kernel/ipc.cpp index 8687c22ba..8138002fc 100644 --- a/src/core/hle/kernel/ipc.cpp +++ b/src/core/hle/kernel/ipc.cpp @@ -140,8 +140,8 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy VAddr page_start = Common::AlignDown(source_address, Memory::CITRA_PAGE_SIZE); u32 page_offset = source_address - page_start; - u32 num_pages = - Common::AlignUp(page_offset + size, Memory::CITRA_PAGE_SIZE) >> Memory::CITRA_PAGE_BITS; + u32 num_pages = Common::AlignUp(page_offset + size, Memory::CITRA_PAGE_SIZE) >> + Memory::CITRA_PAGE_BITS; // Skip when the size is zero and num_pages == 0 if (size == 0) { @@ -180,8 +180,9 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy next_vma.meminfo_state == MemoryState::Reserved); // Unmap the buffer and guard pages from the source process - ResultCode result = src_process->vm_manager.UnmapRange( - page_start - Memory::CITRA_PAGE_SIZE, (num_pages + 2) * Memory::CITRA_PAGE_SIZE); + ResultCode result = + src_process->vm_manager.UnmapRange(page_start - Memory::CITRA_PAGE_SIZE, + (num_pages + 2) * Memory::CITRA_PAGE_SIZE); ASSERT(result == RESULT_SUCCESS); mapped_buffer_context.erase(found); diff --git a/src/core/hle/service/apt/applet_manager.cpp b/src/core/hle/service/apt/applet_manager.cpp index d59980720..6416d3b16 100644 --- a/src/core/hle/service/apt/applet_manager.cpp +++ b/src/core/hle/service/apt/applet_manager.cpp @@ -26,47 +26,66 @@ struct AppletTitleData { static constexpr std::size_t NumApplets = 29; static constexpr std::array applet_titleids = {{ - {{AppletId::HomeMenu, AppletId::None}, {0x4003000008202, 0x4003000008F02, 0x4003000009802, - 0x4003000008202, 0x400300000A102, 0x400300000A902, 0x400300000B102}}, - {{AppletId::AlternateMenu, AppletId::None}, {0x4003000008102, 0x4003000008102, 0x4003000008102, - 0x4003000008102, 0x4003000008102, 0x4003000008102, 0x4003000008102}}, - {{AppletId::Camera, AppletId::None}, {0x4003000008402, 0x4003000009002, 0x4003000009902, - 0x4003000008402, 0x400300000A202, 0x400300000AA02, 0x400300000B202}}, - {{AppletId::FriendList, AppletId::None}, {0x4003000008D02, 0x4003000009602, 0x4003000009F02, - 0x4003000008D02, 0x400300000A702, 0x400300000AF02, 0x400300000B702}}, - {{AppletId::GameNotes, AppletId::None}, {0x4003000008702, 0x4003000009302, 0x4003000009C02, - 0x4003000008702, 0x400300000A502, 0x400300000AD02, 0x400300000B502}}, - {{AppletId::InternetBrowser, AppletId::None}, {0x4003000008802, 0x4003000009402, 0x4003000009D02, - 0x4003000008802, 0x400300000A602, 0x400300000AE02, 0x400300000B602}}, - {{AppletId::InstructionManual, AppletId::None}, {0x4003000008602, 0x4003000009202, 0x4003000009B02, - 0x4003000008602, 0x400300000A402, 0x400300000AC02, 0x400300000B402}}, - {{AppletId::Notifications, AppletId::None}, {0x4003000008E02, 0x4003000009702, 0x400300000A002, - 0x4003000008E02, 0x400300000A802, 0x400300000B002, 0x400300000B802}}, - {{AppletId::Miiverse, AppletId::None}, {0x400300000BC02, 0x400300000BD02, 0x400300000BE02, - 0x400300000BC02, 0x4003000009E02, 0x4003000009502, 0x400300000B902}}, + {{AppletId::HomeMenu, AppletId::None}, + {0x4003000008202, 0x4003000008F02, 0x4003000009802, 0x4003000008202, 0x400300000A102, + 0x400300000A902, 0x400300000B102}}, + {{AppletId::AlternateMenu, AppletId::None}, + {0x4003000008102, 0x4003000008102, 0x4003000008102, 0x4003000008102, 0x4003000008102, + 0x4003000008102, 0x4003000008102}}, + {{AppletId::Camera, AppletId::None}, + {0x4003000008402, 0x4003000009002, 0x4003000009902, 0x4003000008402, 0x400300000A202, + 0x400300000AA02, 0x400300000B202}}, + {{AppletId::FriendList, AppletId::None}, + {0x4003000008D02, 0x4003000009602, 0x4003000009F02, 0x4003000008D02, 0x400300000A702, + 0x400300000AF02, 0x400300000B702}}, + {{AppletId::GameNotes, AppletId::None}, + {0x4003000008702, 0x4003000009302, 0x4003000009C02, 0x4003000008702, 0x400300000A502, + 0x400300000AD02, 0x400300000B502}}, + {{AppletId::InternetBrowser, AppletId::None}, + {0x4003000008802, 0x4003000009402, 0x4003000009D02, 0x4003000008802, 0x400300000A602, + 0x400300000AE02, 0x400300000B602}}, + {{AppletId::InstructionManual, AppletId::None}, + {0x4003000008602, 0x4003000009202, 0x4003000009B02, 0x4003000008602, 0x400300000A402, + 0x400300000AC02, 0x400300000B402}}, + {{AppletId::Notifications, AppletId::None}, + {0x4003000008E02, 0x4003000009702, 0x400300000A002, 0x4003000008E02, 0x400300000A802, + 0x400300000B002, 0x400300000B802}}, + {{AppletId::Miiverse, AppletId::None}, + {0x400300000BC02, 0x400300000BD02, 0x400300000BE02, 0x400300000BC02, 0x4003000009E02, + 0x4003000009502, 0x400300000B902}}, // These values obtained from an older NS dump firmware 4.5 - {{AppletId::MiiversePost, AppletId::None}, {0x400300000BA02, 0x400300000BA02, 0x400300000BA02, - 0x400300000BA02, 0x400300000BA02, 0x400300000BA02, 0x400300000BA02}}, + {{AppletId::MiiversePost, AppletId::None}, + {0x400300000BA02, 0x400300000BA02, 0x400300000BA02, 0x400300000BA02, 0x400300000BA02, + 0x400300000BA02, 0x400300000BA02}}, // {AppletId::MiiversePost, AppletId::None, 0x4003000008302, 0x4003000008B02, 0x400300000BA02, // 0x4003000008302, 0x0, 0x0, 0x0}, - {{AppletId::AmiiboSettings, AppletId::None}, {0x4003000009502, 0x4003000009E02, 0x400300000B902, - 0x4003000009502, 0x0, 0x4003000008C02, 0x400300000BF02}}, - {{AppletId::SoftwareKeyboard1, AppletId::SoftwareKeyboard2}, {0x400300000C002, 0x400300000C802, - 0x400300000D002, 0x400300000C002, 0x400300000D802, 0x400300000DE02, 0x400300000E402}}, - {{AppletId::Ed1, AppletId::Ed2}, {0x400300000C102, 0x400300000C902, 0x400300000D102, - 0x400300000C102, 0x400300000D902, 0x400300000DF02, 0x400300000E502}}, - {{AppletId::PnoteApp, AppletId::PnoteApp2}, {0x400300000C302, 0x400300000CB02, 0x400300000D302, - 0x400300000C302, 0x400300000DB02, 0x400300000E102, 0x400300000E702}}, - {{AppletId::SnoteApp, AppletId::SnoteApp2}, {0x400300000C402, 0x400300000CC02, 0x400300000D402, - 0x400300000C402, 0x400300000DC02, 0x400300000E202, 0x400300000E802}}, - {{AppletId::Error, AppletId::Error2}, {0x400300000C502, 0x400300000C502, 0x400300000C502, - 0x400300000C502, 0x400300000CF02, 0x400300000CF02, 0x400300000CF02}}, - {{AppletId::Mint, AppletId::Mint2}, {0x400300000C602, 0x400300000CE02, 0x400300000D602, - 0x400300000C602, 0x400300000DD02, 0x400300000E302, 0x400300000E902}}, - {{AppletId::Extrapad, AppletId::Extrapad2}, {0x400300000CD02, 0x400300000CD02, 0x400300000CD02, - 0x400300000CD02, 0x400300000D502, 0x400300000D502, 0x400300000D502}}, - {{AppletId::Memolib, AppletId::Memolib2}, {0x400300000F602, 0x400300000F602, 0x400300000F602, - 0x400300000F602, 0x400300000F602, 0x400300000F602, 0x400300000F602}}, + {{AppletId::AmiiboSettings, AppletId::None}, + {0x4003000009502, 0x4003000009E02, 0x400300000B902, 0x4003000009502, 0x0, 0x4003000008C02, + 0x400300000BF02}}, + {{AppletId::SoftwareKeyboard1, AppletId::SoftwareKeyboard2}, + {0x400300000C002, 0x400300000C802, 0x400300000D002, 0x400300000C002, 0x400300000D802, + 0x400300000DE02, 0x400300000E402}}, + {{AppletId::Ed1, AppletId::Ed2}, + {0x400300000C102, 0x400300000C902, 0x400300000D102, 0x400300000C102, 0x400300000D902, + 0x400300000DF02, 0x400300000E502}}, + {{AppletId::PnoteApp, AppletId::PnoteApp2}, + {0x400300000C302, 0x400300000CB02, 0x400300000D302, 0x400300000C302, 0x400300000DB02, + 0x400300000E102, 0x400300000E702}}, + {{AppletId::SnoteApp, AppletId::SnoteApp2}, + {0x400300000C402, 0x400300000CC02, 0x400300000D402, 0x400300000C402, 0x400300000DC02, + 0x400300000E202, 0x400300000E802}}, + {{AppletId::Error, AppletId::Error2}, + {0x400300000C502, 0x400300000C502, 0x400300000C502, 0x400300000C502, 0x400300000CF02, + 0x400300000CF02, 0x400300000CF02}}, + {{AppletId::Mint, AppletId::Mint2}, + {0x400300000C602, 0x400300000CE02, 0x400300000D602, 0x400300000C602, 0x400300000DD02, + 0x400300000E302, 0x400300000E902}}, + {{AppletId::Extrapad, AppletId::Extrapad2}, + {0x400300000CD02, 0x400300000CD02, 0x400300000CD02, 0x400300000CD02, 0x400300000D502, + 0x400300000D502, 0x400300000D502}}, + {{AppletId::Memolib, AppletId::Memolib2}, + {0x400300000F602, 0x400300000F602, 0x400300000F602, 0x400300000F602, 0x400300000F602, + 0x400300000F602, 0x400300000F602}}, // TODO(Subv): Fill in the rest of the titleids }}; diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index 24f9143af..e376120a7 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp @@ -111,7 +111,8 @@ ResultStatus AppLoader_NCCH::LoadExec(std::shared_ptr& process) codeset->RODataSegment().offset + codeset->RODataSegment().size; codeset->DataSegment().addr = overlay_ncch->exheader_header.codeset_info.data.address; codeset->DataSegment().size = - overlay_ncch->exheader_header.codeset_info.data.num_max_pages * Memory::CITRA_PAGE_SIZE + + overlay_ncch->exheader_header.codeset_info.data.num_max_pages * + Memory::CITRA_PAGE_SIZE + bss_page_size; // Apply patches now that the entire codeset (including .bss) has been allocated diff --git a/src/core/memory.cpp b/src/core/memory.cpp index f82b77976..1bdb755d0 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -143,7 +143,8 @@ public: } void WalkBlock(const Kernel::Process& process, const VAddr src_addr, const std::size_t size, - auto on_unmapped, auto on_memory, auto on_special, auto on_rasterizer, auto increment) { + auto on_unmapped, auto on_memory, auto on_special, auto on_rasterizer, + auto increment) { auto& page_table = *process.vm_manager.page_table; std::size_t remaining_size = size; @@ -152,7 +153,8 @@ public: while (remaining_size > 0) { const std::size_t copy_amount = std::min(CITRA_PAGE_SIZE - page_offset, remaining_size); - const VAddr current_vaddr = static_cast((page_index << CITRA_PAGE_BITS) + page_offset); + const VAddr current_vaddr = + static_cast((page_index << CITRA_PAGE_BITS) + page_offset); switch (page_table.attributes[page_index]) { case PageType::Unmapped: { @@ -202,13 +204,11 @@ public: [&dest_buffer](const std::size_t copy_amount, const u8* const src_ptr) { std::memcpy(dest_buffer, src_ptr, copy_amount); }, - [&dest_buffer](MMIORegionPointer& handler, - const std::size_t copy_amount, + [&dest_buffer](MMIORegionPointer& handler, const std::size_t copy_amount, const VAddr current_vaddr) { handler->ReadBlock(current_vaddr, dest_buffer, copy_amount); }, - [&dest_buffer](const VAddr current_vaddr, - const std::size_t copy_amount, + [&dest_buffer](const VAddr current_vaddr, const std::size_t copy_amount, const u8* const rasterizer_ptr) { if constexpr (!UNSAFE) { RasterizerFlushVirtualRegion(current_vaddr, static_cast(copy_amount), @@ -234,13 +234,12 @@ public: [&src_buffer](const std::size_t copy_amount, u8* const dest_ptr) { std::memcpy(dest_ptr, src_buffer, copy_amount); }, - [&src_buffer](MMIORegionPointer& handler, - const std::size_t copy_amount, - const VAddr current_vaddr) { + [&src_buffer](MMIORegionPointer& handler, const std::size_t copy_amount, + const VAddr current_vaddr) { handler->WriteBlock(current_vaddr, src_buffer, copy_amount); }, - [&src_buffer](const VAddr current_vaddr, - const std::size_t copy_amount, u8* const host_ptr) { + [&src_buffer](const VAddr current_vaddr, const std::size_t copy_amount, + u8* const host_ptr) { if constexpr (!UNSAFE) { RasterizerFlushVirtualRegion(current_vaddr, static_cast(copy_amount), FlushMode::Invalidate); @@ -356,8 +355,8 @@ std::shared_ptr MemorySystem::GetCurrentPageTable() const { void MemorySystem::MapPages(PageTable& page_table, u32 base, u32 size, MemoryRef memory, PageType type) { - LOG_DEBUG(HW_Memory, "Mapping {} onto {:08X}-{:08X}", (void*)memory.GetPtr(), base * CITRA_PAGE_SIZE, - (base + size) * CITRA_PAGE_SIZE); + LOG_DEBUG(HW_Memory, "Mapping {} onto {:08X}-{:08X}", (void*)memory.GetPtr(), + base * CITRA_PAGE_SIZE, (base + size) * CITRA_PAGE_SIZE); RasterizerFlushVirtualRegion(base << CITRA_PAGE_BITS, size * CITRA_PAGE_SIZE, FlushMode::FlushAndInvalidate); @@ -391,7 +390,8 @@ void MemorySystem::MapIoRegion(PageTable& page_table, VAddr base, u32 size, MMIORegionPointer mmio_handler) { ASSERT_MSG((size & CITRA_PAGE_MASK) == 0, "non-page aligned size: {:08X}", size); ASSERT_MSG((base & CITRA_PAGE_MASK) == 0, "non-page aligned base: {:08X}", base); - MapPages(page_table, base / CITRA_PAGE_SIZE, size / CITRA_PAGE_SIZE, nullptr, PageType::Special); + MapPages(page_table, base / CITRA_PAGE_SIZE, size / CITRA_PAGE_SIZE, nullptr, + PageType::Special); page_table.special_regions.emplace_back(SpecialRegion{base, size, mmio_handler}); } @@ -399,7 +399,8 @@ void MemorySystem::MapIoRegion(PageTable& page_table, VAddr base, u32 size, void MemorySystem::UnmapRegion(PageTable& page_table, VAddr base, u32 size) { ASSERT_MSG((size & CITRA_PAGE_MASK) == 0, "non-page aligned size: {:08X}", size); ASSERT_MSG((base & CITRA_PAGE_MASK) == 0, "non-page aligned base: {:08X}", base); - MapPages(page_table, base / CITRA_PAGE_SIZE, size / CITRA_PAGE_SIZE, nullptr, PageType::Unmapped); + MapPages(page_table, base / CITRA_PAGE_SIZE, size / CITRA_PAGE_SIZE, nullptr, + PageType::Unmapped); } MemoryRef MemorySystem::GetPointerForRasterizerCache(VAddr addr) const { @@ -574,12 +575,11 @@ MemoryRef MemorySystem::GetPhysicalRef(PAddr address) const { std::make_pair(N3DS_EXTRA_RAM_PADDR, N3DS_EXTRA_RAM_SIZE), }; - const auto area = - std::ranges::find_if(memory_areas, [&](const auto& area) { - // Note: the region end check is inclusive because the user can pass in an address that - // represents an open right bound - return address >= area.first && address <= area.first + area.second; - }); + const auto area = std::ranges::find_if(memory_areas, [&](const auto& area) { + // Note: the region end check is inclusive because the user can pass in an address that + // represents an open right bound + return address >= area.first && address <= area.first + area.second; + }); if (area == memory_areas.end()) { LOG_ERROR(HW_Memory, "Unknown GetPhysicalPointer @ {:#08X} at PC {:#08X}", address, @@ -806,7 +806,8 @@ void MemorySystem::WriteBlock(const Kernel::Process& process, const VAddr dest_a return impl->WriteBlockImpl(process, dest_addr, src_buffer, size); } -void MemorySystem::WriteBlock(const VAddr dest_addr, const void* src_buffer, const std::size_t size) { +void MemorySystem::WriteBlock(const VAddr dest_addr, const void* src_buffer, + const std::size_t size) { auto& process = *Core::System::GetInstance().Kernel().GetCurrentProcess(); return impl->WriteBlockImpl(process, dest_addr, src_buffer, size); } @@ -825,13 +826,11 @@ void MemorySystem::ZeroBlock(const Kernel::Process& process, const VAddr dest_ad [](const std::size_t copy_amount, u8* const dest_ptr) { std::memset(dest_ptr, 0, copy_amount); }, - [&zeros = zeros](MMIORegionPointer& handler, - const std::size_t copy_amount, + [&zeros = zeros](MMIORegionPointer& handler, const std::size_t copy_amount, const VAddr current_vaddr) { handler->WriteBlock(current_vaddr, zeros.data(), copy_amount); }, - [](const VAddr current_vaddr, const std::size_t copy_amount, - u8* const rasterizer_ptr) { + [](const VAddr current_vaddr, const std::size_t copy_amount, u8* const rasterizer_ptr) { RasterizerFlushVirtualRegion(current_vaddr, static_cast(copy_amount), FlushMode::Invalidate); std::memset(rasterizer_ptr, 0, copy_amount); @@ -861,14 +860,13 @@ void MemorySystem::CopyBlock(const Kernel::Process& dest_process, [this, &dest_process, &dest_addr](const std::size_t copy_amount, const u8* const src_ptr) { impl->WriteBlockImpl(dest_process, dest_addr, src_ptr, copy_amount); }, - [this, &dest_process, &dest_addr, ©_buffer](MMIORegionPointer& handler, - const std::size_t copy_amount, - const VAddr current_vaddr) { + [this, &dest_process, &dest_addr, ©_buffer]( + MMIORegionPointer& handler, const std::size_t copy_amount, const VAddr current_vaddr) { handler->ReadBlock(current_vaddr, copy_buffer.data(), copy_amount); impl->WriteBlockImpl(dest_process, dest_addr, copy_buffer.data(), copy_amount); }, - [this, &dest_process, &dest_addr]( - const VAddr current_vaddr, const std::size_t copy_amount, u8* const rasterizer_ptr) { + [this, &dest_process, &dest_addr](const VAddr current_vaddr, const std::size_t copy_amount, + u8* const rasterizer_ptr) { RasterizerFlushVirtualRegion(current_vaddr, static_cast(copy_amount), FlushMode::Flush); impl->WriteBlockImpl(dest_process, dest_addr, rasterizer_ptr, copy_amount); diff --git a/src/core/memory.h b/src/core/memory.h index 53d7e2f0e..1369ab223 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -430,7 +430,6 @@ public: */ std::string ReadCString(VAddr vaddr, std::size_t max_length); - /** * Reads a contiguous block of bytes from a specified process' address space. * diff --git a/src/core/settings.h b/src/core/settings.h index c4421cc79..fb0f7f44b 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -14,11 +14,7 @@ namespace Settings { -enum class GraphicsAPI { - OpenGL = 0, - OpenGLES = 1, - Vulkan = 2 -}; +enum class GraphicsAPI { OpenGL = 0, OpenGLES = 1, Vulkan = 2 }; enum class InitClock { SystemTime = 0, diff --git a/src/input_common/motion_emu.cpp b/src/input_common/motion_emu.cpp index d4d09fef7..431c8712b 100644 --- a/src/input_common/motion_emu.cpp +++ b/src/input_common/motion_emu.cpp @@ -5,9 +5,9 @@ #include #include #include +#include #include #include -#include #include "common/math_util.h" #include "common/quaternion.h" #include "common/thread.h" diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp index 48e6578cd..626e56bc6 100644 --- a/src/input_common/sdl/sdl_impl.cpp +++ b/src/input_common/sdl/sdl_impl.cpp @@ -8,13 +8,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include #include #include "common/logging/log.h" #include "common/param_package.h" diff --git a/src/video_core/pica.cpp b/src/video_core/pica.cpp index 88382d904..74f408c57 100644 --- a/src/video_core/pica.cpp +++ b/src/video_core/pica.cpp @@ -41,7 +41,7 @@ State::State() : geometry_pipeline(*this) { auto SubmitVertex = [this](const Shader::AttributeBuffer& vertex) { using Pica::Shader::OutputVertex; auto AddTriangle = [](const OutputVertex& v0, const OutputVertex& v1, - const OutputVertex& v2) { + const OutputVertex& v2) { VideoCore::g_renderer->Rasterizer()->AddTriangle(v0, v1, v2); }; primitive_assembler.SubmitVertex( diff --git a/src/video_core/rasterizer_accelerated.cpp b/src/video_core/rasterizer_accelerated.cpp index ed6f37c76..3384b973e 100644 --- a/src/video_core/rasterizer_accelerated.cpp +++ b/src/video_core/rasterizer_accelerated.cpp @@ -4,8 +4,8 @@ #include #include "core/memory.h" -#include "video_core/video_core.h" #include "video_core/rasterizer_accelerated.h" +#include "video_core/video_core.h" namespace VideoCore { @@ -53,21 +53,18 @@ void RasterizerAccelerated::UpdatePagesCachedCount(PAddr addr, u32 size, int del cache_bytes += Memory::CITRA_PAGE_SIZE; } else if (cache_bytes > 0) { - VideoCore::g_memory->RasterizerMarkRegionCached(cache_start_addr, cache_bytes, - true); + VideoCore::g_memory->RasterizerMarkRegionCached(cache_start_addr, cache_bytes, true); cache_bytes = 0; } } if (uncache_bytes > 0) { - VideoCore::g_memory->RasterizerMarkRegionCached(uncache_start_addr, uncache_bytes, - false); + VideoCore::g_memory->RasterizerMarkRegionCached(uncache_start_addr, uncache_bytes, false); } if (cache_bytes > 0) { - VideoCore::g_memory->RasterizerMarkRegionCached(cache_start_addr, cache_bytes, - true); + VideoCore::g_memory->RasterizerMarkRegionCached(cache_start_addr, cache_bytes, true); } } @@ -98,8 +95,7 @@ void RasterizerAccelerated::ClearAll(bool flush) { } if (uncache_bytes > 0) { - VideoCore::g_memory->RasterizerMarkRegionCached(uncache_start_addr, uncache_bytes, - false); + VideoCore::g_memory->RasterizerMarkRegionCached(uncache_start_addr, uncache_bytes, false); } cached_pages = {}; diff --git a/src/video_core/rasterizer_cache/morton_swizzle.h b/src/video_core/rasterizer_cache/morton_swizzle.h index ab5077aff..c3bf55c44 100644 --- a/src/video_core/rasterizer_cache/morton_swizzle.h +++ b/src/video_core/rasterizer_cache/morton_swizzle.h @@ -3,9 +3,9 @@ // Refer to the license.txt file included. #pragma once -#include -#include #include +#include +#include #include "common/alignment.h" #include "common/color.h" #include "video_core/rasterizer_cache/pixel_format.h" @@ -108,7 +108,8 @@ inline void EncodePixel(const std::byte* source, std::byte* dest) { } template -inline void MortonCopyTile(u32 stride, std::span tile_buffer, std::span linear_buffer) { +inline void MortonCopyTile(u32 stride, std::span tile_buffer, + std::span linear_buffer) { constexpr u32 bytes_per_pixel = GetFormatBpp(format) / 8; constexpr u32 linear_bytes_per_pixel = GetBytesPerPixel(format); constexpr bool is_compressed = format == PixelFormat::ETC1 || format == PixelFormat::ETC1A4; @@ -116,10 +117,10 @@ inline void MortonCopyTile(u32 stride, std::span tile_buffer, std::sp for (u32 y = 0; y < 8; y++) { for (u32 x = 0; x < 8; x++) { - const auto tiled_pixel = tile_buffer.subspan(VideoCore::MortonInterleave(x, y) * bytes_per_pixel, - bytes_per_pixel); - const auto linear_pixel = linear_buffer.subspan(((7 - y) * stride + x) * linear_bytes_per_pixel, - linear_bytes_per_pixel); + const auto tiled_pixel = tile_buffer.subspan( + VideoCore::MortonInterleave(x, y) * bytes_per_pixel, bytes_per_pixel); + const auto linear_pixel = linear_buffer.subspan( + ((7 - y) * stride + x) * linear_bytes_per_pixel, linear_bytes_per_pixel); if constexpr (morton_to_linear) { if constexpr (is_compressed) { DecodePixelETC1(x, y, tile_buffer.data(), linear_pixel.data()); @@ -138,28 +139,30 @@ inline void MortonCopyTile(u32 stride, std::span tile_buffer, std::sp /** * @brief Performs morton to/from linear convertions on the provided pixel data * @param width, height The dimentions of the rectangular region of pixels in linear_buffer - * @param start_offset The number of bytes from the start of the first tile to the start of tiled_buffer + * @param start_offset The number of bytes from the start of the first tile to the start of + * tiled_buffer * @param end_offset The number of bytes from the start of the first tile to the end of tiled_buffer * @param linear_buffer The linear pixel data * @param tiled_buffer The tiled pixel data * - * The MortonCopy is at the heart of the PICA texture implementation, as it's responsible for converting between - * linear and morton tiled layouts. The function handles both convertions but there are slightly different - * paths and inputs for each: + * The MortonCopy is at the heart of the PICA texture implementation, as it's responsible for + * converting between linear and morton tiled layouts. The function handles both convertions but + * there are slightly different paths and inputs for each: * * Morton to Linear: - * During uploads, tiled_buffer is always aligned to the tile or scanline boundary depending if the linear rectangle - * spans multiple vertical tiles. linear_buffer does not reference the entire texture area, but rather the - * specific rectangle affected by the upload. + * During uploads, tiled_buffer is always aligned to the tile or scanline boundary depending if the + * linear rectangle spans multiple vertical tiles. linear_buffer does not reference the entire + * texture area, but rather the specific rectangle affected by the upload. * * Linear to Morton: - * This is similar to the other convertion but with some differences. In this case tiled_buffer is not required - * to be aligned to any specific boundary which requires special care. start_offset/end_offset are useful - * here as they tell us exactly where the data should be placed in the linear_buffer. + * This is similar to the other convertion but with some differences. In this case tiled_buffer is + * not required to be aligned to any specific boundary which requires special care. + * start_offset/end_offset are useful here as they tell us exactly where the data should be placed + * in the linear_buffer. */ template static void MortonCopy(u32 width, u32 height, u32 start_offset, u32 end_offset, - std::span linear_buffer, std::span tiled_buffer) { + std::span linear_buffer, std::span tiled_buffer) { constexpr u32 bytes_per_pixel = GetFormatBpp(format) / 8; constexpr u32 aligned_bytes_per_pixel = GetBytesPerPixel(format); constexpr u32 tile_size = GetFormatBpp(format) * 64 / 8; @@ -170,7 +173,8 @@ static void MortonCopy(u32 width, u32 height, u32 start_offset, u32 end_offset, const u32 aligned_start_offset = Common::AlignUp(start_offset, tile_size); const u32 aligned_end_offset = Common::AlignDown(end_offset, tile_size); - ASSERT(!morton_to_linear || (aligned_start_offset == start_offset && aligned_end_offset == end_offset)); + ASSERT(!morton_to_linear || + (aligned_start_offset == start_offset && aligned_end_offset == end_offset)); // In OpenGL the texture origin is in the bottom left corner as opposed to other // APIs that have it at the top left. To avoid flipping texture coordinates in @@ -184,7 +188,7 @@ static void MortonCopy(u32 width, u32 height, u32 start_offset, u32 end_offset, x = (x + 8) % width; linear_offset += 8 * aligned_bytes_per_pixel; if (!x) { - y = (y + 8) % height; + y = (y + 8) % height; if (!y) { return; } @@ -222,7 +226,8 @@ static void MortonCopy(u32 width, u32 height, u32 start_offset, u32 end_offset, std::array tmp_buf; auto linear_data = linear_buffer.subspan(linear_offset, linear_tile_stride); MortonCopyTile(width, tmp_buf, linear_data); - std::memcpy(tiled_buffer.data() + tiled_offset, tmp_buf.data(), end_offset - aligned_end_offset); + std::memcpy(tiled_buffer.data() + tiled_offset, tmp_buf.data(), + end_offset - aligned_end_offset); } } @@ -234,19 +239,19 @@ static constexpr std::array UNSWIZZLE_TABLE = { MortonCopy, // 2 MortonCopy, // 3 MortonCopy, // 4 - MortonCopy, // 5 - MortonCopy, // 6 - MortonCopy, // 7 - MortonCopy, // 8 - MortonCopy, // 9 - MortonCopy, // 10 - MortonCopy, // 11 - MortonCopy, // 12 - MortonCopy, // 13 - MortonCopy, // 14 - nullptr, // 15 - MortonCopy, // 16 - MortonCopy // 17 + MortonCopy, // 5 + MortonCopy, // 6 + MortonCopy, // 7 + MortonCopy, // 8 + MortonCopy, // 9 + MortonCopy, // 10 + MortonCopy, // 11 + MortonCopy, // 12 + MortonCopy, // 13 + MortonCopy, // 14 + nullptr, // 15 + MortonCopy, // 16 + MortonCopy // 17 }; static constexpr std::array SWIZZLE_TABLE = { diff --git a/src/video_core/rasterizer_cache/rasterizer_cache.cpp b/src/video_core/rasterizer_cache/rasterizer_cache.cpp index 6f2436350..49b3c38a8 100644 --- a/src/video_core/rasterizer_cache/rasterizer_cache.cpp +++ b/src/video_core/rasterizer_cache/rasterizer_cache.cpp @@ -6,9 +6,13 @@ namespace VideoCore { -MICROPROFILE_DEFINE(RasterizerCache_BlitSurface, "RasterizerCache", "BlitSurface", MP_RGB(128, 192, 64)); -MICROPROFILE_DEFINE(RasterizerCache_CopySurface, "RasterizerCache", "CopySurface", MP_RGB(128, 192, 64)); -MICROPROFILE_DEFINE(RasterizerCache_SurfaceLoad, "RasterizerCache", "Surface Load", MP_RGB(128, 192, 64)); -MICROPROFILE_DEFINE(RasterizerCache_SurfaceFlush, "RasterizerCache", "Surface Flush", MP_RGB(128, 192, 64)); +MICROPROFILE_DEFINE(RasterizerCache_BlitSurface, "RasterizerCache", "BlitSurface", + MP_RGB(128, 192, 64)); +MICROPROFILE_DEFINE(RasterizerCache_CopySurface, "RasterizerCache", "CopySurface", + MP_RGB(128, 192, 64)); +MICROPROFILE_DEFINE(RasterizerCache_SurfaceLoad, "RasterizerCache", "Surface Load", + MP_RGB(128, 192, 64)); +MICROPROFILE_DEFINE(RasterizerCache_SurfaceFlush, "RasterizerCache", "Surface Flush", + MP_RGB(128, 192, 64)); } // namespace VideoCore diff --git a/src/video_core/rasterizer_cache/rasterizer_cache.h b/src/video_core/rasterizer_cache/rasterizer_cache.h index 0532b4889..8c5a38c75 100644 --- a/src/video_core/rasterizer_cache/rasterizer_cache.h +++ b/src/video_core/rasterizer_cache/rasterizer_cache.h @@ -4,8 +4,8 @@ #pragma once #include -#include #include +#include #include #include #include "common/alignment.h" @@ -14,8 +14,8 @@ #include "video_core/pica_state.h" #include "video_core/rasterizer_accelerated.h" #include "video_core/rasterizer_cache/surface_base.h" -#include "video_core/rasterizer_cache/utils.h" #include "video_core/rasterizer_cache/surface_params.h" +#include "video_core/rasterizer_cache/utils.h" #include "video_core/texture/texture_decode.h" #include "video_core/video_core.h" @@ -54,16 +54,18 @@ public: private: /// Declare rasterizer interval types using SurfaceSet = std::set; - using SurfaceMap = - boost::icl::interval_map; - using SurfaceCache = - boost::icl::interval_map; + using SurfaceMap = boost::icl::interval_map; + using SurfaceCache = boost::icl::interval_map; - static_assert(std::is_same() && - std::is_same(), - "Incorrect interval types"); + static_assert( + std::is_same() && + std::is_same(), + "Incorrect interval types"); using SurfaceRect_Tuple = std::tuple>; using SurfaceSurfaceRect_Tuple = std::tuple>; @@ -170,7 +172,8 @@ private: }; template -RasterizerCache::RasterizerCache(VideoCore::RasterizerAccelerated& rasterizer, TextureRuntime& runtime) +RasterizerCache::RasterizerCache(VideoCore::RasterizerAccelerated& rasterizer, + TextureRuntime& runtime) : rasterizer{rasterizer}, runtime{runtime} { resolution_scale_factor = VideoCore::GetResolutionScaleFactor(); } @@ -249,7 +252,7 @@ auto RasterizerCache::FindMatch(const SurfaceCache& surface_cache, const Surf IsMatch_Helper(std::integral_constant{}, [&] { ASSERT(validate_interval); auto copy_interval = - surface->GetCopyableInterval(params.FromInterval(*validate_interval)); + surface->GetCopyableInterval(params.FromInterval(*validate_interval)); bool matched = boost::icl::length(copy_interval & *validate_interval) != 0 && surface->CanCopy(params, copy_interval); return std::make_pair(matched, copy_interval); @@ -271,8 +274,7 @@ bool RasterizerCache::BlitSurfaces(const Surface& src_surface, Common::Rectan const Surface& dst_surface, Common::Rectangle dst_rect) { MICROPROFILE_SCOPE(RasterizerCache_BlitSurface); - if (!CheckFormatsBlittable(src_surface->pixel_format, - dst_surface->pixel_format)) [[unlikely]] { + if (!CheckFormatsBlittable(src_surface->pixel_format, dst_surface->pixel_format)) [[unlikely]] { return false; } @@ -282,28 +284,23 @@ bool RasterizerCache::BlitSurfaces(const Surface& src_surface, Common::Rectan // 1. No scaling (the dimentions of src and dest rect are the same) // 2. No flipping (if the bottom value is bigger than the top this indicates texture flip) if (src_rect.GetWidth() == dst_rect.GetWidth() && - src_rect.GetHeight() == dst_rect.GetHeight() && - src_rect.bottom < src_rect.top) { - const TextureCopy texture_copy = { - .src_level = 0, - .dst_level = 0, - .src_layer = 0, - .dst_layer = 0, - .src_offset = {src_rect.left, src_rect.bottom}, - .dst_offset = {dst_rect.left, dst_rect.bottom}, - .extent = {src_rect.GetWidth(), src_rect.GetHeight()} - }; + src_rect.GetHeight() == dst_rect.GetHeight() && src_rect.bottom < src_rect.top) { + const TextureCopy texture_copy = {.src_level = 0, + .dst_level = 0, + .src_layer = 0, + .dst_layer = 0, + .src_offset = {src_rect.left, src_rect.bottom}, + .dst_offset = {dst_rect.left, dst_rect.bottom}, + .extent = {src_rect.GetWidth(), src_rect.GetHeight()}}; return runtime.CopyTextures(*src_surface, *dst_surface, texture_copy); } else { - const TextureBlit texture_blit = { - .src_level = 0, - .dst_level = 0, - .src_layer = 0, - .dst_layer = 0, - .src_rect = src_rect, - .dst_rect = dst_rect - }; + const TextureBlit texture_blit = {.src_level = 0, + .dst_level = 0, + .src_layer = 0, + .dst_layer = 0, + .src_rect = src_rect, + .dst_rect = dst_rect}; return runtime.BlitTextures(*src_surface, *dst_surface, texture_blit); } @@ -332,23 +329,20 @@ void RasterizerCache::CopySurface(const Surface& src_surface, const Surface& const ClearValue clear_value = MakeClearValue(dst_surface->type, dst_surface->pixel_format, fill_buffer.data()); const TextureClear clear_rect = { - .texture_level = 0, - .texture_rect = dst_surface->GetScaledSubRect(subrect_params) - }; + .texture_level = 0, .texture_rect = dst_surface->GetScaledSubRect(subrect_params)}; runtime.ClearTexture(*dst_surface, clear_rect, clear_value); return; } if (src_surface->CanSubRect(subrect_params)) { - const TextureBlit texture_blit = { - .src_level = 0, - .dst_level = 0, - .src_layer = 0, - .dst_layer = 0, - .src_rect = src_surface->GetScaledSubRect(subrect_params), - .dst_rect = dst_surface->GetScaledSubRect(subrect_params) - }; + const TextureBlit texture_blit = {.src_level = 0, + .dst_level = 0, + .src_layer = 0, + .dst_layer = 0, + .src_rect = src_surface->GetScaledSubRect(subrect_params), + .dst_rect = + dst_surface->GetScaledSubRect(subrect_params)}; runtime.BlitTextures(*src_surface, *dst_surface, texture_blit); return; @@ -488,13 +482,15 @@ auto RasterizerCache::GetSurfaceSubRect(const SurfaceParams& params, ScaleMat } template -auto RasterizerCache::GetTextureSurface(const Pica::TexturingRegs::FullTextureConfig& config) -> Surface { +auto RasterizerCache::GetTextureSurface(const Pica::TexturingRegs::FullTextureConfig& config) + -> Surface { const auto info = Pica::Texture::TextureInfo::FromPicaRegister(config.config, config.format); return GetTextureSurface(info, config.config.lod.max_level); } template -auto RasterizerCache::GetTextureSurface(const Pica::Texture::TextureInfo& info, u32 max_level) -> Surface { +auto RasterizerCache::GetTextureSurface(const Pica::Texture::TextureInfo& info, u32 max_level) + -> Surface { if (info.physical_address == 0) [[unlikely]] { return nullptr; } @@ -572,15 +568,13 @@ auto RasterizerCache::GetTextureSurface(const Pica::Texture::TextureInfo& inf ValidateSurface(level_surface, level_surface->addr, level_surface->size); } - if (/*texture_filterer->IsNull()*/true) { - const TextureBlit texture_blit = { - .src_level = 0, - .dst_level = level, - .src_layer = 0, - .dst_layer = 0, - .src_rect = level_surface->GetScaledRect(), - .dst_rect = surface_params.GetScaledRect() - }; + if (/*texture_filterer->IsNull()*/ true) { + const TextureBlit texture_blit = {.src_level = 0, + .dst_level = level, + .src_layer = 0, + .dst_layer = 0, + .src_rect = level_surface->GetScaledRect(), + .dst_rect = surface_params.GetScaledRect()}; runtime.BlitTextures(*level_surface, *surface, texture_blit); } @@ -597,15 +591,13 @@ template auto RasterizerCache::GetTextureCube(const TextureCubeConfig& config) -> const Surface& { auto [it, new_surface] = texture_cube_cache.try_emplace(config); if (new_surface) { - SurfaceParams cube_params = { - .addr = config.px, - .width = config.width, - .height = config.width, - .stride = config.width, - .texture_type = TextureType::CubeMap, - .pixel_format = PixelFormatFromTextureFormat(config.format), - .type = SurfaceType::Texture - }; + SurfaceParams cube_params = {.addr = config.px, + .width = config.width, + .height = config.width, + .stride = config.width, + .texture_type = TextureType::CubeMap, + .pixel_format = PixelFormatFromTextureFormat(config.format), + .type = SurfaceType::Texture}; it->second = CreateSurface(cube_params); } @@ -614,8 +606,7 @@ auto RasterizerCache::GetTextureCube(const TextureCubeConfig& config) -> cons // Update surface watchers auto& watchers = cube->level_watchers; - const std::array addresses = {config.px, config.nx, config.py, - config.ny, config.pz, config.nz}; + const std::array addresses = {config.px, config.nx, config.py, config.ny, config.pz, config.nz}; for (std::size_t i = 0; i < addresses.size(); i++) { auto& watcher = watchers[i]; @@ -632,9 +623,9 @@ auto RasterizerCache::GetTextureCube(const TextureCubeConfig& config) -> cons if (surface) { watcher = surface->CreateWatcher(); } else { - // Can occur when texture address is invalid. We mark the watcher with nullptr - // in this case and the content of the face wouldn't get updated. These are usually - // leftover setup in the texture unit and games are not supposed to draw using them. + // Can occur when texture address is invalid. We mark the watcher with nullptr + // in this case and the content of the face wouldn't get updated. These are usually + // leftover setup in the texture unit and games are not supposed to draw using them. watcher = nullptr; } } @@ -650,14 +641,12 @@ auto RasterizerCache::GetTextureCube(const TextureCubeConfig& config) -> cons ValidateSurface(face, face->addr, face->size); } - const TextureBlit texture_blit = { - .src_level = 0, - .dst_level = 0, - .src_layer = 0, - .dst_layer = static_cast(i), - .src_rect = face->GetScaledRect(), - .dst_rect = Rect2D{0, scaled_size, scaled_size, 0} - }; + const TextureBlit texture_blit = {.src_level = 0, + .dst_level = 0, + .src_layer = 0, + .dst_layer = static_cast(i), + .src_rect = face->GetScaledRect(), + .dst_rect = Rect2D{0, scaled_size, scaled_size, 0}}; runtime.BlitTextures(*face, *cube, texture_blit); watcher->Validate(); @@ -670,7 +659,7 @@ auto RasterizerCache::GetTextureCube(const TextureCubeConfig& config) -> cons template auto RasterizerCache::GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb, const Common::Rectangle& viewport_rect) - -> SurfaceSurfaceRect_Tuple { + -> SurfaceSurfaceRect_Tuple { const auto& regs = Pica::g_state.regs; const auto& config = regs.framebuffer.framebuffer; @@ -680,7 +669,8 @@ auto RasterizerCache::GetFramebufferSurfaces(bool using_color_fb, bool using_ const bool texture_filter_changed = /*VideoCore::g_texture_filter_update_requested.exchange(false) && texture_filterer->Reset(Settings::values.texture_filter_name, - VideoCore::GetResolutionScaleFactor())*/false; + VideoCore::GetResolutionScaleFactor())*/ + false; if (resolution_scale_changed || texture_filter_changed) [[unlikely]] { resolution_scale_factor = VideoCore::GetResolutionScaleFactor(); @@ -918,7 +908,7 @@ void RasterizerCache::UploadSurface(const Surface& surface, SurfaceInterval i MICROPROFILE_SCOPE(RasterizerCache_SurfaceLoad); const auto& staging = runtime.FindStaging( - load_info.width * load_info.height * surface->GetInternalBytesPerPixel(), true); + load_info.width * load_info.height * surface->GetInternalBytesPerPixel(), true); MemoryRef source_ptr = VideoCore::g_memory->GetPhysicalRef(load_info.addr); if (!source_ptr) [[unlikely]] { return; @@ -926,19 +916,18 @@ void RasterizerCache::UploadSurface(const Surface& surface, SurfaceInterval i const auto upload_data = source_ptr.GetWriteBytes(load_info.end - load_info.addr); if (surface->is_tiled) { - std::vector unswizzled_data(load_info.width * load_info.height * GetBytesPerPixel(load_info.pixel_format)); + std::vector unswizzled_data(load_info.width * load_info.height * + GetBytesPerPixel(load_info.pixel_format)); UnswizzleTexture(load_info, load_info.addr, load_info.end, upload_data, unswizzled_data); runtime.FormatConvert(*surface, true, unswizzled_data, staging.mapped); } else { runtime.FormatConvert(*surface, true, upload_data, staging.mapped); } - const BufferTextureCopy upload = { - .buffer_offset = 0, - .buffer_size = staging.size, - .texture_rect = surface->GetSubRect(load_info), - .texture_level = 0 - }; + const BufferTextureCopy upload = {.buffer_offset = 0, + .buffer_size = staging.size, + .texture_rect = surface->GetSubRect(load_info), + .texture_level = 0}; surface->Upload(upload, staging); } @@ -952,32 +941,32 @@ void RasterizerCache::DownloadSurface(const Surface& surface, SurfaceInterval ASSERT(flush_start >= surface->addr && flush_end <= surface->end); const auto& staging = runtime.FindStaging( - flush_info.width * flush_info.height * surface->GetInternalBytesPerPixel(), false); - const BufferTextureCopy download = { - .buffer_offset = 0, - .buffer_size = staging.size, - .texture_rect = surface->GetSubRect(flush_info), - .texture_level = 0 - }; + flush_info.width * flush_info.height * surface->GetInternalBytesPerPixel(), false); + const BufferTextureCopy download = {.buffer_offset = 0, + .buffer_size = staging.size, + .texture_rect = surface->GetSubRect(flush_info), + .texture_level = 0}; surface->Download(download, staging); - download_queue.push_back([this, surface, flush_start, flush_end, flush_info, mapped = staging.mapped]() { - MemoryRef dest_ptr = VideoCore::g_memory->GetPhysicalRef(flush_start); - if (!dest_ptr) [[unlikely]] { - return; - } + download_queue.push_back( + [this, surface, flush_start, flush_end, flush_info, mapped = staging.mapped]() { + MemoryRef dest_ptr = VideoCore::g_memory->GetPhysicalRef(flush_start); + if (!dest_ptr) [[unlikely]] { + return; + } - const auto download_dest = dest_ptr.GetWriteBytes(flush_end - flush_start); + const auto download_dest = dest_ptr.GetWriteBytes(flush_end - flush_start); - if (surface->is_tiled) { - std::vector temp_data(flush_info.width * flush_info.height * GetBytesPerPixel(flush_info.pixel_format)); - runtime.FormatConvert(*surface, false, mapped, temp_data); - SwizzleTexture(flush_info, flush_start, flush_end, temp_data, download_dest); - } else { - runtime.FormatConvert(*surface, false, mapped, download_dest); - } - }); + if (surface->is_tiled) { + std::vector temp_data(flush_info.width * flush_info.height * + GetBytesPerPixel(flush_info.pixel_format)); + runtime.FormatConvert(*surface, false, mapped, temp_data); + SwizzleTexture(flush_info, flush_start, flush_end, temp_data, download_dest); + } else { + runtime.FormatConvert(*surface, false, mapped, download_dest); + } + }); } template @@ -992,7 +981,8 @@ void RasterizerCache::DownloadFillSurface(const Surface& surface, SurfaceInte } const u32 start_offset = flush_start - surface->addr; - const u32 download_size = std::clamp(flush_end - flush_start, 0u, static_cast(dest_ptr.GetSize())); + const u32 download_size = + std::clamp(flush_end - flush_start, 0u, static_cast(dest_ptr.GetSize())); const u32 coarse_start_offset = start_offset - (start_offset % surface->fill_size); const u32 backup_bytes = start_offset % surface->fill_size; @@ -1012,7 +1002,8 @@ void RasterizerCache::DownloadFillSurface(const Surface& surface, SurfaceInte } template -bool RasterizerCache::NoUnimplementedReinterpretations(const Surface& surface, SurfaceParams& params, +bool RasterizerCache::NoUnimplementedReinterpretations(const Surface& surface, + SurfaceParams& params, SurfaceInterval interval) { static constexpr std::array all_formats = { PixelFormat::RGBA8, PixelFormat::RGB8, PixelFormat::RGB5A1, PixelFormat::RGB565, @@ -1043,13 +1034,13 @@ bool RasterizerCache::NoUnimplementedReinterpretations(const Surface& surface } template -bool RasterizerCache::IntervalHasInvalidPixelFormat(SurfaceParams& params, SurfaceInterval interval) { +bool RasterizerCache::IntervalHasInvalidPixelFormat(SurfaceParams& params, + SurfaceInterval interval) { params.pixel_format = PixelFormat::Invalid; for (const auto& set : RangeFromInterval(surface_cache, interval)) { for (const auto& surface : set.second) { if (surface->pixel_format == PixelFormat::Invalid) { - LOG_DEBUG(HW_GPU, "Surface {:#x} found with invalid pixel format", - surface->addr); + LOG_DEBUG(HW_GPU, "Surface {:#x} found with invalid pixel format", surface->addr); return true; } } diff --git a/src/video_core/rasterizer_cache/surface_base.h b/src/video_core/rasterizer_cache/surface_base.h index c06094168..07599f0c1 100644 --- a/src/video_core/rasterizer_cache/surface_base.h +++ b/src/video_core/rasterizer_cache/surface_base.h @@ -46,6 +46,7 @@ public: template class SurfaceBase : public SurfaceParams, public std::enable_shared_from_this { using Watcher = SurfaceWatcher; + public: SurfaceBase(SurfaceParams& params) : SurfaceParams{params} {} virtual ~SurfaceBase() = default; @@ -53,7 +54,8 @@ public: /// Returns true when this surface can be used to fill the fill_interval of dest_surface bool CanFill(const SurfaceParams& dest_surface, SurfaceInterval fill_interval) const; - /// Returns true when copy_interval of dest_surface can be validated by copying from this surface + /// Returns true when copy_interval of dest_surface can be validated by copying from this + /// surface bool CanCopy(const SurfaceParams& dest_surface, SurfaceInterval copy_interval) const; /// Returns the region of the biggest valid rectange within interval @@ -93,7 +95,8 @@ public: }; template -bool SurfaceBase::CanFill(const SurfaceParams& dest_surface, SurfaceInterval fill_interval) const { +bool SurfaceBase::CanFill(const SurfaceParams& dest_surface, + SurfaceInterval fill_interval) const { if (type == SurfaceType::Fill && IsRegionValid(fill_interval) && boost::icl::first(fill_interval) >= addr && boost::icl::last_next(fill_interval) <= end && // dest_surface is within our fill range @@ -123,7 +126,7 @@ bool SurfaceBase::CanFill(const SurfaceParams& dest_surface, SurfaceInterval template bool SurfaceBase::CanCopy(const SurfaceParams& dest_surface, - SurfaceInterval copy_interval) const { + SurfaceInterval copy_interval) const { SurfaceParams subrect_params = dest_surface.FromInterval(copy_interval); ASSERT(subrect_params.GetInterval() == copy_interval); if (CanSubRect(subrect_params)) @@ -139,13 +142,15 @@ template SurfaceInterval SurfaceBase::GetCopyableInterval(const SurfaceParams& params) const { SurfaceInterval result{}; const u32 tile_align = params.BytesInPixels(params.is_tiled ? 8 * 8 : 1); - const auto valid_regions = SurfaceRegions{params.GetInterval() & GetInterval()} - invalid_regions; + const auto valid_regions = + SurfaceRegions{params.GetInterval() & GetInterval()} - invalid_regions; for (auto& valid_interval : valid_regions) { const SurfaceInterval aligned_interval{ - params.addr + Common::AlignUp(boost::icl::first(valid_interval) - params.addr, tile_align), - params.addr + Common::AlignDown(boost::icl::last_next(valid_interval) - params.addr, tile_align) - }; + params.addr + + Common::AlignUp(boost::icl::first(valid_interval) - params.addr, tile_align), + params.addr + + Common::AlignDown(boost::icl::last_next(valid_interval) - params.addr, tile_align)}; if (params.BytesInPixels(tile_align) > boost::icl::length(valid_interval) || boost::icl::length(aligned_interval) == 0) { @@ -155,8 +160,10 @@ SurfaceInterval SurfaceBase::GetCopyableInterval(const SurfaceParams& params) // Get the rectangle within aligned_interval const u32 stride_bytes = params.BytesInPixels(params.stride) * (params.is_tiled ? 8 : 1); SurfaceInterval rect_interval{ - params.addr + Common::AlignUp(boost::icl::first(aligned_interval) - params.addr, stride_bytes), - params.addr + Common::AlignDown(boost::icl::last_next(aligned_interval) - params.addr, stride_bytes), + params.addr + + Common::AlignUp(boost::icl::first(aligned_interval) - params.addr, stride_bytes), + params.addr + Common::AlignDown(boost::icl::last_next(aligned_interval) - params.addr, + stride_bytes), }; if (boost::icl::first(rect_interval) > boost::icl::last_next(rect_interval)) { diff --git a/src/video_core/rasterizer_cache/surface_params.h b/src/video_core/rasterizer_cache/surface_params.h index 15a73881a..39fe30579 100644 --- a/src/video_core/rasterizer_cache/surface_params.h +++ b/src/video_core/rasterizer_cache/surface_params.h @@ -15,10 +15,7 @@ namespace VideoCore { using SurfaceInterval = boost::icl::right_open_interval; -enum class TextureType { - Texture2D = 0, - CubeMap = 1 -}; +enum class TextureType { Texture2D = 0, CubeMap = 1 }; class SurfaceParams { public: diff --git a/src/video_core/rasterizer_cache/utils.cpp b/src/video_core/rasterizer_cache/utils.cpp index 3b4a6b654..52363d21c 100644 --- a/src/video_core/rasterizer_cache/utils.cpp +++ b/src/video_core/rasterizer_cache/utils.cpp @@ -3,10 +3,10 @@ // Refer to the license.txt file included. #include "common/assert.h" -#include "video_core/texture/texture_decode.h" #include "video_core/rasterizer_cache/morton_swizzle.h" #include "video_core/rasterizer_cache/surface_params.h" #include "video_core/rasterizer_cache/utils.h" +#include "video_core/texture/texture_decode.h" namespace VideoCore { @@ -51,18 +51,16 @@ void SwizzleTexture(const SurfaceParams& swizzle_info, PAddr start_addr, PAddr e std::span source_linear, std::span dest_tiled) { const u32 func_index = static_cast(swizzle_info.pixel_format); const MortonFunc SwizzleImpl = SWIZZLE_TABLE[func_index]; - SwizzleImpl(swizzle_info.width, swizzle_info.height, - start_addr - swizzle_info.addr, end_addr - swizzle_info.addr, - source_linear, dest_tiled); + SwizzleImpl(swizzle_info.width, swizzle_info.height, start_addr - swizzle_info.addr, + end_addr - swizzle_info.addr, source_linear, dest_tiled); } void UnswizzleTexture(const SurfaceParams& unswizzle_info, PAddr start_addr, PAddr end_addr, std::span source_tiled, std::span dest_linear) { const u32 func_index = static_cast(unswizzle_info.pixel_format); const MortonFunc UnswizzleImpl = UNSWIZZLE_TABLE[func_index]; - UnswizzleImpl(unswizzle_info.width, unswizzle_info.height, - start_addr - unswizzle_info.addr, end_addr - unswizzle_info.addr, - dest_linear, source_tiled); + UnswizzleImpl(unswizzle_info.width, unswizzle_info.height, start_addr - unswizzle_info.addr, + end_addr - unswizzle_info.addr, dest_linear, source_tiled); } } // namespace VideoCore diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index 88a6f2358..a2c20374f 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h @@ -66,6 +66,6 @@ public: protected: Frontend::EmuWindow& render_window; ///< Reference to the render window handle. - f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer - int m_current_frame = 0; ///< Current frame, should be set by the renderer + f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer + int m_current_frame = 0; ///< Current frame, should be set by the renderer }; diff --git a/src/video_core/renderer_opengl/frame_dumper_opengl.cpp b/src/video_core/renderer_opengl/frame_dumper_opengl.cpp index af79264e5..07273317f 100644 --- a/src/video_core/renderer_opengl/frame_dumper_opengl.cpp +++ b/src/video_core/renderer_opengl/frame_dumper_opengl.cpp @@ -22,9 +22,7 @@ Layout::FramebufferLayout FrameDumperOpenGL::GetLayout() const { } void FrameDumperOpenGL::StartDumping() { - present_thread = std::jthread([&](std::stop_token stop_token) { - PresentLoop(stop_token); - }); + present_thread = std::jthread([&](std::stop_token stop_token) { PresentLoop(stop_token); }); } void FrameDumperOpenGL::StopDumping() { diff --git a/src/video_core/renderer_opengl/gl_driver.cpp b/src/video_core/renderer_opengl/gl_driver.cpp index f7584957b..08545c545 100644 --- a/src/video_core/renderer_opengl/gl_driver.cpp +++ b/src/video_core/renderer_opengl/gl_driver.cpp @@ -147,7 +147,6 @@ void Driver::FindBugs() { if (vendor == Vendor::AMD || (vendor == Vendor::Intel && !is_linux)) { bugs |= DriverBug::BrokenTextureView; } - } } // namespace OpenGL diff --git a/src/video_core/renderer_opengl/gl_driver.h b/src/video_core/renderer_opengl/gl_driver.h index b8d491b7e..5ddff93c9 100644 --- a/src/video_core/renderer_opengl/gl_driver.h +++ b/src/video_core/renderer_opengl/gl_driver.h @@ -7,13 +7,7 @@ namespace OpenGL { -enum class Vendor { - Unknown = 0, - AMD = 1, - Nvidia = 2, - Intel = 3, - Generic = 4 -}; +enum class Vendor { Unknown = 0, AMD = 1, Nvidia = 2, Intel = 3, Generic = 4 }; enum class DriverBug { // AMD drivers sometimes freeze when one shader stage is changed but not the others. diff --git a/src/video_core/renderer_opengl/gl_format_reinterpreter.cpp b/src/video_core/renderer_opengl/gl_format_reinterpreter.cpp index c3b3b2709..46a11024f 100644 --- a/src/video_core/renderer_opengl/gl_format_reinterpreter.cpp +++ b/src/video_core/renderer_opengl/gl_format_reinterpreter.cpp @@ -35,7 +35,7 @@ imageStore(color, tex_coord, vec4(components) / (exp2(8.0) - 1.0)); } void D24S8toRGBA8::Reinterpret(const Surface& source, VideoCore::Rect2D src_rect, - const Surface& dest, VideoCore::Rect2D dst_rect) { + const Surface& dest, VideoCore::Rect2D dst_rect) { OpenGLState prev_state = OpenGLState::GetCurState(); SCOPE_EXIT({ prev_state.Apply(); }); @@ -46,8 +46,8 @@ void D24S8toRGBA8::Reinterpret(const Surface& source, VideoCore::Rect2D src_rect if (use_texture_view) { temp_tex.Create(); glActiveTexture(GL_TEXTURE1); - glTextureView(temp_tex.handle, GL_TEXTURE_2D, source.texture.handle, GL_DEPTH24_STENCIL8, 0, 1, - 0, 1); + glTextureView(temp_tex.handle, GL_TEXTURE_2D, source.texture.handle, GL_DEPTH24_STENCIL8, 0, + 1, 0, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } else { @@ -70,8 +70,8 @@ void D24S8toRGBA8::Reinterpret(const Surface& source, VideoCore::Rect2D src_rect glActiveTexture(GL_TEXTURE1); if (!use_texture_view) { - glCopyImageSubData(source.texture.handle, GL_TEXTURE_2D, 0, src_rect.left, src_rect.bottom, 0, - temp_tex.handle, GL_TEXTURE_2D, 0, src_rect.left, src_rect.bottom, 0, + glCopyImageSubData(source.texture.handle, GL_TEXTURE_2D, 0, src_rect.left, src_rect.bottom, + 0, temp_tex.handle, GL_TEXTURE_2D, 0, src_rect.left, src_rect.bottom, 0, src_rect.GetWidth(), src_rect.GetHeight(), 1); } glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX); @@ -154,8 +154,7 @@ void RGBA4toRGB5A1::Reinterpret(const Surface& source, VideoCore::Rect2D src_rec glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dest.texture.handle, 0); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, - 0); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); glUniform2i(dst_size_loc, dst_rect.GetWidth(), dst_rect.GetHeight()); glUniform2i(src_size_loc, src_rect.GetWidth(), src_rect.GetHeight()); diff --git a/src/video_core/renderer_opengl/gl_format_reinterpreter.h b/src/video_core/renderer_opengl/gl_format_reinterpreter.h index 3279f8de3..5ffa81460 100644 --- a/src/video_core/renderer_opengl/gl_format_reinterpreter.h +++ b/src/video_core/renderer_opengl/gl_format_reinterpreter.h @@ -16,8 +16,8 @@ public: virtual ~FormatReinterpreterBase() = default; virtual VideoCore::PixelFormat GetSourceFormat() const = 0; - virtual void Reinterpret(const Surface& source, VideoCore::Rect2D src_rect, - const Surface& dest, VideoCore::Rect2D dst_rect) = 0; + virtual void Reinterpret(const Surface& source, VideoCore::Rect2D src_rect, const Surface& dest, + VideoCore::Rect2D dst_rect) = 0; }; using ReinterpreterList = std::vector>; @@ -30,8 +30,8 @@ public: return VideoCore::PixelFormat::D24S8; } - void Reinterpret(const Surface& source, VideoCore::Rect2D src_rect, - const Surface& dest, VideoCore::Rect2D dst_rect) override; + void Reinterpret(const Surface& source, VideoCore::Rect2D src_rect, const Surface& dest, + VideoCore::Rect2D dst_rect) override; private: bool use_texture_view{}; @@ -49,8 +49,8 @@ public: return VideoCore::PixelFormat::RGBA4; } - void Reinterpret(const Surface& source, VideoCore::Rect2D src_rect, - const Surface& dest, VideoCore::Rect2D dst_rect) override; + void Reinterpret(const Surface& source, VideoCore::Rect2D src_rect, const Surface& dest, + VideoCore::Rect2D dst_rect) override; private: OGLFramebuffer read_fbo; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index e1e8afc25..ed6fe7e44 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -39,8 +39,8 @@ static bool IsVendorIntel() { #endif RasterizerOpenGL::RasterizerOpenGL(Frontend::EmuWindow& emu_window, Driver& driver) - : driver{driver}, runtime{driver}, res_cache{*this, runtime}, - is_amd(IsVendorAmd()), vertex_buffer(GL_ARRAY_BUFFER, VERTEX_BUFFER_SIZE, is_amd), + : driver{driver}, runtime{driver}, res_cache{*this, runtime}, is_amd(IsVendorAmd()), + vertex_buffer(GL_ARRAY_BUFFER, VERTEX_BUFFER_SIZE, is_amd), uniform_buffer(GL_UNIFORM_BUFFER, UNIFORM_BUFFER_SIZE, false), index_buffer(GL_ELEMENT_ARRAY_BUFFER, INDEX_BUFFER_SIZE, false), texture_buffer(GL_TEXTURE_BUFFER, TEXTURE_BUFFER_SIZE, false), @@ -687,8 +687,7 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { .pz = regs.texturing.GetCubePhysicalAddress(CubeFace::PositiveZ), .nz = regs.texturing.GetCubePhysicalAddress(CubeFace::NegativeZ), .width = texture.config.width, - .format = texture.format - }; + .format = texture.format}; state.texture_cube_unit.texture_cube = res_cache.GetTextureCube(config)->texture.handle; @@ -729,8 +728,9 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) { // Making a copy to sample from eliminates this issue and seems to be fairly cheap. OGLTexture temp_tex; if (need_duplicate_texture) { - temp_tex = runtime.Allocate(color_surface->GetScaledWidth(), color_surface->GetScaledHeight(), - color_surface->pixel_format, color_surface->texture_type); + temp_tex = + runtime.Allocate(color_surface->GetScaledWidth(), color_surface->GetScaledHeight(), + color_surface->pixel_format, color_surface->texture_type); temp_tex.CopyFrom(color_surface->texture, GL_TEXTURE_2D, color_surface->max_level + 1, color_surface->GetScaledWidth(), color_surface->GetScaledHeight()); @@ -1383,14 +1383,14 @@ bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransfe dst_params.UpdateParams(); auto [src_surface, src_rect] = - res_cache.GetSurfaceSubRect(src_params, VideoCore::ScaleMatch::Ignore, true); + res_cache.GetSurfaceSubRect(src_params, VideoCore::ScaleMatch::Ignore, true); if (src_surface == nullptr) return false; dst_params.res_scale = src_surface->res_scale; auto [dst_surface, dst_rect] = - res_cache.GetSurfaceSubRect(dst_params, VideoCore::ScaleMatch::Upscale, false); + res_cache.GetSurfaceSubRect(dst_params, VideoCore::ScaleMatch::Upscale, false); if (dst_surface == nullptr) { return false; } diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index f563c429c..ca6ac95eb 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -9,10 +9,10 @@ #include "video_core/rasterizer_accelerated.h" #include "video_core/regs_lighting.h" #include "video_core/regs_texturing.h" -#include "video_core/renderer_opengl/gl_texture_runtime.h" #include "video_core/renderer_opengl/gl_shader_manager.h" #include "video_core/renderer_opengl/gl_state.h" #include "video_core/renderer_opengl/gl_stream_buffer.h" +#include "video_core/renderer_opengl/gl_texture_runtime.h" #include "video_core/shader/shader.h" namespace Frontend { diff --git a/src/video_core/renderer_opengl/gl_resource_manager.h b/src/video_core/renderer_opengl/gl_resource_manager.h index 91edc2e20..ecb538f1e 100644 --- a/src/video_core/renderer_opengl/gl_resource_manager.h +++ b/src/video_core/renderer_opengl/gl_resource_manager.h @@ -4,8 +4,8 @@ #pragma once -#include #include +#include #include #include #include "common/common_types.h" diff --git a/src/video_core/renderer_opengl/gl_shader_util.cpp b/src/video_core/renderer_opengl/gl_shader_util.cpp index 6b701db6d..5f73af4e4 100644 --- a/src/video_core/renderer_opengl/gl_shader_util.cpp +++ b/src/video_core/renderer_opengl/gl_shader_util.cpp @@ -25,7 +25,8 @@ GLuint LoadShader(const char* source, GLenum type) { #if defined(GL_EXT_clip_cull_distance) #extension GL_EXT_clip_cull_distance : enable #endif -)" : "#version 430 core\n"; +)" + : "#version 430 core\n"; const char* debug_type; switch (type) { diff --git a/src/video_core/renderer_opengl/gl_texture_runtime.cpp b/src/video_core/renderer_opengl/gl_texture_runtime.cpp index 8b70d5361..f87adbf1c 100644 --- a/src/video_core/renderer_opengl/gl_texture_runtime.cpp +++ b/src/video_core/renderer_opengl/gl_texture_runtime.cpp @@ -4,20 +4,19 @@ #include "common/scope_exit.h" #include "video_core/rasterizer_cache/utils.h" -#include "video_core/renderer_opengl/gl_texture_runtime.h" #include "video_core/renderer_opengl/gl_driver.h" #include "video_core/renderer_opengl/gl_format_reinterpreter.h" #include "video_core/renderer_opengl/gl_state.h" +#include "video_core/renderer_opengl/gl_texture_runtime.h" namespace OpenGL { constexpr FormatTuple DEFAULT_TUPLE = {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE}; static constexpr std::array DEPTH_TUPLES = { - FormatTuple{GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // D16 - FormatTuple{}, - FormatTuple{GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT}, // D24 - FormatTuple{GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // D24S8 + FormatTuple{GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // D16 + FormatTuple{}, FormatTuple{GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT}, // D24 + FormatTuple{GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // D24S8 }; static constexpr std::array COLOR_TUPLES = { @@ -54,13 +53,14 @@ GLbitfield MakeBufferMask(VideoCore::SurfaceType type) { } TextureRuntime::TextureRuntime(Driver& driver) - : driver{driver}, downloader_es{false}, - filterer{Settings::values.texture_filter_name, VideoCore::GetResolutionScaleFactor()}{ + : driver{driver}, downloader_es{false}, filterer{Settings::values.texture_filter_name, + VideoCore::GetResolutionScaleFactor()} { read_fbo.Create(); draw_fbo.Create(); - auto Register = [this](VideoCore::PixelFormat dest, std::unique_ptr&& obj) { + auto Register = [this](VideoCore::PixelFormat dest, + std::unique_ptr&& obj) { const u32 dst_index = static_cast(dest); return reinterpreters[dst_index].push_back(std::move(obj)); }; @@ -90,17 +90,19 @@ const StagingBuffer& TextureRuntime::FindStaging(u32 size, bool upload) { // Allocate a new buffer and map the data to the host std::byte* data = nullptr; if (driver.IsOpenGLES() && driver.HasExtBufferStorage()) { - const GLbitfield storage = upload ? GL_MAP_WRITE_BIT : GL_MAP_READ_BIT | GL_CLIENT_STORAGE_BIT_EXT; - glBufferStorageEXT(target, size, nullptr, storage | GL_MAP_PERSISTENT_BIT_EXT | - GL_MAP_COHERENT_BIT_EXT); - data = reinterpret_cast(glMapBufferRange(target, 0, size, access | GL_MAP_PERSISTENT_BIT_EXT | - GL_MAP_COHERENT_BIT_EXT)); + const GLbitfield storage = + upload ? GL_MAP_WRITE_BIT : GL_MAP_READ_BIT | GL_CLIENT_STORAGE_BIT_EXT; + glBufferStorageEXT(target, size, nullptr, + storage | GL_MAP_PERSISTENT_BIT_EXT | GL_MAP_COHERENT_BIT_EXT); + data = reinterpret_cast(glMapBufferRange( + target, 0, size, access | GL_MAP_PERSISTENT_BIT_EXT | GL_MAP_COHERENT_BIT_EXT)); } else if (driver.HasArbBufferStorage()) { - const GLbitfield storage = upload ? GL_MAP_WRITE_BIT : GL_MAP_READ_BIT | GL_CLIENT_STORAGE_BIT; - glBufferStorage(target, size, nullptr, storage | GL_MAP_PERSISTENT_BIT | - GL_MAP_COHERENT_BIT); - data = reinterpret_cast(glMapBufferRange(target, 0, size, access | GL_MAP_PERSISTENT_BIT | - GL_MAP_COHERENT_BIT)); + const GLbitfield storage = + upload ? GL_MAP_WRITE_BIT : GL_MAP_READ_BIT | GL_CLIENT_STORAGE_BIT; + glBufferStorage(target, size, nullptr, + storage | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT); + data = reinterpret_cast(glMapBufferRange( + target, 0, size, access | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT)); } else { UNIMPLEMENTED(); } @@ -108,10 +110,7 @@ const StagingBuffer& TextureRuntime::FindStaging(u32 size, bool upload) { glBindBuffer(target, 0); StagingBuffer staging = { - .buffer = std::move(buffer), - .mapped = std::span{data, size}, - .size = size - }; + .buffer = std::move(buffer), .mapped = std::span{data, size}, .size = size}; const auto& it = search.emplace(std::move(staging)); return *it; @@ -134,8 +133,8 @@ const FormatTuple& TextureRuntime::GetFormatTuple(VideoCore::PixelFormat pixel_f return DEFAULT_TUPLE; } -void TextureRuntime::FormatConvert(const Surface& surface, bool upload, - std::span source, std::span dest) { +void TextureRuntime::FormatConvert(const Surface& surface, bool upload, std::span source, + std::span dest) { const VideoCore::PixelFormat format = surface.pixel_format; if (format == VideoCore::PixelFormat::RGBA8 && driver.IsOpenGLES()) { return Pica::Texture::ConvertABGRToRGBA(source, dest); @@ -151,13 +150,9 @@ OGLTexture TextureRuntime::Allocate(u32 width, u32 height, VideoCore::PixelForma VideoCore::TextureType type) { const u32 layers = type == VideoCore::TextureType::CubeMap ? 6 : 1; const GLenum target = - type == VideoCore::TextureType::CubeMap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D; + type == VideoCore::TextureType::CubeMap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D; const VideoCore::HostTextureTag key = { - .format = format, - .width = width, - .height = height, - .layers = layers - }; + .format = format, .width = width, .height = height, .layers = layers}; // Attempt to recycle an unused texture if (auto it = texture_recycler.find(key); it != texture_recycler.end()) { @@ -177,8 +172,8 @@ OGLTexture TextureRuntime::Allocate(u32 width, u32 height, VideoCore::PixelForma glActiveTexture(GL_TEXTURE0); glBindTexture(target, texture.handle); - glTexStorage2D(target, std::bit_width(std::max(width, height)), - tuple.internal_format, width, height); + glTexStorage2D(target, std::bit_width(std::max(width, height)), tuple.internal_format, width, + height); glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -250,23 +245,22 @@ bool TextureRuntime::ClearTexture(Surface& surface, const VideoCore::TextureClea return true; } -bool TextureRuntime::CopyTextures(Surface& source, Surface& dest, const VideoCore::TextureCopy& copy) { +bool TextureRuntime::CopyTextures(Surface& source, Surface& dest, + const VideoCore::TextureCopy& copy) { // Emulate texture copy with blit for now const VideoCore::TextureBlit blit = { .src_level = copy.src_level, .dst_level = copy.dst_level, .src_layer = copy.src_layer, .dst_layer = copy.dst_layer, - .src_rect = {copy.src_offset.x, copy.extent.height, - copy.extent.width, copy.src_offset.x}, - .dst_rect = {copy.dst_offset.x, copy.extent.height, - copy.extent.width, copy.dst_offset.x} - }; + .src_rect = {copy.src_offset.x, copy.extent.height, copy.extent.width, copy.src_offset.x}, + .dst_rect = {copy.dst_offset.x, copy.extent.height, copy.extent.width, copy.dst_offset.x}}; return BlitTextures(source, dest, blit); } -bool TextureRuntime::BlitTextures(Surface& source, Surface& dest, const VideoCore::TextureBlit& blit) { +bool TextureRuntime::BlitTextures(Surface& source, Surface& dest, + const VideoCore::TextureBlit& blit) { OpenGLState prev_state = OpenGLState::GetCurState(); SCOPE_EXIT({ prev_state.Apply(); }); @@ -275,12 +269,15 @@ bool TextureRuntime::BlitTextures(Surface& source, Surface& dest, const VideoCor state.draw.draw_framebuffer = draw_fbo.handle; state.Apply(); - const GLenum src_textarget = source.texture_type == VideoCore::TextureType::CubeMap ? - GL_TEXTURE_CUBE_MAP_POSITIVE_X + blit.src_layer : GL_TEXTURE_2D; - BindFramebuffer(GL_READ_FRAMEBUFFER, blit.src_level, src_textarget, source.type, source.texture); + const GLenum src_textarget = source.texture_type == VideoCore::TextureType::CubeMap + ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + blit.src_layer + : GL_TEXTURE_2D; + BindFramebuffer(GL_READ_FRAMEBUFFER, blit.src_level, src_textarget, source.type, + source.texture); - const GLenum dst_textarget = dest.texture_type == VideoCore::TextureType::CubeMap ? - GL_TEXTURE_CUBE_MAP_POSITIVE_X + blit.dst_layer : GL_TEXTURE_2D; + const GLenum dst_textarget = dest.texture_type == VideoCore::TextureType::CubeMap + ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + blit.dst_layer + : GL_TEXTURE_2D; BindFramebuffer(GL_DRAW_FRAMEBUFFER, blit.dst_level, dst_textarget, dest.type, dest.texture); // TODO (wwylele): use GL_NEAREST for shadow map texture @@ -290,9 +287,9 @@ bool TextureRuntime::BlitTextures(Surface& source, Surface& dest, const VideoCor // inconsistent scale. const GLbitfield buffer_mask = MakeBufferMask(source.type); const GLenum filter = buffer_mask == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST; - glBlitFramebuffer(blit.src_rect.left, blit.src_rect.bottom, blit.src_rect.right, blit.src_rect.top, - blit.dst_rect.left, blit.dst_rect.bottom, blit.dst_rect.right, blit.dst_rect.top, - buffer_mask, filter); + glBlitFramebuffer(blit.src_rect.left, blit.src_rect.bottom, blit.src_rect.right, + blit.src_rect.top, blit.dst_rect.left, blit.dst_rect.bottom, + blit.dst_rect.right, blit.dst_rect.top, buffer_mask, filter); return true; } @@ -310,7 +307,8 @@ void TextureRuntime::GenerateMipmaps(Surface& surface, u32 max_level) { glGenerateMipmap(GL_TEXTURE_2D); } -const ReinterpreterList& TextureRuntime::GetPossibleReinterpretations(VideoCore::PixelFormat dest_format) const { +const ReinterpreterList& TextureRuntime::GetPossibleReinterpretations( + VideoCore::PixelFormat dest_format) const { return reinterpreters[static_cast(dest_format)]; } @@ -332,7 +330,8 @@ void TextureRuntime::BindFramebuffer(GLenum target, GLint level, GLenum textarge break; case VideoCore::SurfaceType::DepthStencil: glFramebufferTexture2D(target, GL_COLOR_ATTACHMENT0, textarget, 0, 0); - glFramebufferTexture2D(target, GL_DEPTH_STENCIL_ATTACHMENT, textarget, texture.handle, level); + glFramebufferTexture2D(target, GL_DEPTH_STENCIL_ATTACHMENT, textarget, texture.handle, + level); break; default: UNREACHABLE_MSG("Invalid surface type!"); @@ -342,7 +341,8 @@ void TextureRuntime::BindFramebuffer(GLenum target, GLint level, GLenum textarge Surface::Surface(VideoCore::SurfaceParams& params, TextureRuntime& runtime) : VideoCore::SurfaceBase{params}, runtime{runtime}, driver{runtime.GetDriver()} { if (pixel_format != VideoCore::PixelFormat::Invalid) { - texture = runtime.Allocate(GetScaledWidth(), GetScaledHeight(), params.pixel_format, texture_type); + texture = runtime.Allocate(GetScaledWidth(), GetScaledHeight(), params.pixel_format, + texture_type); } } @@ -352,8 +352,7 @@ Surface::~Surface() { .format = pixel_format, .width = GetScaledWidth(), .height = GetScaledHeight(), - .layers = texture_type == VideoCore::TextureType::CubeMap ? 6u : 1u - }; + .layers = texture_type == VideoCore::TextureType::CubeMap ? 6u : 1u}; runtime.texture_recycler.emplace(tag, std::move(texture)); } @@ -380,11 +379,9 @@ void Surface::Upload(const VideoCore::BufferTextureCopy& upload, const StagingBu glBindTexture(GL_TEXTURE_2D, texture.handle); const auto& tuple = runtime.GetFormatTuple(pixel_format); - glTexSubImage2D(GL_TEXTURE_2D, upload.texture_level, - upload.texture_rect.left, upload.texture_rect.bottom, - upload.texture_rect.GetWidth(), - upload.texture_rect.GetHeight(), - tuple.format, tuple.type, 0); + glTexSubImage2D(GL_TEXTURE_2D, upload.texture_level, upload.texture_rect.left, + upload.texture_rect.bottom, upload.texture_rect.GetWidth(), + upload.texture_rect.GetHeight(), tuple.format, tuple.type, 0); } glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); @@ -412,7 +409,8 @@ void Surface::Download(const VideoCore::BufferTextureCopy& download, const Stagi if (is_scaled) { ScaledDownload(download); } else { - runtime.BindFramebuffer(GL_READ_FRAMEBUFFER, download.texture_level, GL_TEXTURE_2D, type, texture); + runtime.BindFramebuffer(GL_READ_FRAMEBUFFER, download.texture_level, GL_TEXTURE_2D, type, + texture); const auto& tuple = runtime.GetFormatTuple(pixel_format); glReadPixels(download.texture_rect.left, download.texture_rect.bottom, @@ -429,15 +427,16 @@ void Surface::ScaledDownload(const VideoCore::BufferTextureCopy& download) { const u32 rect_height = download.texture_rect.GetHeight(); // Allocate an unscaled texture that fits the download rectangle to use as a blit destination - OGLTexture unscaled_tex = runtime.Allocate(rect_width, rect_height, pixel_format, - VideoCore::TextureType::Texture2D); + OGLTexture unscaled_tex = + runtime.Allocate(rect_width, rect_height, pixel_format, VideoCore::TextureType::Texture2D); runtime.BindFramebuffer(GL_DRAW_FRAMEBUFFER, 0, GL_TEXTURE_2D, type, unscaled_tex); - runtime.BindFramebuffer(GL_READ_FRAMEBUFFER, download.texture_level, GL_TEXTURE_2D, type, texture); + runtime.BindFramebuffer(GL_READ_FRAMEBUFFER, download.texture_level, GL_TEXTURE_2D, type, + texture); // Blit the scaled rectangle to the unscaled texture const VideoCore::Rect2D scaled_rect = download.texture_rect * res_scale; - glBlitFramebuffer(scaled_rect.left, scaled_rect.bottom, scaled_rect.right, scaled_rect.top, - 0, 0, rect_width, rect_height, MakeBufferMask(type), GL_LINEAR); + glBlitFramebuffer(scaled_rect.left, scaled_rect.bottom, scaled_rect.right, scaled_rect.top, 0, + 0, rect_width, rect_height, MakeBufferMask(type), GL_LINEAR); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, unscaled_tex.handle); @@ -445,8 +444,8 @@ void Surface::ScaledDownload(const VideoCore::BufferTextureCopy& download) { const auto& tuple = runtime.GetFormatTuple(pixel_format); if (driver.IsOpenGLES()) { const auto& downloader_es = runtime.GetDownloaderES(); - downloader_es.GetTexImage(GL_TEXTURE_2D, 0, tuple.format, tuple.type, - rect_height, rect_width, 0); + downloader_es.GetTexImage(GL_TEXTURE_2D, 0, tuple.format, tuple.type, rect_height, + rect_width, 0); } else { glGetTexImage(GL_TEXTURE_2D, 0, tuple.format, tuple.type, 0); } @@ -456,8 +455,8 @@ void Surface::ScaledUpload(const VideoCore::BufferTextureCopy& upload) { const u32 rect_width = upload.texture_rect.GetWidth(); const u32 rect_height = upload.texture_rect.GetHeight(); - OGLTexture unscaled_tex = runtime.Allocate(rect_width, rect_height, pixel_format, - VideoCore::TextureType::Texture2D); + OGLTexture unscaled_tex = + runtime.Allocate(rect_width, rect_height, pixel_format, VideoCore::TextureType::Texture2D); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, unscaled_tex.handle); @@ -470,13 +469,13 @@ void Surface::ScaledUpload(const VideoCore::BufferTextureCopy& upload) { const auto& filterer = runtime.GetFilterer(); if (!filterer.Filter(unscaled_tex, unscaled_rect, texture, scaled_rect, type)) { runtime.BindFramebuffer(GL_READ_FRAMEBUFFER, 0, GL_TEXTURE_2D, type, unscaled_tex); - runtime.BindFramebuffer(GL_DRAW_FRAMEBUFFER, upload.texture_level, GL_TEXTURE_2D, type, texture); + runtime.BindFramebuffer(GL_DRAW_FRAMEBUFFER, upload.texture_level, GL_TEXTURE_2D, type, + texture); // If filtering fails, resort to normal blitting - glBlitFramebuffer(0, 0, rect_width, rect_height, - upload.texture_rect.left, upload.texture_rect.bottom, - upload.texture_rect.right, upload.texture_rect.top, - MakeBufferMask(type), GL_LINEAR); + glBlitFramebuffer(0, 0, rect_width, rect_height, upload.texture_rect.left, + upload.texture_rect.bottom, upload.texture_rect.right, + upload.texture_rect.top, MakeBufferMask(type), GL_LINEAR); } } diff --git a/src/video_core/renderer_opengl/gl_texture_runtime.h b/src/video_core/renderer_opengl/gl_texture_runtime.h index 1a9fb6a36..01d7085b7 100644 --- a/src/video_core/renderer_opengl/gl_texture_runtime.h +++ b/src/video_core/renderer_opengl/gl_texture_runtime.h @@ -3,13 +3,13 @@ // Refer to the license.txt file included. #pragma once -#include #include +#include #include "video_core/rasterizer_cache/rasterizer_cache.h" #include "video_core/rasterizer_cache/surface_base.h" #include "video_core/renderer_opengl/gl_format_reinterpreter.h" -#include "video_core/renderer_opengl/texture_filters/texture_filterer.h" #include "video_core/renderer_opengl/texture_downloader_es.h" +#include "video_core/renderer_opengl/texture_filters/texture_filterer.h" namespace OpenGL { @@ -59,6 +59,7 @@ class Surface; */ class TextureRuntime { friend class Surface; + public: TextureRuntime(Driver& driver); ~TextureRuntime() = default; @@ -72,8 +73,8 @@ public: void Finish() const {} /// Performs required format convertions on the staging data - void FormatConvert(const Surface& surface, bool upload, - std::span source, std::span dest); + void FormatConvert(const Surface& surface, bool upload, std::span source, + std::span dest); /// Allocates an OpenGL texture with the specified dimentions and format OGLTexture Allocate(u32 width, u32 height, VideoCore::PixelFormat format, @@ -94,12 +95,12 @@ public: /// Returns all source formats that support reinterpretation to the dest format [[nodiscard]] const ReinterpreterList& GetPossibleReinterpretations( - VideoCore::PixelFormat dest_format) const; + VideoCore::PixelFormat dest_format) const; private: /// Returns the framebuffer used for texture downloads - void BindFramebuffer(GLenum target, GLint level, GLenum textarget, - VideoCore::SurfaceType type, OGLTexture& texture) const; + void BindFramebuffer(GLenum target, GLint level, GLenum textarget, VideoCore::SurfaceType type, + OGLTexture& texture) const; /// Returns the OpenGL driver class const Driver& GetDriver() const { diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 36533c003..0beab3b1c 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -575,7 +575,7 @@ void RendererOpenGL::LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& fram ASSERT(pixel_stride % 4 == 0); if (!rasterizer->AccelerateDisplay(framebuffer, framebuffer_addr, - static_cast(pixel_stride), screen_info)) { + static_cast(pixel_stride), screen_info)) { // Reset the screen info's display texture to its own permanent texture screen_info.display_texture = screen_info.texture.resource.handle; screen_info.display_texcoords = Common::Rectangle(0.f, 0.f, 1.f, 1.f); diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index ba6979b8f..981874d5d 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h @@ -7,8 +7,8 @@ #include #include "core/hw/gpu.h" #include "video_core/renderer_base.h" -#include "video_core/renderer_opengl/gl_driver.h" #include "video_core/renderer_opengl/frame_dumper_opengl.h" +#include "video_core/renderer_opengl/gl_driver.h" #include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_state.h" diff --git a/src/video_core/renderer_opengl/texture_downloader_es.cpp b/src/video_core/renderer_opengl/texture_downloader_es.cpp index e8704e8de..06b6a8a59 100644 --- a/src/video_core/renderer_opengl/texture_downloader_es.cpp +++ b/src/video_core/renderer_opengl/texture_downloader_es.cpp @@ -17,10 +17,9 @@ namespace OpenGL { static constexpr std::array DEPTH_TUPLES_HACK = { - FormatTuple{GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // D16 - FormatTuple{}, - FormatTuple{GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT}, // D24 - FormatTuple{GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // D24S8 + FormatTuple{GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // D16 + FormatTuple{}, FormatTuple{GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT}, // D24 + FormatTuple{GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // D24S8 }; const FormatTuple& GetFormatTuple(VideoCore::PixelFormat format) { diff --git a/src/video_core/renderer_opengl/texture_downloader_es.h b/src/video_core/renderer_opengl/texture_downloader_es.h index 88616671e..c5c3d9a5a 100644 --- a/src/video_core/renderer_opengl/texture_downloader_es.h +++ b/src/video_core/renderer_opengl/texture_downloader_es.h @@ -12,6 +12,7 @@ class OpenGLState; class TextureDownloaderES { static constexpr u16 MAX_SIZE = 1024; + public: TextureDownloaderES(bool enable_depth_stencil); @@ -22,16 +23,16 @@ public: * Depth texture download assumes that the texture's format tuple matches what is found * OpenGL::depth_format_tuples */ - void GetTexImage(GLenum target, GLuint level, GLenum format, const GLenum type, - GLint height, GLint width, void* pixels) const; + void GetTexImage(GLenum target, GLuint level, GLenum format, const GLenum type, GLint height, + GLint width, void* pixels) const; private: /** * OpenGL ES does not support glReadBuffer for depth/stencil formats. * This gets around it by converting to a Red surface before downloading */ - GLuint ConvertDepthToColor(GLuint level, GLenum& format, GLenum& type, - GLint height, GLint width) const; + GLuint ConvertDepthToColor(GLuint level, GLenum& format, GLenum& type, GLint height, + GLint width) const; /// Self tests for the texture downloader void Test(); diff --git a/src/video_core/renderer_opengl/texture_filters/texture_filterer.cpp b/src/video_core/renderer_opengl/texture_filters/texture_filterer.cpp index f299f37a2..d3310cf27 100644 --- a/src/video_core/renderer_opengl/texture_filters/texture_filterer.cpp +++ b/src/video_core/renderer_opengl/texture_filters/texture_filterer.cpp @@ -63,7 +63,8 @@ bool TextureFilterer::Filter(const OGLTexture& src_tex, Common::Rectangle s VideoCore::SurfaceType type) const { // Depth/Stencil texture filtering is not supported for now - if (IsNull() || (type != VideoCore::SurfaceType::Color && type != VideoCore::SurfaceType::Texture)) { + if (IsNull() || + (type != VideoCore::SurfaceType::Color && type != VideoCore::SurfaceType::Texture)) { return false; } diff --git a/src/video_core/renderer_vulkan/pica_to_vk.h b/src/video_core/renderer_vulkan/pica_to_vk.h index 33f04225d..1d8643c53 100644 --- a/src/video_core/renderer_vulkan/pica_to_vk.h +++ b/src/video_core/renderer_vulkan/pica_to_vk.h @@ -19,15 +19,10 @@ struct FilterInfo { }; inline FilterInfo TextureFilterMode(TextureFilter mag, TextureFilter min, TextureFilter mip) { - constexpr std::array filter_table = { - vk::Filter::eNearest, - vk::Filter::eLinear - }; + constexpr std::array filter_table = {vk::Filter::eNearest, vk::Filter::eLinear}; - constexpr std::array mipmap_table = { - vk::SamplerMipmapMode::eNearest, - vk::SamplerMipmapMode::eLinear - }; + constexpr std::array mipmap_table = {vk::SamplerMipmapMode::eNearest, + vk::SamplerMipmapMode::eLinear}; return FilterInfo{filter_table.at(mag), filter_table.at(min), mipmap_table.at(mip)}; } @@ -118,21 +113,21 @@ inline vk::BlendOp BlendEquation(Pica::FramebufferRegs::BlendEquation equation) inline vk::BlendFactor BlendFunc(Pica::FramebufferRegs::BlendFactor factor) { static constexpr std::array blend_func_table{{ - vk::BlendFactor::eZero, // BlendFactor::Zero - vk::BlendFactor::eOne, // BlendFactor::One - vk::BlendFactor::eSrcColor, // BlendFactor::SourceColor - vk::BlendFactor::eOneMinusSrcColor, // BlendFactor::OneMinusSourceColor - vk::BlendFactor::eDstColor, // BlendFactor::DestColor - vk::BlendFactor::eOneMinusDstColor, // BlendFactor::OneMinusDestColor - vk::BlendFactor::eSrcAlpha, // BlendFactor::SourceAlpha - vk::BlendFactor::eOneMinusSrcAlpha, // BlendFactor::OneMinusSourceAlpha - vk::BlendFactor::eDstAlpha, // BlendFactor::DestAlpha - vk::BlendFactor::eOneMinusDstAlpha, // BlendFactor::OneMinusDestAlpha - vk::BlendFactor::eConstantColor, // BlendFactor::ConstantColor - vk::BlendFactor::eOneMinusConstantColor,// BlendFactor::OneMinusConstantColor - vk::BlendFactor::eConstantAlpha, // BlendFactor::ConstantAlpha - vk::BlendFactor::eOneMinusConstantAlpha,// BlendFactor::OneMinusConstantAlpha - vk::BlendFactor::eSrcAlphaSaturate, // BlendFactor::SourceAlphaSaturate + vk::BlendFactor::eZero, // BlendFactor::Zero + vk::BlendFactor::eOne, // BlendFactor::One + vk::BlendFactor::eSrcColor, // BlendFactor::SourceColor + vk::BlendFactor::eOneMinusSrcColor, // BlendFactor::OneMinusSourceColor + vk::BlendFactor::eDstColor, // BlendFactor::DestColor + vk::BlendFactor::eOneMinusDstColor, // BlendFactor::OneMinusDestColor + vk::BlendFactor::eSrcAlpha, // BlendFactor::SourceAlpha + vk::BlendFactor::eOneMinusSrcAlpha, // BlendFactor::OneMinusSourceAlpha + vk::BlendFactor::eDstAlpha, // BlendFactor::DestAlpha + vk::BlendFactor::eOneMinusDstAlpha, // BlendFactor::OneMinusDestAlpha + vk::BlendFactor::eConstantColor, // BlendFactor::ConstantColor + vk::BlendFactor::eOneMinusConstantColor, // BlendFactor::OneMinusConstantColor + vk::BlendFactor::eConstantAlpha, // BlendFactor::ConstantAlpha + vk::BlendFactor::eOneMinusConstantAlpha, // BlendFactor::OneMinusConstantAlpha + vk::BlendFactor::eSrcAlphaSaturate, // BlendFactor::SourceAlphaSaturate }}; const auto index = static_cast(factor); @@ -208,14 +203,14 @@ inline vk::CompareOp CompareFunc(Pica::FramebufferRegs::CompareFunc func) { inline vk::StencilOp StencilOp(Pica::FramebufferRegs::StencilAction action) { static constexpr std::array stencil_op_table{{ - vk::StencilOp::eKeep, // StencilAction::Keep - vk::StencilOp::eZero, // StencilAction::Zero - vk::StencilOp::eReplace, // StencilAction::Replace - vk::StencilOp::eIncrementAndClamp, // StencilAction::Increment - vk::StencilOp::eDecrementAndClamp, // StencilAction::Decrement - vk::StencilOp::eInvert, // StencilAction::Invert - vk::StencilOp::eIncrementAndWrap, // StencilAction::IncrementWrap - vk::StencilOp::eDecrementAndWrap, // StencilAction::DecrementWrap + vk::StencilOp::eKeep, // StencilAction::Keep + vk::StencilOp::eZero, // StencilAction::Zero + vk::StencilOp::eReplace, // StencilAction::Replace + vk::StencilOp::eIncrementAndClamp, // StencilAction::Increment + vk::StencilOp::eDecrementAndClamp, // StencilAction::Decrement + vk::StencilOp::eInvert, // StencilAction::Invert + vk::StencilOp::eIncrementAndWrap, // StencilAction::IncrementWrap + vk::StencilOp::eDecrementAndWrap, // StencilAction::DecrementWrap }}; const auto index = static_cast(action); @@ -281,4 +276,4 @@ inline Common::Vec3f LightColor(const Pica::LightingRegs::LightColor& color) { return Common::Vec3u{color.r, color.g, color.b} / 255.0f; } -} // namespace PicaToGL +} // namespace PicaToVK diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index f923b0c28..2f217785f 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -140,12 +140,11 @@ void main() { } )"; - /// Vertex structure that the drawn screen rectangles are composed of. struct ScreenRectVertex { ScreenRectVertex() = default; - ScreenRectVertex(float x, float y, float u, float v) : - position{Common::MakeVec(x, y)}, tex_coord{Common::MakeVec(u, v)} {} + ScreenRectVertex(float x, float y, float u, float v) + : position{Common::MakeVec(x, y)}, tex_coord{Common::MakeVec(u, v)} {} Common::Vec2f position; Common::Vec2f tex_coord; @@ -154,11 +153,12 @@ struct ScreenRectVertex { constexpr u32 VERTEX_BUFFER_SIZE = sizeof(ScreenRectVertex) * 8192; RendererVulkan::RendererVulkan(Frontend::EmuWindow& window) - : RendererBase{window}, instance{window, Settings::values.physical_device, 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, {}} { + : RendererBase{window}, instance{window, Settings::values.physical_device, + 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(); constexpr auto user_system = Common::Telemetry::FieldType::UserSystem; @@ -192,8 +192,7 @@ RendererVulkan::~RendererVulkan() { .format = VideoCore::PixelFormatFromGPUPixelFormat(info.texture.format), .width = info.texture.width, .height = info.texture.height, - .layers = 1 - }; + .layers = 1}; runtime.Recycle(tag, std::move(info.texture.alloc)); } @@ -207,8 +206,8 @@ VideoCore::ResultStatus RendererVulkan::Init() { BuildPipelines(); // Create the rasterizer - rasterizer = std::make_unique(render_window, instance, scheduler, - runtime, renderpass_cache); + rasterizer = std::make_unique(render_window, instance, scheduler, runtime, + renderpass_cache); return VideoCore::ResultStatus::Success; } @@ -237,13 +236,8 @@ void RendererVulkan::PrepareRendertarget() { if (color_fill.is_enabled) { const vk::ClearColorValue clear_color = { - .float32 = std::array{ - color_fill.color_r / 255.0f, - color_fill.color_g / 255.0f, - color_fill.color_b / 255.0f, - 1.0f - } - }; + .float32 = std::array{color_fill.color_r / 255.0f, color_fill.color_g / 255.0f, + color_fill.color_b / 255.0f, 1.0f}}; const vk::ImageSubresourceRange range = { .aspectMask = vk::ImageAspectFlagBits::eColor, @@ -255,13 +249,14 @@ void RendererVulkan::PrepareRendertarget() { vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); TextureInfo& texture = screen_infos[i].texture; - runtime.Transition(command_buffer, texture.alloc, vk::ImageLayout::eTransferDstOptimal, 0, texture.alloc.levels); - command_buffer.clearColorImage(texture.alloc.image, vk::ImageLayout::eTransferDstOptimal, - clear_color, range); + runtime.Transition(command_buffer, texture.alloc, vk::ImageLayout::eTransferDstOptimal, + 0, texture.alloc.levels); + command_buffer.clearColorImage( + texture.alloc.image, vk::ImageLayout::eTransferDstOptimal, clear_color, range); } else { TextureInfo& texture = screen_infos[i].texture; if (texture.width != framebuffer.width || texture.height != framebuffer.height || - texture.format != framebuffer.color_format) { + texture.format != framebuffer.color_format) { // Reallocate texture if the framebuffer size has changed. // This is expected to not happen very often and hence should not be a @@ -280,7 +275,8 @@ void RendererVulkan::PrepareRendertarget() { void RendererVulkan::BeginRendering() { vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); - command_buffer.bindPipeline(vk::PipelineBindPoint::eGraphics, present_pipelines[current_pipeline]); + command_buffer.bindPipeline(vk::PipelineBindPoint::eGraphics, + present_pipelines[current_pipeline]); std::array present_textures; for (std::size_t i = 0; i < screen_infos.size(); i++) { @@ -288,38 +284,29 @@ void RendererVulkan::BeginRendering() { present_textures[i] = vk::DescriptorImageInfo{ .imageView = info.display_texture ? info.display_texture->image_view : info.texture.alloc.image_view, - .imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal - }; + .imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal}; } - present_textures[3] = vk::DescriptorImageInfo{ - .sampler = present_samplers[current_sampler] - }; + present_textures[3] = vk::DescriptorImageInfo{.sampler = present_samplers[current_sampler]}; - const vk::DescriptorSetAllocateInfo alloc_info = { - .descriptorPool = scheduler.GetDescriptorPool(), - .descriptorSetCount = 1, - .pSetLayouts = &present_descriptor_layout - }; + const vk::DescriptorSetAllocateInfo alloc_info = {.descriptorPool = + scheduler.GetDescriptorPool(), + .descriptorSetCount = 1, + .pSetLayouts = &present_descriptor_layout}; vk::Device device = instance.GetDevice(); vk::DescriptorSet set = device.allocateDescriptorSets(alloc_info)[0]; device.updateDescriptorSetWithTemplate(set, present_update_template, present_textures[0]); - command_buffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, present_pipeline_layout, - 0, 1, &set, 0, nullptr); + command_buffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, present_pipeline_layout, 0, + 1, &set, 0, nullptr); - const vk::ClearValue clear_value = { - .color = clear_color - }; + const vk::ClearValue clear_value = {.color = clear_color}; const vk::RenderPassBeginInfo begin_info = { .renderPass = renderpass_cache.GetPresentRenderpass(), .framebuffer = swapchain.GetFramebuffer(), - .renderArea = vk::Rect2D{ - .offset = {0, 0}, - .extent = swapchain.GetExtent() - }, + .renderArea = vk::Rect2D{.offset = {0, 0}, .extent = swapchain.GetExtent()}, .clearValueCount = 1, .pClearValues = &clear_value, }; @@ -352,7 +339,8 @@ void RendererVulkan::LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& fram // only allows rows to have a memory alignement of 4. ASSERT(pixel_stride % 4 == 0); - if (!rasterizer->AccelerateDisplay(framebuffer, framebuffer_addr, static_cast(pixel_stride), screen_info)) { + if (!rasterizer->AccelerateDisplay(framebuffer, framebuffer_addr, + static_cast(pixel_stride), screen_info)) { ASSERT(false); // Reset the screen info's display texture to its own permanent texture /*screen_info.display_texture = &screen_info.texture; @@ -370,14 +358,14 @@ void RendererVulkan::LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& fram void RendererVulkan::CompileShaders() { vk::Device device = instance.GetDevice(); - present_vertex_shader = Compile(vertex_shader, vk::ShaderStageFlagBits::eVertex, - device, ShaderOptimization::Debug); - present_shaders[0] = Compile(fragment_shader, vk::ShaderStageFlagBits::eFragment, - device, ShaderOptimization::Debug); + present_vertex_shader = + Compile(vertex_shader, vk::ShaderStageFlagBits::eVertex, device, ShaderOptimization::Debug); + present_shaders[0] = Compile(fragment_shader, vk::ShaderStageFlagBits::eFragment, device, + ShaderOptimization::Debug); present_shaders[1] = Compile(fragment_shader_anaglyph, vk::ShaderStageFlagBits::eFragment, - device, ShaderOptimization::Debug); + device, ShaderOptimization::Debug); present_shaders[2] = Compile(fragment_shader_interlaced, vk::ShaderStageFlagBits::eFragment, - device, ShaderOptimization::Debug); + device, ShaderOptimization::Debug); auto properties = instance.GetPhysicalDevice().getProperties(); for (std::size_t i = 0; i < present_samplers.size(); i++) { @@ -393,8 +381,7 @@ void RendererVulkan::CompileShaders() { .compareEnable = false, .compareOp = vk::CompareOp::eAlways, .borderColor = vk::BorderColor::eIntOpaqueBlack, - .unnormalizedCoordinates = false - }; + .unnormalizedCoordinates = false}; present_samplers[i] = device.createSampler(sampler_info); } @@ -402,53 +389,41 @@ void RendererVulkan::CompileShaders() { void RendererVulkan::BuildLayouts() { const std::array present_layout_bindings = { - vk::DescriptorSetLayoutBinding{ - .binding = 0, - .descriptorType = vk::DescriptorType::eSampledImage, - .descriptorCount = 3, - .stageFlags = vk::ShaderStageFlagBits::eFragment - }, - vk::DescriptorSetLayoutBinding{ - .binding = 1, - .descriptorType = vk::DescriptorType::eSampler, - .descriptorCount = 1, - .stageFlags = vk::ShaderStageFlagBits::eFragment - } - }; + vk::DescriptorSetLayoutBinding{.binding = 0, + .descriptorType = vk::DescriptorType::eSampledImage, + .descriptorCount = 3, + .stageFlags = vk::ShaderStageFlagBits::eFragment}, + vk::DescriptorSetLayoutBinding{.binding = 1, + .descriptorType = vk::DescriptorType::eSampler, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eFragment}}; const vk::DescriptorSetLayoutCreateInfo present_layout_info = { .bindingCount = static_cast(present_layout_bindings.size()), - .pBindings = present_layout_bindings.data() - }; + .pBindings = present_layout_bindings.data()}; vk::Device device = instance.GetDevice(); present_descriptor_layout = device.createDescriptorSetLayout(present_layout_info); const std::array update_template_entries = { - vk::DescriptorUpdateTemplateEntry{ - .dstBinding = 0, - .dstArrayElement = 0, - .descriptorCount = 3, - .descriptorType = vk::DescriptorType::eSampledImage, - .offset = 0, - .stride = sizeof(vk::DescriptorImageInfo) - }, - vk::DescriptorUpdateTemplateEntry{ - .dstBinding = 1, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = vk::DescriptorType::eSampler, - .offset = 3 * sizeof(vk::DescriptorImageInfo), - .stride = 0 - } - }; + vk::DescriptorUpdateTemplateEntry{.dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = 3, + .descriptorType = vk::DescriptorType::eSampledImage, + .offset = 0, + .stride = sizeof(vk::DescriptorImageInfo)}, + vk::DescriptorUpdateTemplateEntry{.dstBinding = 1, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eSampler, + .offset = 3 * sizeof(vk::DescriptorImageInfo), + .stride = 0}}; const vk::DescriptorUpdateTemplateCreateInfo template_info = { .descriptorUpdateEntryCount = static_cast(update_template_entries.size()), .pDescriptorUpdateEntries = update_template_entries.data(), .templateType = vk::DescriptorUpdateTemplateType::eDescriptorSet, - .descriptorSetLayout = present_descriptor_layout - }; + .descriptorSetLayout = present_descriptor_layout}; present_update_template = device.createDescriptorUpdateTemplate(template_info); @@ -458,49 +433,37 @@ void RendererVulkan::BuildLayouts() { .size = sizeof(PresentUniformData), }; - const vk::PipelineLayoutCreateInfo layout_info = { - .setLayoutCount = 1, - .pSetLayouts = &present_descriptor_layout, - .pushConstantRangeCount = 1, - .pPushConstantRanges = &push_range - }; + const vk::PipelineLayoutCreateInfo layout_info = {.setLayoutCount = 1, + .pSetLayouts = &present_descriptor_layout, + .pushConstantRangeCount = 1, + .pPushConstantRanges = &push_range}; present_pipeline_layout = device.createPipelineLayout(layout_info); } void RendererVulkan::BuildPipelines() { - const vk::VertexInputBindingDescription binding = { - .binding = 0, - .stride = sizeof(ScreenRectVertex), - .inputRate = vk::VertexInputRate::eVertex - }; + const vk::VertexInputBindingDescription binding = {.binding = 0, + .stride = sizeof(ScreenRectVertex), + .inputRate = vk::VertexInputRate::eVertex}; const std::array attributes = { - vk::VertexInputAttributeDescription{ - .location = 0, - .binding = 0, - .format = vk::Format::eR32G32Sfloat, - .offset = offsetof(ScreenRectVertex, position) - }, - vk::VertexInputAttributeDescription{ - .location = 1, - .binding = 0, - .format = vk::Format::eR32G32Sfloat, - .offset = offsetof(ScreenRectVertex, tex_coord) - } - }; + vk::VertexInputAttributeDescription{.location = 0, + .binding = 0, + .format = vk::Format::eR32G32Sfloat, + .offset = offsetof(ScreenRectVertex, position)}, + vk::VertexInputAttributeDescription{.location = 1, + .binding = 0, + .format = vk::Format::eR32G32Sfloat, + .offset = offsetof(ScreenRectVertex, tex_coord)}}; const vk::PipelineVertexInputStateCreateInfo vertex_input_info = { .vertexBindingDescriptionCount = 1, .pVertexBindingDescriptions = &binding, .vertexAttributeDescriptionCount = static_cast(attributes.size()), - .pVertexAttributeDescriptions = attributes.data() - }; + .pVertexAttributeDescriptions = attributes.data()}; const vk::PipelineInputAssemblyStateCreateInfo input_assembly = { - .topology = vk::PrimitiveTopology::eTriangleStrip, - .primitiveRestartEnable = false - }; + .topology = vk::PrimitiveTopology::eTriangleStrip, .primitiveRestartEnable = false}; const vk::PipelineRasterizationStateCreateInfo raster_state = { .depthClampEnable = false, @@ -508,26 +471,21 @@ void RendererVulkan::BuildPipelines() { .cullMode = vk::CullModeFlagBits::eNone, .frontFace = vk::FrontFace::eClockwise, .depthBiasEnable = false, - .lineWidth = 1.0f - }; + .lineWidth = 1.0f}; const vk::PipelineMultisampleStateCreateInfo multisampling = { - .rasterizationSamples = vk::SampleCountFlagBits::e1, - .sampleShadingEnable = false - }; + .rasterizationSamples = vk::SampleCountFlagBits::e1, .sampleShadingEnable = false}; const vk::PipelineColorBlendAttachmentState colorblend_attachment = { .blendEnable = false, .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | - vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA - }; + vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA}; const vk::PipelineColorBlendStateCreateInfo color_blending = { .logicOpEnable = false, .attachmentCount = 1, .pAttachments = &colorblend_attachment, - .blendConstants = std::array{1.0f, 1.0f, 1.0f, 1.0f} - }; + .blendConstants = std::array{1.0f, 1.0f, 1.0f, 1.0f}}; const vk::Viewport placeholder_viewport = vk::Viewport{0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f}; const vk::Rect2D placeholder_scissor = vk::Rect2D{{0, 0}, {1, 1}}; @@ -538,36 +496,27 @@ void RendererVulkan::BuildPipelines() { .pScissors = &placeholder_scissor, }; - const std::array dynamic_states = { - vk::DynamicState::eViewport, - vk::DynamicState::eScissor - }; + const std::array dynamic_states = {vk::DynamicState::eViewport, vk::DynamicState::eScissor}; const vk::PipelineDynamicStateCreateInfo dynamic_info = { .dynamicStateCount = static_cast(dynamic_states.size()), - .pDynamicStates = dynamic_states.data() - }; + .pDynamicStates = dynamic_states.data()}; - const vk::PipelineDepthStencilStateCreateInfo depth_info = { - .depthTestEnable = false, - .depthWriteEnable = false, - .depthCompareOp = vk::CompareOp::eAlways, - .depthBoundsTestEnable = false, - .stencilTestEnable = false - }; + const vk::PipelineDepthStencilStateCreateInfo depth_info = {.depthTestEnable = false, + .depthWriteEnable = false, + .depthCompareOp = + vk::CompareOp::eAlways, + .depthBoundsTestEnable = false, + .stencilTestEnable = false}; for (u32 i = 0; i < PRESENT_PIPELINES; i++) { const std::array shader_stages = { - vk::PipelineShaderStageCreateInfo{ - .stage = vk::ShaderStageFlagBits::eVertex, - .module = present_vertex_shader, - .pName = "main" - }, - vk::PipelineShaderStageCreateInfo{ - .stage = vk::ShaderStageFlagBits::eFragment, - .module = present_shaders[i], - .pName = "main" - }, + vk::PipelineShaderStageCreateInfo{.stage = vk::ShaderStageFlagBits::eVertex, + .module = present_vertex_shader, + .pName = "main"}, + vk::PipelineShaderStageCreateInfo{.stage = vk::ShaderStageFlagBits::eFragment, + .module = present_shaders[i], + .pName = "main"}, }; const vk::GraphicsPipelineCreateInfo pipeline_info = { @@ -582,12 +531,11 @@ void RendererVulkan::BuildPipelines() { .pColorBlendState = &color_blending, .pDynamicState = &dynamic_info, .layout = present_pipeline_layout, - .renderPass = renderpass_cache.GetPresentRenderpass() - }; + .renderPass = renderpass_cache.GetPresentRenderpass()}; vk::Device device = instance.GetDevice(); if (const auto result = device.createGraphicsPipeline({}, pipeline_info); - result.result == vk::Result::eSuccess) { + result.result == vk::Result::eSuccess) { present_pipelines[i] = result.value; } else { LOG_CRITICAL(Render_Vulkan, "Unable to build present pipelines"); @@ -596,25 +544,27 @@ void RendererVulkan::BuildPipelines() { } } -void RendererVulkan::ConfigureFramebufferTexture(TextureInfo& texture, const GPU::Regs::FramebufferConfig& framebuffer) { +void RendererVulkan::ConfigureFramebufferTexture(TextureInfo& texture, + const GPU::Regs::FramebufferConfig& framebuffer) { TextureInfo old_texture = texture; texture = TextureInfo{ - .alloc = runtime.Allocate(framebuffer.width, framebuffer.height, - VideoCore::PixelFormatFromGPUPixelFormat(framebuffer.color_format), - VideoCore::TextureType::Texture2D), + .alloc = + runtime.Allocate(framebuffer.width, framebuffer.height, + VideoCore::PixelFormatFromGPUPixelFormat(framebuffer.color_format), + VideoCore::TextureType::Texture2D), .width = framebuffer.width, .height = framebuffer.height, .format = framebuffer.color_format, }; - // Recyle the old texture after allocation to avoid having duplicates of the same allocation in the recycler + // Recyle the old texture after allocation to avoid having duplicates of the same allocation in + // the recycler if (old_texture.width != 0 && old_texture.height != 0) { const VideoCore::HostTextureTag tag = { .format = VideoCore::PixelFormatFromGPUPixelFormat(old_texture.format), .width = old_texture.width, .height = old_texture.height, - .layers = 1 - }; + .layers = 1}; runtime.Recycle(tag, std::move(old_texture.alloc)); } @@ -633,7 +583,7 @@ void RendererVulkan::ReloadPipeline() { case Settings::StereoRenderOption::ReverseInterlaced: current_pipeline = 2; draw_info.reverse_interlaced = - Settings::values.render_3d == Settings::StereoRenderOption::ReverseInterlaced; + Settings::values.render_3d == Settings::StereoRenderOption::ReverseInterlaced; break; default: current_pipeline = 0; @@ -665,15 +615,16 @@ void RendererVulkan::DrawSingleScreenRotated(u32 screen_id, float x, float y, fl const float width = static_cast(screen_info.texture.width); const float height = static_cast(screen_info.texture.height); - draw_info.i_resolution = Common::Vec4f{width * scale_factor, height * scale_factor, - 1.0f / (width * scale_factor), - 1.0f / (height * scale_factor)}; + draw_info.i_resolution = + Common::Vec4f{width * scale_factor, height * scale_factor, 1.0f / (width * scale_factor), + 1.0f / (height * scale_factor)}; draw_info.o_resolution = Common::Vec4f{h, w, 1.0f / h, 1.0f / w}; draw_info.screen_id_l = screen_id; vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); command_buffer.pushConstants(present_pipeline_layout, - vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eVertex, + vk::ShaderStageFlagBits::eFragment | + vk::ShaderStageFlagBits::eVertex, 0, sizeof(draw_info), &draw_info); command_buffer.bindVertexBuffers(0, vertex_buffer.GetHandle(), {0}); @@ -701,20 +652,19 @@ void RendererVulkan::DrawSingleScreen(u32 screen_id, float x, float y, float w, const float width = static_cast(screen_info.texture.width); const float height = static_cast(screen_info.texture.height); - draw_info.i_resolution = Common::Vec4f{width * scale_factor, height * scale_factor, - 1.0f / (width * scale_factor), - 1.0f / (height * scale_factor)}; + draw_info.i_resolution = + Common::Vec4f{width * scale_factor, height * scale_factor, 1.0f / (width * scale_factor), + 1.0f / (height * scale_factor)}; draw_info.o_resolution = Common::Vec4f{h, w, 1.0f / h, 1.0f / w}; draw_info.screen_id_l = screen_id; vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); command_buffer.pushConstants(present_pipeline_layout, - vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eVertex, + vk::ShaderStageFlagBits::eFragment | + vk::ShaderStageFlagBits::eVertex, 0, sizeof(draw_info), &draw_info); - const vk::ClearValue clear_value = { - .color = clear_color - }; + const vk::ClearValue clear_value = {.color = clear_color}; const vk::RenderPassBeginInfo begin_info = { .renderPass = renderpass_cache.GetPresentRenderpass(), @@ -729,20 +679,18 @@ void RendererVulkan::DrawSingleScreen(u32 screen_id, float x, float y, float w, command_buffer.draw(4, 1, offset / sizeof(ScreenRectVertex), 0); } -void RendererVulkan::DrawSingleScreenStereoRotated(u32 screen_id_l, u32 screen_id_r, - float x, float y, float w, float h) { +void RendererVulkan::DrawSingleScreenStereoRotated(u32 screen_id_l, u32 screen_id_r, float x, + float y, float w, float h) { const ScreenInfo& screen_info_l = screen_infos[screen_id_l]; const auto& texcoords = screen_info_l.display_texcoords; u32 size = sizeof(ScreenRectVertex) * 4; auto [ptr, offset, invalidate] = vertex_buffer.Map(size); - const std::array vertices = { - ScreenRectVertex{x, y, texcoords.bottom, texcoords.left}, - ScreenRectVertex{x + w, y, texcoords.bottom, texcoords.right}, - ScreenRectVertex{x, y + h, texcoords.top, texcoords.left}, - ScreenRectVertex{x + w, y + h, texcoords.top, texcoords.right} - }; + const std::array vertices = {ScreenRectVertex{x, y, texcoords.bottom, texcoords.left}, + ScreenRectVertex{x + w, y, texcoords.bottom, texcoords.right}, + ScreenRectVertex{x, y + h, texcoords.top, texcoords.left}, + ScreenRectVertex{x + w, y + h, texcoords.top, texcoords.right}}; std::memcpy(ptr, vertices.data(), size); vertex_buffer.Commit(size); @@ -751,9 +699,9 @@ void RendererVulkan::DrawSingleScreenStereoRotated(u32 screen_id_l, u32 screen_i const float width = static_cast(screen_info_l.texture.width); const float height = static_cast(screen_info_l.texture.height); - draw_info.i_resolution = Common::Vec4f{width * scale_factor, height * scale_factor, - 1.0f / (width * scale_factor), - 1.0f / (height * scale_factor)}; + draw_info.i_resolution = + Common::Vec4f{width * scale_factor, height * scale_factor, 1.0f / (width * scale_factor), + 1.0f / (height * scale_factor)}; draw_info.o_resolution = Common::Vec4f{h, w, 1.0f / h, 1.0f / w}; draw_info.screen_id_l = screen_id_l; @@ -761,15 +709,16 @@ void RendererVulkan::DrawSingleScreenStereoRotated(u32 screen_id_l, u32 screen_i vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); command_buffer.pushConstants(present_pipeline_layout, - vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eVertex, + vk::ShaderStageFlagBits::eFragment | + vk::ShaderStageFlagBits::eVertex, 0, sizeof(draw_info), &draw_info); command_buffer.bindVertexBuffers(0, vertex_buffer.GetHandle(), {0}); command_buffer.draw(4, 1, offset / sizeof(ScreenRectVertex), 0); } -void RendererVulkan::DrawSingleScreenStereo(u32 screen_id_l, u32 screen_id_r, - float x, float y, float w, float h) { +void RendererVulkan::DrawSingleScreenStereo(u32 screen_id_l, u32 screen_id_r, float x, float y, + float w, float h) { const ScreenInfo& screen_info_l = screen_infos[screen_id_l]; const auto& texcoords = screen_info_l.display_texcoords; @@ -790,9 +739,9 @@ void RendererVulkan::DrawSingleScreenStereo(u32 screen_id_l, u32 screen_id_r, const float width = static_cast(screen_info_l.texture.width); const float height = static_cast(screen_info_l.texture.height); - draw_info.i_resolution = Common::Vec4f{width * scale_factor, height * scale_factor, - 1.0f / (width * scale_factor), - 1.0f / (height * scale_factor)}; + draw_info.i_resolution = + Common::Vec4f{width * scale_factor, height * scale_factor, 1.0f / (width * scale_factor), + 1.0f / (height * scale_factor)}; draw_info.o_resolution = Common::Vec4f{w, h, 1.0f / w, 1.0f / h}; draw_info.screen_id_l = screen_id_l; @@ -800,7 +749,8 @@ void RendererVulkan::DrawSingleScreenStereo(u32 screen_id_l, u32 screen_id_r, vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); command_buffer.pushConstants(present_pipeline_layout, - vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eVertex, + vk::ShaderStageFlagBits::eFragment | + vk::ShaderStageFlagBits::eVertex, 0, sizeof(draw_info), &draw_info); command_buffer.bindVertexBuffers(0, vertex_buffer.GetHandle(), {0}); @@ -828,11 +778,11 @@ void RendererVulkan::DrawScreens(const Layout::FramebufferLayout& layout, bool f const auto& bottom_screen = layout.bottom_screen; // Set projection matrix - //draw_info.modelview = - // MakeOrthographicMatrix(static_cast(layout.width), static_cast(layout.height), flipped); - draw_info.modelview = glm::transpose(glm::ortho(0.f, static_cast(layout.width), - static_cast(layout.height), 0.0f, - 0.f, 1.f)); + // draw_info.modelview = + // MakeOrthographicMatrix(static_cast(layout.width), + // static_cast(layout.height), flipped); + draw_info.modelview = glm::transpose(glm::ortho( + 0.f, static_cast(layout.width), static_cast(layout.height), 0.0f, 0.f, 1.f)); const bool stereo_single_screen = Settings::values.render_3d == Settings::StereoRenderOption::Anaglyph || @@ -846,31 +796,29 @@ void RendererVulkan::DrawScreens(const Layout::FramebufferLayout& layout, bool f if (layout.top_screen_enabled) { if (layout.is_rotated) { if (Settings::values.render_3d == Settings::StereoRenderOption::Off) { - DrawSingleScreenRotated(0, top_screen.left, - top_screen.top, top_screen.GetWidth(), + DrawSingleScreenRotated(0, top_screen.left, top_screen.top, top_screen.GetWidth(), top_screen.GetHeight()); } else if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide) { - DrawSingleScreenRotated(0, (float)top_screen.left / 2, - (float)top_screen.top, (float)top_screen.GetWidth() / 2, + DrawSingleScreenRotated(0, (float)top_screen.left / 2, (float)top_screen.top, + (float)top_screen.GetWidth() / 2, (float)top_screen.GetHeight()); draw_info.layer = 1; - DrawSingleScreenRotated(1, - ((float)top_screen.left / 2) + ((float)layout.width / 2), + DrawSingleScreenRotated(1, ((float)top_screen.left / 2) + ((float)layout.width / 2), (float)top_screen.top, (float)top_screen.GetWidth() / 2, (float)top_screen.GetHeight()); } else if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) { - DrawSingleScreenRotated(0, layout.top_screen.left, - layout.top_screen.top, layout.top_screen.GetWidth(), + DrawSingleScreenRotated(0, layout.top_screen.left, layout.top_screen.top, + layout.top_screen.GetWidth(), layout.top_screen.GetHeight()); draw_info.layer = 1; - DrawSingleScreenRotated(1, - layout.cardboard.top_screen_right_eye + - ((float)layout.width / 2), - layout.top_screen.top, layout.top_screen.GetWidth(), - layout.top_screen.GetHeight()); + DrawSingleScreenRotated( + 1, layout.cardboard.top_screen_right_eye + ((float)layout.width / 2), + layout.top_screen.top, layout.top_screen.GetWidth(), + layout.top_screen.GetHeight()); } else if (stereo_single_screen) { DrawSingleScreenStereoRotated(0, 1, (float)top_screen.left, (float)top_screen.top, - (float)top_screen.GetWidth(), (float)top_screen.GetHeight()); + (float)top_screen.GetWidth(), + (float)top_screen.GetHeight()); } } else { if (Settings::values.render_3d == Settings::StereoRenderOption::Off) { @@ -880,8 +828,7 @@ void RendererVulkan::DrawScreens(const Layout::FramebufferLayout& layout, bool f DrawSingleScreen(0, (float)top_screen.left / 2, (float)top_screen.top, (float)top_screen.GetWidth() / 2, (float)top_screen.GetHeight()); draw_info.layer = 1; - DrawSingleScreen(1, - ((float)top_screen.left / 2) + ((float)layout.width / 2), + DrawSingleScreen(1, ((float)top_screen.left / 2) + ((float)layout.width / 2), (float)top_screen.top, (float)top_screen.GetWidth() / 2, (float)top_screen.GetHeight()); } else if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) { @@ -893,9 +840,8 @@ void RendererVulkan::DrawScreens(const Layout::FramebufferLayout& layout, bool f layout.top_screen.top, layout.top_screen.GetWidth(), layout.top_screen.GetHeight()); } else if (stereo_single_screen) { - DrawSingleScreenStereo(0, 1, (float)top_screen.left, - (float)top_screen.top, (float)top_screen.GetWidth(), - (float)top_screen.GetHeight()); + DrawSingleScreenStereo(0, 1, (float)top_screen.left, (float)top_screen.top, + (float)top_screen.GetWidth(), (float)top_screen.GetHeight()); } } } @@ -904,60 +850,55 @@ void RendererVulkan::DrawScreens(const Layout::FramebufferLayout& layout, bool f if (layout.bottom_screen_enabled) { if (layout.is_rotated) { if (Settings::values.render_3d == Settings::StereoRenderOption::Off) { - DrawSingleScreenRotated(2, (float)bottom_screen.left, - (float)bottom_screen.top, (float)bottom_screen.GetWidth(), + DrawSingleScreenRotated(2, (float)bottom_screen.left, (float)bottom_screen.top, + (float)bottom_screen.GetWidth(), (float)bottom_screen.GetHeight()); } else if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide) { - DrawSingleScreenRotated( - 2, (float)bottom_screen.left / 2, (float)bottom_screen.top, - (float)bottom_screen.GetWidth() / 2, (float)bottom_screen.GetHeight()); + DrawSingleScreenRotated(2, (float)bottom_screen.left / 2, (float)bottom_screen.top, + (float)bottom_screen.GetWidth() / 2, + (float)bottom_screen.GetHeight()); draw_info.layer = 1; DrawSingleScreenRotated( 2, ((float)bottom_screen.left / 2) + ((float)layout.width / 2), (float)bottom_screen.top, (float)bottom_screen.GetWidth() / 2, (float)bottom_screen.GetHeight()); } else if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) { - DrawSingleScreenRotated(2, layout.bottom_screen.left, - layout.bottom_screen.top, layout.bottom_screen.GetWidth(), + DrawSingleScreenRotated(2, layout.bottom_screen.left, layout.bottom_screen.top, + layout.bottom_screen.GetWidth(), layout.bottom_screen.GetHeight()); draw_info.layer = 1; - DrawSingleScreenRotated(2, - layout.cardboard.bottom_screen_right_eye + - ((float)layout.width / 2), - layout.bottom_screen.top, layout.bottom_screen.GetWidth(), - layout.bottom_screen.GetHeight()); + DrawSingleScreenRotated( + 2, layout.cardboard.bottom_screen_right_eye + ((float)layout.width / 2), + layout.bottom_screen.top, layout.bottom_screen.GetWidth(), + layout.bottom_screen.GetHeight()); } else if (stereo_single_screen) { - DrawSingleScreenStereoRotated(2, 2, (float)bottom_screen.left, (float)bottom_screen.top, - (float)bottom_screen.GetWidth(), - (float)bottom_screen.GetHeight()); + DrawSingleScreenStereoRotated( + 2, 2, (float)bottom_screen.left, (float)bottom_screen.top, + (float)bottom_screen.GetWidth(), (float)bottom_screen.GetHeight()); } } else { if (Settings::values.render_3d == Settings::StereoRenderOption::Off) { - DrawSingleScreen(2, (float)bottom_screen.left, - (float)bottom_screen.top, (float)bottom_screen.GetWidth(), - (float)bottom_screen.GetHeight()); + DrawSingleScreen(2, (float)bottom_screen.left, (float)bottom_screen.top, + (float)bottom_screen.GetWidth(), (float)bottom_screen.GetHeight()); } else if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide) { - DrawSingleScreen(2, (float)bottom_screen.left / 2, - (float)bottom_screen.top, (float)bottom_screen.GetWidth() / 2, + DrawSingleScreen(2, (float)bottom_screen.left / 2, (float)bottom_screen.top, + (float)bottom_screen.GetWidth() / 2, (float)bottom_screen.GetHeight()); draw_info.layer = 1; - DrawSingleScreen(2, - ((float)bottom_screen.left / 2) + ((float)layout.width / 2), + DrawSingleScreen(2, ((float)bottom_screen.left / 2) + ((float)layout.width / 2), (float)bottom_screen.top, (float)bottom_screen.GetWidth() / 2, (float)bottom_screen.GetHeight()); } else if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) { - DrawSingleScreen(2, layout.bottom_screen.left, - layout.bottom_screen.top, layout.bottom_screen.GetWidth(), - layout.bottom_screen.GetHeight()); + DrawSingleScreen(2, layout.bottom_screen.left, layout.bottom_screen.top, + layout.bottom_screen.GetWidth(), layout.bottom_screen.GetHeight()); draw_info.layer = 1; - DrawSingleScreen(2, - layout.cardboard.bottom_screen_right_eye + - ((float)layout.width / 2), - layout.bottom_screen.top, layout.bottom_screen.GetWidth(), - layout.bottom_screen.GetHeight()); + DrawSingleScreen( + 2, layout.cardboard.bottom_screen_right_eye + ((float)layout.width / 2), + layout.bottom_screen.top, layout.bottom_screen.GetWidth(), + layout.bottom_screen.GetHeight()); } else if (stereo_single_screen) { - DrawSingleScreenStereo(2, 2, (float)bottom_screen.left, - (float)bottom_screen.top, (float)bottom_screen.GetWidth(), + DrawSingleScreenStereo(2, 2, (float)bottom_screen.left, (float)bottom_screen.top, + (float)bottom_screen.GetWidth(), (float)bottom_screen.GetHeight()); } } @@ -980,19 +921,14 @@ void RendererVulkan::SwapBuffers() { const vk::Semaphore present_ready = scheduler.GetPresentReadySemaphore(); swapchain.AcquireNextImage(image_acquired); - const vk::Viewport viewport = { - .x = 0.0f, - .y = 0.0f, - .width = static_cast(layout.width), - .height = static_cast(layout.height), - .minDepth = 0.0f, - .maxDepth = 1.0f - }; + const vk::Viewport viewport = {.x = 0.0f, + .y = 0.0f, + .width = static_cast(layout.width), + .height = static_cast(layout.height), + .minDepth = 0.0f, + .maxDepth = 1.0f}; - const vk::Rect2D scissor = { - .offset = {0, 0}, - .extent = {layout.width, layout.height} - }; + const vk::Rect2D scissor = {.offset = {0, 0}, .extent = {layout.width, layout.height}}; vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); command_buffer.setViewport(0, viewport); @@ -1002,7 +938,8 @@ void RendererVulkan::SwapBuffers() { for (auto& info : screen_infos) { auto alloc = info.display_texture ? info.display_texture : &info.texture.alloc; - runtime.Transition(command_buffer, *alloc, vk::ImageLayout::eShaderReadOnlyOptimal, 0, alloc->levels); + runtime.Transition(command_buffer, *alloc, vk::ImageLayout::eShaderReadOnlyOptimal, 0, + alloc->levels); } DrawScreens(layout, false); diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index 705eee9af..ca7e410a6 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h @@ -10,9 +10,9 @@ #include "common/math_util.h" #include "core/hw/gpu.h" #include "video_core/renderer_base.h" -#include "video_core/renderer_vulkan/vk_swapchain.h" #include "video_core/renderer_vulkan/vk_instance.h" #include "video_core/renderer_vulkan/vk_renderpass_cache.h" +#include "video_core/renderer_vulkan/vk_swapchain.h" #include "video_core/renderer_vulkan/vk_texture_runtime.h" namespace Layout { @@ -81,7 +81,8 @@ private: void CompileShaders(); void BuildLayouts(); void BuildPipelines(); - void ConfigureFramebufferTexture(TextureInfo& texture, const GPU::Regs::FramebufferConfig& framebuffer); + void ConfigureFramebufferTexture(TextureInfo& texture, + const GPU::Regs::FramebufferConfig& framebuffer); void ConfigureRenderPipeline(); void PrepareRendertarget(); void BeginRendering(); @@ -89,8 +90,10 @@ private: void DrawScreens(const Layout::FramebufferLayout& layout, bool flipped); void DrawSingleScreenRotated(u32 screen_id, float x, float y, float w, float h); void DrawSingleScreen(u32 screen_id, float x, float y, float w, float h); - void DrawSingleScreenStereoRotated(u32 screen_id_l, u32 screen_id_r, float x, float y, float w, float h); - void DrawSingleScreenStereo(u32 screen_id_l, u32 screen_id_r, float x, float y, float w, float h); + void DrawSingleScreenStereoRotated(u32 screen_id_l, u32 screen_id_r, float x, float y, float w, + float h); + void DrawSingleScreenStereo(u32 screen_id_l, u32 screen_id_r, float x, float y, float w, + float h); void UpdateFramerate(); diff --git a/src/video_core/renderer_vulkan/vk_common.h b/src/video_core/renderer_vulkan/vk_common.h index 6e1954ffa..765235fca 100644 --- a/src/video_core/renderer_vulkan/vk_common.h +++ b/src/video_core/renderer_vulkan/vk_common.h @@ -41,31 +41,27 @@ constexpr vk::ImageAspectFlags GetImageAspect(vk::Format format) { /// Returns a bit mask with the required usage of a format with a particular aspect constexpr vk::ImageUsageFlags GetImageUsage(vk::ImageAspectFlags aspect) { - auto usage = vk::ImageUsageFlagBits::eSampled | - vk::ImageUsageFlagBits::eTransferDst | - vk::ImageUsageFlagBits::eTransferSrc; + auto usage = vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst | + vk::ImageUsageFlagBits::eTransferSrc; if (aspect & vk::ImageAspectFlagBits::eDepth) { return usage | vk::ImageUsageFlagBits::eDepthStencilAttachment; } else { - return usage | vk::ImageUsageFlagBits::eStorage | - vk::ImageUsageFlagBits::eColorAttachment; + return usage | vk::ImageUsageFlagBits::eStorage | vk::ImageUsageFlagBits::eColorAttachment; } } /// Returns a bit mask with the required features of a format with a particular aspect constexpr vk::FormatFeatureFlags GetFormatFeatures(vk::ImageAspectFlags aspect) { auto usage = vk::FormatFeatureFlagBits::eSampledImage | - vk::FormatFeatureFlagBits::eTransferDst | - vk::FormatFeatureFlagBits::eTransferSrc | - vk::FormatFeatureFlagBits::eBlitSrc | - vk::FormatFeatureFlagBits::eBlitDst; + vk::FormatFeatureFlagBits::eTransferDst | vk::FormatFeatureFlagBits::eTransferSrc | + vk::FormatFeatureFlagBits::eBlitSrc | vk::FormatFeatureFlagBits::eBlitDst; if (aspect & vk::ImageAspectFlagBits::eDepth) { return usage | vk::FormatFeatureFlagBits::eDepthStencilAttachment; } else { return usage | vk::FormatFeatureFlagBits::eStorageImage | - vk::FormatFeatureFlagBits::eColorAttachment; + vk::FormatFeatureFlagBits::eColorAttachment; } } diff --git a/src/video_core/renderer_vulkan/vk_format_reinterpreter.cpp b/src/video_core/renderer_vulkan/vk_format_reinterpreter.cpp index 15243dbb6..f93266ccf 100644 --- a/src/video_core/renderer_vulkan/vk_format_reinterpreter.cpp +++ b/src/video_core/renderer_vulkan/vk_format_reinterpreter.cpp @@ -4,12 +4,13 @@ #define VULKAN_HPP_NO_CONSTRUCTORS #include "video_core/renderer_vulkan/vk_format_reinterpreter.h" -#include "video_core/renderer_vulkan/vk_texture_runtime.h" #include "video_core/renderer_vulkan/vk_shader.h" +#include "video_core/renderer_vulkan/vk_texture_runtime.h" namespace Vulkan { -D24S8toRGBA8::D24S8toRGBA8(const Instance& instance, TaskScheduler& scheduler, TextureRuntime& runtime) +D24S8toRGBA8::D24S8toRGBA8(const Instance& instance, TaskScheduler& scheduler, + TextureRuntime& runtime) : FormatReinterpreterBase{instance, scheduler, runtime}, device{instance.GetDevice()} { constexpr std::string_view cs_source = R"( #version 450 core @@ -35,70 +36,54 @@ void main() { } )"; - compute_shader = Compile(cs_source, vk::ShaderStageFlagBits::eCompute, - device, ShaderOptimization::High); + compute_shader = + Compile(cs_source, vk::ShaderStageFlagBits::eCompute, device, ShaderOptimization::High); const std::array compute_layout_bindings = { - vk::DescriptorSetLayoutBinding{ - .binding = 0, - .descriptorType = vk::DescriptorType::eSampledImage, - .descriptorCount = 1, - .stageFlags = vk::ShaderStageFlagBits::eCompute - }, - vk::DescriptorSetLayoutBinding{ - .binding = 1, - .descriptorType = vk::DescriptorType::eSampledImage, - .descriptorCount = 1, - .stageFlags = vk::ShaderStageFlagBits::eCompute - }, - vk::DescriptorSetLayoutBinding{ - .binding = 2, - .descriptorType = vk::DescriptorType::eStorageImage, - .descriptorCount = 1, - .stageFlags = vk::ShaderStageFlagBits::eCompute - } - }; + vk::DescriptorSetLayoutBinding{.binding = 0, + .descriptorType = vk::DescriptorType::eSampledImage, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eCompute}, + vk::DescriptorSetLayoutBinding{.binding = 1, + .descriptorType = vk::DescriptorType::eSampledImage, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eCompute}, + vk::DescriptorSetLayoutBinding{.binding = 2, + .descriptorType = vk::DescriptorType::eStorageImage, + .descriptorCount = 1, + .stageFlags = vk::ShaderStageFlagBits::eCompute}}; const vk::DescriptorSetLayoutCreateInfo compute_layout_info = { .bindingCount = static_cast(compute_layout_bindings.size()), - .pBindings = compute_layout_bindings.data() - }; + .pBindings = compute_layout_bindings.data()}; descriptor_layout = device.createDescriptorSetLayout(compute_layout_info); const std::array update_template_entries = { - vk::DescriptorUpdateTemplateEntry{ - .dstBinding = 0, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = vk::DescriptorType::eSampledImage, - .offset = 0, - .stride = sizeof(vk::DescriptorImageInfo) - }, - vk::DescriptorUpdateTemplateEntry{ - .dstBinding = 1, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = vk::DescriptorType::eSampledImage, - .offset = sizeof(vk::DescriptorImageInfo), - .stride = 0 - }, - vk::DescriptorUpdateTemplateEntry{ - .dstBinding = 2, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = vk::DescriptorType::eStorageImage, - .offset = 2 * sizeof(vk::DescriptorImageInfo), - .stride = 0 - } - }; + vk::DescriptorUpdateTemplateEntry{.dstBinding = 0, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eSampledImage, + .offset = 0, + .stride = sizeof(vk::DescriptorImageInfo)}, + vk::DescriptorUpdateTemplateEntry{.dstBinding = 1, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eSampledImage, + .offset = sizeof(vk::DescriptorImageInfo), + .stride = 0}, + vk::DescriptorUpdateTemplateEntry{.dstBinding = 2, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = vk::DescriptorType::eStorageImage, + .offset = 2 * sizeof(vk::DescriptorImageInfo), + .stride = 0}}; const vk::DescriptorUpdateTemplateCreateInfo template_info = { .descriptorUpdateEntryCount = static_cast(update_template_entries.size()), .pDescriptorUpdateEntries = update_template_entries.data(), .templateType = vk::DescriptorUpdateTemplateType::eDescriptorSet, - .descriptorSetLayout = descriptor_layout - }; + .descriptorSetLayout = descriptor_layout}; update_template = device.createDescriptorUpdateTemplate(template_info); @@ -108,40 +93,32 @@ void main() { .size = sizeof(Common::Vec2i), }; - const vk::PipelineLayoutCreateInfo layout_info = { - .setLayoutCount = 1, - .pSetLayouts = &descriptor_layout, - .pushConstantRangeCount = 1, - .pPushConstantRanges = &push_range - }; + const vk::PipelineLayoutCreateInfo layout_info = {.setLayoutCount = 1, + .pSetLayouts = &descriptor_layout, + .pushConstantRangeCount = 1, + .pPushConstantRanges = &push_range}; compute_pipeline_layout = device.createPipelineLayout(layout_info); - const vk::DescriptorSetAllocateInfo alloc_info = { - .descriptorPool = scheduler.GetPersistentDescriptorPool(), - .descriptorSetCount = 1, - .pSetLayouts = &descriptor_layout - }; + const vk::DescriptorSetAllocateInfo alloc_info = {.descriptorPool = + scheduler.GetPersistentDescriptorPool(), + .descriptorSetCount = 1, + .pSetLayouts = &descriptor_layout}; descriptor_set = device.allocateDescriptorSets(alloc_info)[0]; const vk::PipelineShaderStageCreateInfo compute_stage = { - .stage = vk::ShaderStageFlagBits::eCompute, - .module = compute_shader, - .pName = "main" - }; + .stage = vk::ShaderStageFlagBits::eCompute, .module = compute_shader, .pName = "main"}; - const vk::ComputePipelineCreateInfo compute_info = { - .stage = compute_stage, - .layout = compute_pipeline_layout - }; + const vk::ComputePipelineCreateInfo compute_info = {.stage = compute_stage, + .layout = compute_pipeline_layout}; if (const auto result = device.createComputePipeline({}, compute_info); - result.result == vk::Result::eSuccess) { + result.result == vk::Result::eSuccess) { compute_pipeline = result.value; } else { - LOG_CRITICAL(Render_Vulkan, "D24S8 compute pipeline creation failed!"); - UNREACHABLE(); + LOG_CRITICAL(Render_Vulkan, "D24S8 compute pipeline creation failed!"); + UNREACHABLE(); } } @@ -153,37 +130,30 @@ D24S8toRGBA8::~D24S8toRGBA8() { device.destroyShaderModule(compute_shader); } -void D24S8toRGBA8::Reinterpret(Surface& source, VideoCore::Rect2D src_rect, - Surface& dest, VideoCore::Rect2D dst_rect) { +void D24S8toRGBA8::Reinterpret(Surface& source, VideoCore::Rect2D src_rect, Surface& dest, + VideoCore::Rect2D dst_rect) { vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); runtime.Transition(command_buffer, source.alloc, vk::ImageLayout::eDepthStencilReadOnlyOptimal, 0, source.alloc.levels); runtime.Transition(command_buffer, dest.alloc, vk::ImageLayout::eGeneral, 0, dest.alloc.levels); const std::array textures = { - vk::DescriptorImageInfo{ - .imageView = source.GetDepthView(), - .imageLayout = vk::ImageLayout::eDepthStencilReadOnlyOptimal - }, - vk::DescriptorImageInfo{ - .imageView = source.GetStencilView(), - .imageLayout = vk::ImageLayout::eDepthStencilReadOnlyOptimal - }, - vk::DescriptorImageInfo{ - .imageView = dest.GetImageView(), - .imageLayout = vk::ImageLayout::eGeneral - } - }; + vk::DescriptorImageInfo{.imageView = source.GetDepthView(), + .imageLayout = vk::ImageLayout::eDepthStencilReadOnlyOptimal}, + vk::DescriptorImageInfo{.imageView = source.GetStencilView(), + .imageLayout = vk::ImageLayout::eDepthStencilReadOnlyOptimal}, + vk::DescriptorImageInfo{.imageView = dest.GetImageView(), + .imageLayout = vk::ImageLayout::eGeneral}}; device.updateDescriptorSetWithTemplate(descriptor_set, update_template, textures[0]); - command_buffer.bindDescriptorSets(vk::PipelineBindPoint::eCompute, compute_pipeline_layout, - 0, 1, &descriptor_set, 0, nullptr); + command_buffer.bindDescriptorSets(vk::PipelineBindPoint::eCompute, compute_pipeline_layout, 0, + 1, &descriptor_set, 0, nullptr); command_buffer.bindPipeline(vk::PipelineBindPoint::eCompute, compute_pipeline); const auto src_offset = Common::MakeVec(src_rect.left, src_rect.bottom); - command_buffer.pushConstants(compute_pipeline_layout, vk::ShaderStageFlagBits::eCompute, - 0, sizeof(Common::Vec2i), src_offset.AsArray()); + command_buffer.pushConstants(compute_pipeline_layout, vk::ShaderStageFlagBits::eCompute, 0, + sizeof(Common::Vec2i), src_offset.AsArray()); command_buffer.dispatch(src_rect.GetWidth() / 32, src_rect.GetHeight() / 32, 1); } diff --git a/src/video_core/renderer_vulkan/vk_format_reinterpreter.h b/src/video_core/renderer_vulkan/vk_format_reinterpreter.h index 47e115ed4..0c0972565 100644 --- a/src/video_core/renderer_vulkan/vk_format_reinterpreter.h +++ b/src/video_core/renderer_vulkan/vk_format_reinterpreter.h @@ -16,13 +16,14 @@ class TextureRuntime; class FormatReinterpreterBase { public: - FormatReinterpreterBase(const Instance& instance, TaskScheduler& scheduler, TextureRuntime& runtime) + FormatReinterpreterBase(const Instance& instance, TaskScheduler& scheduler, + TextureRuntime& runtime) : instance{instance}, scheduler{scheduler}, runtime{runtime} {} virtual ~FormatReinterpreterBase() = default; virtual VideoCore::PixelFormat GetSourceFormat() const = 0; - virtual void Reinterpret(Surface& source, VideoCore::Rect2D src_rect, - Surface& dest, VideoCore::Rect2D dst_rect) = 0; + virtual void Reinterpret(Surface& source, VideoCore::Rect2D src_rect, Surface& dest, + VideoCore::Rect2D dst_rect) = 0; protected: const Instance& instance; @@ -41,8 +42,8 @@ public: return VideoCore::PixelFormat::D24S8; } - void Reinterpret(Surface& source, VideoCore::Rect2D src_rect, - Surface& dest, VideoCore::Rect2D dst_rect) override; + void Reinterpret(Surface& source, VideoCore::Rect2D src_rect, Surface& dest, + VideoCore::Rect2D dst_rect) override; private: vk::Device device; diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index d8414ccea..ae243fc0c 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -6,8 +6,8 @@ #include #include "common/assert.h" #include "core/frontend/emu_window.h" -#include "video_core/renderer_vulkan/vk_platform.h" #include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_platform.h" namespace Vulkan { @@ -41,30 +41,27 @@ vk::Format ToVkFormat(VideoCore::PixelFormat format) { Instance::Instance() { // Fetch instance independant function pointers vk::DynamicLoader dl; - auto vkGetInstanceProcAddr = dl.getProcAddress("vkGetInstanceProcAddr"); + auto vkGetInstanceProcAddr = + dl.getProcAddress("vkGetInstanceProcAddr"); VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr); - const vk::ApplicationInfo application_info = { - .pApplicationName = "Citra", - .applicationVersion = VK_MAKE_VERSION(1, 0, 0), - .pEngineName = "Citra Vulkan", - .engineVersion = VK_MAKE_VERSION(1, 0, 0), - .apiVersion = VK_API_VERSION_1_0 - }; + const vk::ApplicationInfo application_info = {.pApplicationName = "Citra", + .applicationVersion = VK_MAKE_VERSION(1, 0, 0), + .pEngineName = "Citra Vulkan", + .engineVersion = VK_MAKE_VERSION(1, 0, 0), + .apiVersion = VK_API_VERSION_1_0}; - const vk::InstanceCreateInfo instance_info = { - .pApplicationInfo = &application_info - }; + const vk::InstanceCreateInfo instance_info = {.pApplicationInfo = &application_info}; instance = vk::createInstance(instance_info); // Load required function pointers for querying the physical device - VULKAN_HPP_DEFAULT_DISPATCHER.vkEnumeratePhysicalDevices = - PFN_vkEnumeratePhysicalDevices(vkGetInstanceProcAddr(instance, "vkEnumeratePhysicalDevices")); - VULKAN_HPP_DEFAULT_DISPATCHER.vkGetPhysicalDeviceProperties = - PFN_vkGetPhysicalDeviceProperties(vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties")); + VULKAN_HPP_DEFAULT_DISPATCHER.vkEnumeratePhysicalDevices = PFN_vkEnumeratePhysicalDevices( + vkGetInstanceProcAddr(instance, "vkEnumeratePhysicalDevices")); + VULKAN_HPP_DEFAULT_DISPATCHER.vkGetPhysicalDeviceProperties = PFN_vkGetPhysicalDeviceProperties( + vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceProperties")); VULKAN_HPP_DEFAULT_DISPATCHER.vkDestroyInstance = - PFN_vkDestroyInstance(vkGetInstanceProcAddr(instance, "vkDestroyInstance")); + PFN_vkDestroyInstance(vkGetInstanceProcAddr(instance, "vkDestroyInstance")); physical_devices = instance.enumeratePhysicalDevices(); } @@ -74,7 +71,8 @@ Instance::Instance(Frontend::EmuWindow& window, u32 physical_device_index, bool // Fetch instance independant function pointers vk::DynamicLoader dl; - auto vkGetInstanceProcAddr = dl.getProcAddress("vkGetInstanceProcAddr"); + auto vkGetInstanceProcAddr = + dl.getProcAddress("vkGetInstanceProcAddr"); VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr); // Enable the instance extensions the backend uses @@ -87,23 +85,20 @@ Instance::Instance(Frontend::EmuWindow& window, u32 physical_device_index, bool return; } - const vk::ApplicationInfo application_info = { - .pApplicationName = "Citra", - .applicationVersion = VK_MAKE_VERSION(1, 0, 0), - .pEngineName = "Citra Vulkan", - .engineVersion = VK_MAKE_VERSION(1, 0, 0), - .apiVersion = available_version - }; + const vk::ApplicationInfo application_info = {.pApplicationName = "Citra", + .applicationVersion = VK_MAKE_VERSION(1, 0, 0), + .pEngineName = "Citra Vulkan", + .engineVersion = VK_MAKE_VERSION(1, 0, 0), + .apiVersion = available_version}; 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 = layer_count, - .ppEnabledLayerNames = layers.data(), - .enabledExtensionCount = static_cast(extensions.size()), - .ppEnabledExtensionNames = extensions.data() - }; + const vk::InstanceCreateInfo instance_info = {.pApplicationInfo = &application_info, + .enabledLayerCount = layer_count, + .ppEnabledLayerNames = layers.data(), + .enabledExtensionCount = + static_cast(extensions.size()), + .ppEnabledExtensionNames = extensions.data()}; instance = vk::createInstance(instance_info); surface = CreateSurface(instance, window); @@ -111,8 +106,9 @@ Instance::Instance(Frontend::EmuWindow& window, u32 physical_device_index, bool // Pick physical device physical_devices = instance.enumeratePhysicalDevices(); if (const u16 physical_device_count = static_cast(physical_devices.size()); - physical_device_index >= physical_devices.size()) { - LOG_CRITICAL(Render_Vulkan, "Invalid physical device index {} provided when only {} devices exist", + physical_device_index >= physical_devices.size()) { + LOG_CRITICAL(Render_Vulkan, + "Invalid physical device index {} provided when only {} devices exist", physical_device_index, physical_device_count); UNREACHABLE(); } @@ -145,59 +141,48 @@ FormatTraits Instance::GetTraits(VideoCore::PixelFormat pixel_format) const { void Instance::CreateFormatTable() { constexpr std::array pixel_formats = { - VideoCore::PixelFormat::RGBA8, - VideoCore::PixelFormat::RGB8, - VideoCore::PixelFormat::RGB5A1, - VideoCore::PixelFormat::RGB565, - VideoCore::PixelFormat::RGBA4, - VideoCore::PixelFormat::IA8, - VideoCore::PixelFormat::RG8, - VideoCore::PixelFormat::I8, - VideoCore::PixelFormat::A8, - VideoCore::PixelFormat::IA4, - VideoCore::PixelFormat::I4, - VideoCore::PixelFormat::A4, - VideoCore::PixelFormat::ETC1, - VideoCore::PixelFormat::ETC1A4, - VideoCore::PixelFormat::D16, - VideoCore::PixelFormat::D24, - VideoCore::PixelFormat::D24S8 - }; + VideoCore::PixelFormat::RGBA8, VideoCore::PixelFormat::RGB8, + VideoCore::PixelFormat::RGB5A1, VideoCore::PixelFormat::RGB565, + VideoCore::PixelFormat::RGBA4, VideoCore::PixelFormat::IA8, + VideoCore::PixelFormat::RG8, VideoCore::PixelFormat::I8, + VideoCore::PixelFormat::A8, VideoCore::PixelFormat::IA4, + VideoCore::PixelFormat::I4, VideoCore::PixelFormat::A4, + VideoCore::PixelFormat::ETC1, VideoCore::PixelFormat::ETC1A4, + VideoCore::PixelFormat::D16, VideoCore::PixelFormat::D24, + VideoCore::PixelFormat::D24S8}; const vk::FormatFeatureFlags storage_usage = vk::FormatFeatureFlagBits::eStorageImage; - const vk::FormatFeatureFlags blit_usage = vk::FormatFeatureFlagBits::eSampledImage | - vk::FormatFeatureFlagBits::eTransferDst | - vk::FormatFeatureFlagBits::eTransferSrc | - vk::FormatFeatureFlagBits::eBlitSrc | - vk::FormatFeatureFlagBits::eBlitDst; + const vk::FormatFeatureFlags blit_usage = + vk::FormatFeatureFlagBits::eSampledImage | vk::FormatFeatureFlagBits::eTransferDst | + vk::FormatFeatureFlagBits::eTransferSrc | vk::FormatFeatureFlagBits::eBlitSrc | + vk::FormatFeatureFlagBits::eBlitDst; for (const auto& pixel_format : pixel_formats) { const vk::Format format = ToVkFormat(pixel_format); const vk::FormatProperties properties = physical_device.getFormatProperties(format); const vk::ImageAspectFlags aspect = GetImageAspect(format); - const vk::FormatFeatureFlagBits attachment_usage = (aspect & vk::ImageAspectFlagBits::eDepth) ? - vk::FormatFeatureFlagBits::eDepthStencilAttachment : - vk::FormatFeatureFlagBits::eColorAttachment; + const vk::FormatFeatureFlagBits attachment_usage = + (aspect & vk::ImageAspectFlagBits::eDepth) + ? vk::FormatFeatureFlagBits::eDepthStencilAttachment + : vk::FormatFeatureFlagBits::eColorAttachment; - const bool supports_blit = - (properties.optimalTilingFeatures & blit_usage) == blit_usage; + const bool supports_blit = (properties.optimalTilingFeatures & blit_usage) == blit_usage; const bool supports_attachment = - (properties.optimalTilingFeatures & attachment_usage) == attachment_usage; + (properties.optimalTilingFeatures & attachment_usage) == attachment_usage; const bool supports_storage = - (properties.optimalTilingFeatures & storage_usage) == storage_usage; + (properties.optimalTilingFeatures & storage_usage) == storage_usage; // Find the most inclusive usage flags for this format vk::ImageUsageFlags best_usage; if (supports_blit) { - best_usage |= vk::ImageUsageFlagBits::eSampled | - vk::ImageUsageFlagBits::eTransferDst | - vk::ImageUsageFlagBits::eTransferSrc; + best_usage |= vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst | + vk::ImageUsageFlagBits::eTransferSrc; } if (supports_attachment) { - best_usage |= (aspect & vk::ImageAspectFlagBits::eDepth) ? - vk::ImageUsageFlagBits::eDepthStencilAttachment : - vk::ImageUsageFlagBits::eColorAttachment; + best_usage |= (aspect & vk::ImageAspectFlagBits::eDepth) + ? vk::ImageUsageFlagBits::eDepthStencilAttachment + : vk::ImageUsageFlagBits::eColorAttachment; } if (supports_storage) { best_usage |= vk::ImageUsageFlagBits::eStorage; @@ -219,26 +204,26 @@ void Instance::CreateFormatTable() { } const u32 index = static_cast(pixel_format); - format_table[index] = FormatTraits{ - .blit_support = supports_blit, - .attachment_support = supports_attachment, - .storage_support = supports_storage, - .usage = best_usage, - .native = format, - .fallback = fallback - }; + format_table[index] = FormatTraits{.blit_support = supports_blit, + .attachment_support = supports_attachment, + .storage_support = supports_storage, + .usage = best_usage, + .native = format, + .fallback = fallback}; } } bool Instance::CreateDevice() { - auto feature_chain = physical_device.getFeatures2(); + auto feature_chain = + physical_device.getFeatures2(); // Not having geometry shaders will cause issues with accelerated rendering. const vk::PhysicalDeviceFeatures available = feature_chain.get().features; if (!available.geometryShader) { - LOG_WARNING(Render_Vulkan, "Geometry shaders not availabe! Accelerated rendering not possible!"); + LOG_WARNING(Render_Vulkan, + "Geometry shaders not availabe! Accelerated rendering not possible!"); } auto extension_list = physical_device.enumerateDeviceExtensionProperties(); @@ -252,9 +237,9 @@ bool Instance::CreateDevice() { u32 enabled_extension_count = 0; auto AddExtension = [&](std::string_view name) -> bool { - auto result = std::find_if(extension_list.begin(), extension_list.end(), [&](const auto& prop) { - return name.compare(prop.extensionName.data()); - }); + auto result = + std::find_if(extension_list.begin(), extension_list.end(), + [&](const auto& prop) { return name.compare(prop.extensionName.data()); }); if (result != extension_list.end()) { LOG_INFO(Render_Vulkan, "Enabling extension: {}", name); @@ -311,17 +296,12 @@ bool Instance::CreateDevice() { static constexpr float queue_priorities[] = {1.0f}; const std::array queue_infos = { - vk::DeviceQueueCreateInfo{ - .queueFamilyIndex = graphics_queue_family_index, - .queueCount = 1, - .pQueuePriorities = queue_priorities - }, - vk::DeviceQueueCreateInfo{ - .queueFamilyIndex = present_queue_family_index, - .queueCount = 1, - .pQueuePriorities = queue_priorities - } - }; + vk::DeviceQueueCreateInfo{.queueFamilyIndex = graphics_queue_family_index, + .queueCount = 1, + .pQueuePriorities = queue_priorities}, + vk::DeviceQueueCreateInfo{.queueFamilyIndex = present_queue_family_index, + .queueCount = 1, + .pQueuePriorities = queue_priorities}}; const u32 queue_count = graphics_queue_family_index != present_queue_family_index ? 2u : 1u; const vk::StructureChain device_chain = { @@ -332,25 +312,19 @@ bool Instance::CreateDevice() { .ppEnabledExtensionNames = enabled_extensions.data(), }, vk::PhysicalDeviceFeatures2{ - .features = { - .robustBufferAccess = available.robustBufferAccess, - .geometryShader = available.geometryShader, - .dualSrcBlend = available.dualSrcBlend, - .logicOp = available.logicOp, - .depthClamp = available.depthClamp, - .largePoints = available.largePoints, - .samplerAnisotropy = available.samplerAnisotropy, - .fragmentStoresAndAtomics = available.fragmentStoresAndAtomics, - .shaderStorageImageMultisample = available.shaderStorageImageMultisample, - .shaderClipDistance = available.shaderClipDistance - } - }, - vk::PhysicalDeviceDepthClipControlFeaturesEXT{ - .depthClipControl = true - }, + .features = {.robustBufferAccess = available.robustBufferAccess, + .geometryShader = available.geometryShader, + .dualSrcBlend = available.dualSrcBlend, + .logicOp = available.logicOp, + .depthClamp = available.depthClamp, + .largePoints = available.largePoints, + .samplerAnisotropy = available.samplerAnisotropy, + .fragmentStoresAndAtomics = available.fragmentStoresAndAtomics, + .shaderStorageImageMultisample = available.shaderStorageImageMultisample, + .shaderClipDistance = available.shaderClipDistance}}, + vk::PhysicalDeviceDepthClipControlFeaturesEXT{.depthClipControl = true}, feature_chain.get(), - feature_chain.get() - }; + feature_chain.get()}; // Create logical device device = physical_device.createDevice(device_chain.get()); @@ -367,16 +341,13 @@ bool Instance::CreateDevice() { void Instance::CreateAllocator() { const VmaVulkanFunctions functions = { .vkGetInstanceProcAddr = VULKAN_HPP_DEFAULT_DISPATCHER.vkGetInstanceProcAddr, - .vkGetDeviceProcAddr = VULKAN_HPP_DEFAULT_DISPATCHER.vkGetDeviceProcAddr - }; + .vkGetDeviceProcAddr = VULKAN_HPP_DEFAULT_DISPATCHER.vkGetDeviceProcAddr}; - const VmaAllocatorCreateInfo allocator_info = { - .physicalDevice = physical_device, - .device = device, - .pVulkanFunctions = &functions, - .instance = instance, - .vulkanApiVersion = VK_API_VERSION_1_1 - }; + const VmaAllocatorCreateInfo allocator_info = {.physicalDevice = physical_device, + .device = device, + .pVulkanFunctions = &functions, + .instance = instance, + .vulkanApiVersion = VK_API_VERSION_1_1}; if (VkResult result = vmaCreateAllocator(&allocator_info, &allocator); result != VK_SUCCESS) { LOG_CRITICAL(Render_Vulkan, "Failed to initialize VMA with error {}", result); diff --git a/src/video_core/renderer_vulkan/vk_instance.h b/src/video_core/renderer_vulkan/vk_instance.h index 09f490beb..2777859aa 100644 --- a/src/video_core/renderer_vulkan/vk_instance.h +++ b/src/video_core/renderer_vulkan/vk_instance.h @@ -17,11 +17,11 @@ class EmuWindow; namespace Vulkan { struct FormatTraits { - bool blit_support = false; ///< True if the format supports omnidirectonal blit operations + bool blit_support = false; ///< True if the format supports omnidirectonal blit operations bool attachment_support = false; ///< True if the format supports being used as an attachment - bool storage_support = false; ///< True if the format supports storage operations - vk::ImageUsageFlags usage{}; ///< Most supported usage for the native format - vk::Format native = vk::Format::eUndefined; ///< Closest possible native format + bool storage_support = false; ///< True if the format supports storage operations + vk::ImageUsageFlags usage{}; ///< Most supported usage for the native format + vk::Format native = vk::Format::eUndefined; ///< Closest possible native format vk::Format fallback = vk::Format::eUndefined; ///< Best fallback format }; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 575e8f780..23135cd1f 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -8,8 +8,8 @@ #include "common/file_util.h" #include "common/logging/log.h" #include "video_core/renderer_vulkan/pica_to_vk.h" -#include "video_core/renderer_vulkan/vk_pipeline_cache.h" #include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_pipeline_cache.h" #include "video_core/renderer_vulkan/vk_renderpass_cache.h" #include "video_core/renderer_vulkan/vk_task_scheduler.h" @@ -22,51 +22,26 @@ struct Bindings { constexpr u32 RASTERIZER_SET_COUNT = 4; constexpr static std::array RASTERIZER_SETS = { - Bindings{ - // Utility set - .bindings = { - vk::DescriptorType::eUniformBuffer, - vk::DescriptorType::eUniformBuffer, - vk::DescriptorType::eUniformTexelBuffer, - vk::DescriptorType::eUniformTexelBuffer, - vk::DescriptorType::eUniformTexelBuffer - }, - .binding_count = 5 - }, - Bindings{ - // Texture set - .bindings = { - vk::DescriptorType::eSampledImage, - vk::DescriptorType::eSampledImage, - vk::DescriptorType::eSampledImage, - vk::DescriptorType::eSampledImage - }, - .binding_count = 4 - }, - Bindings{ - // Sampler set - .bindings = { - vk::DescriptorType::eSampler, - vk::DescriptorType::eSampler, - vk::DescriptorType::eSampler, - vk::DescriptorType::eSampler - }, - .binding_count = 4 - }, - Bindings { - // Shadow set - .bindings = { - vk::DescriptorType::eStorageImage, - vk::DescriptorType::eStorageImage, - vk::DescriptorType::eStorageImage, - vk::DescriptorType::eStorageImage, - vk::DescriptorType::eStorageImage, - vk::DescriptorType::eStorageImage, - vk::DescriptorType::eStorageImage - }, - .binding_count = 7 - } -}; + Bindings{// Utility set + .bindings = {vk::DescriptorType::eUniformBuffer, vk::DescriptorType::eUniformBuffer, + vk::DescriptorType::eUniformTexelBuffer, + vk::DescriptorType::eUniformTexelBuffer, + vk::DescriptorType::eUniformTexelBuffer}, + .binding_count = 5}, + Bindings{// Texture set + .bindings = {vk::DescriptorType::eSampledImage, vk::DescriptorType::eSampledImage, + vk::DescriptorType::eSampledImage, vk::DescriptorType::eSampledImage}, + .binding_count = 4}, + Bindings{// Sampler set + .bindings = {vk::DescriptorType::eSampler, vk::DescriptorType::eSampler, + vk::DescriptorType::eSampler, vk::DescriptorType::eSampler}, + .binding_count = 4}, + Bindings{// Shadow set + .bindings = {vk::DescriptorType::eStorageImage, vk::DescriptorType::eStorageImage, + vk::DescriptorType::eStorageImage, vk::DescriptorType::eStorageImage, + vk::DescriptorType::eStorageImage, vk::DescriptorType::eStorageImage, + vk::DescriptorType::eStorageImage}, + .binding_count = 7}}; constexpr vk::ShaderStageFlags ToVkStageFlags(vk::DescriptorType type) { vk::ShaderStageFlags flags; @@ -79,10 +54,8 @@ constexpr vk::ShaderStageFlags ToVkStageFlags(vk::DescriptorType type) { break; case vk::DescriptorType::eUniformBuffer: case vk::DescriptorType::eUniformBufferDynamic: - flags = vk::ShaderStageFlagBits::eFragment | - vk::ShaderStageFlagBits::eVertex | - vk::ShaderStageFlagBits::eGeometry | - vk::ShaderStageFlagBits::eCompute; + flags = vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eVertex | + vk::ShaderStageFlagBits::eGeometry | vk::ShaderStageFlagBits::eCompute; break; default: LOG_ERROR(Render_Vulkan, "Unknown descriptor type!"); @@ -109,10 +82,14 @@ vk::Format ToVkAttributeFormat(VertexAttribute attrib) { switch (attrib.type) { case AttribType::Float: switch (attrib.size) { - case 1: return vk::Format::eR32Sfloat; - case 2: return vk::Format::eR32G32Sfloat; - case 3: return vk::Format::eR32G32B32Sfloat; - case 4: return vk::Format::eR32G32B32A32Sfloat; + case 1: + return vk::Format::eR32Sfloat; + case 2: + return vk::Format::eR32G32Sfloat; + case 3: + return vk::Format::eR32G32B32Sfloat; + case 4: + return vk::Format::eR32G32B32A32Sfloat; } default: LOG_CRITICAL(Render_Vulkan, "Unimplemented vertex attribute format!"); @@ -124,9 +101,12 @@ vk::Format ToVkAttributeFormat(VertexAttribute attrib) { vk::ShaderStageFlagBits ToVkShaderStage(std::size_t index) { switch (index) { - case 0: return vk::ShaderStageFlagBits::eVertex; - case 1: return vk::ShaderStageFlagBits::eFragment; - case 2: return vk::ShaderStageFlagBits::eGeometry; + case 0: + return vk::ShaderStageFlagBits::eVertex; + case 1: + return vk::ShaderStageFlagBits::eFragment; + case 2: + return vk::ShaderStageFlagBits::eGeometry; default: LOG_CRITICAL(Render_Vulkan, "Invalid shader stage index!"); UNREACHABLE(); @@ -135,7 +115,8 @@ vk::ShaderStageFlagBits ToVkShaderStage(std::size_t index) { return vk::ShaderStageFlagBits::eVertex; } -PipelineCache::PipelineCache(const Instance& instance, TaskScheduler& scheduler, RenderpassCache& renderpass_cache) +PipelineCache::PipelineCache(const Instance& instance, TaskScheduler& scheduler, + RenderpassCache& renderpass_cache) : instance{instance}, scheduler{scheduler}, renderpass_cache{renderpass_cache} { descriptor_dirty.fill(true); @@ -185,9 +166,10 @@ void PipelineCache::BindPipeline(const PipelineInfo& info) { shader_hash = Common::HashCombine(shader_hash, shader_hashes[i]); } - const u64 info_hash_size = instance.IsExtendedDynamicStateSupported() ? - offsetof(PipelineInfo, rasterization) : - offsetof(PipelineInfo, depth_stencil) + offsetof(DepthStencilState, stencil_reference); + const u64 info_hash_size = instance.IsExtendedDynamicStateSupported() + ? offsetof(PipelineInfo, rasterization) + : offsetof(PipelineInfo, depth_stencil) + + offsetof(DepthStencilState, stencil_reference); u64 info_hash = Common::ComputeHash64(&info, info_hash_size); u64 pipeline_hash = Common::HashCombine(shader_hash, info_hash); @@ -206,10 +188,12 @@ void PipelineCache::BindPipeline(const PipelineInfo& info) { BindDescriptorSets(); } -bool PipelineCache::UseProgrammableVertexShader(const Pica::Regs& regs, Pica::Shader::ShaderSetup& setup) { +bool PipelineCache::UseProgrammableVertexShader(const Pica::Regs& regs, + Pica::Shader::ShaderSetup& setup) { const PicaVSConfig config{regs.vs, setup}; - auto [handle, result] = programmable_vertex_shaders.Get(config, setup, vk::ShaderStageFlagBits::eVertex, - instance.GetDevice(), ShaderOptimization::Debug); + auto [handle, result] = + programmable_vertex_shaders.Get(config, setup, vk::ShaderStageFlagBits::eVertex, + instance.GetDevice(), ShaderOptimization::Debug); if (!handle) { return false; } @@ -247,48 +231,33 @@ void PipelineCache::UseFragmentShader(const Pica::Regs& regs) { void PipelineCache::BindTexture(u32 binding, vk::ImageView image_view) { const vk::DescriptorImageInfo image_info = { - .imageView = image_view, - .imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal - }; + .imageView = image_view, .imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal}; SetBinding(1, binding, DescriptorData{image_info}); } void PipelineCache::BindStorageImage(u32 binding, vk::ImageView image_view) { - const vk::DescriptorImageInfo image_info = { - .imageView = image_view, - .imageLayout = vk::ImageLayout::eGeneral - }; + const vk::DescriptorImageInfo image_info = {.imageView = image_view, + .imageLayout = vk::ImageLayout::eGeneral}; SetBinding(3, binding, DescriptorData{image_info}); } void PipelineCache::BindBuffer(u32 binding, vk::Buffer buffer, u32 offset, u32 size) { const DescriptorData data = { - .buffer_info = vk::DescriptorBufferInfo{ - .buffer = buffer, - .offset = offset, - .range = size - } - }; + .buffer_info = vk::DescriptorBufferInfo{.buffer = buffer, .offset = offset, .range = size}}; SetBinding(0, binding, data); } void PipelineCache::BindTexelBuffer(u32 binding, vk::BufferView buffer_view) { - const DescriptorData data = { - .buffer_view = buffer_view - }; + const DescriptorData data = {.buffer_view = buffer_view}; SetBinding(0, binding, data); } void PipelineCache::BindSampler(u32 binding, vk::Sampler sampler) { - const DescriptorData data = { - .image_info = vk::DescriptorImageInfo{ - .sampler = sampler - } - }; + const DescriptorData data = {.image_info = vk::DescriptorImageInfo{.sampler = sampler}}; SetBinding(2, binding, data); } @@ -311,7 +280,8 @@ void PipelineCache::MarkDirty() { void PipelineCache::ApplyDynamic(const PipelineInfo& info) { if (instance.IsExtendedDynamicStateSupported()) { vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); - command_buffer.setPrimitiveTopologyEXT(PicaToVK::PrimitiveTopology(info.rasterization.topology)); + command_buffer.setPrimitiveTopologyEXT( + PicaToVK::PrimitiveTopology(info.rasterization.topology)); } } @@ -331,27 +301,22 @@ void PipelineCache::BuildLayout() { const auto& set = RASTERIZER_SETS[i]; for (u32 j = 0; j < set.binding_count; j++) { vk::DescriptorType type = set.bindings[j]; - set_bindings[j] = vk::DescriptorSetLayoutBinding{ - .binding = j, - .descriptorType = type, - .descriptorCount = 1, - .stageFlags = ToVkStageFlags(type) - }; + set_bindings[j] = vk::DescriptorSetLayoutBinding{.binding = j, + .descriptorType = type, + .descriptorCount = 1, + .stageFlags = ToVkStageFlags(type)}; - update_entries[j] = vk::DescriptorUpdateTemplateEntry{ - .dstBinding = j, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = type, - .offset = j * sizeof(DescriptorData), - .stride = 0 - }; + update_entries[j] = + vk::DescriptorUpdateTemplateEntry{.dstBinding = j, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = type, + .offset = j * sizeof(DescriptorData), + .stride = 0}; } - const vk::DescriptorSetLayoutCreateInfo layout_info = { - .bindingCount = set.binding_count, - .pBindings = set_bindings.data() - }; + const vk::DescriptorSetLayoutCreateInfo layout_info = {.bindingCount = set.binding_count, + .pBindings = set_bindings.data()}; // Create descriptor set layout descriptor_set_layouts[i] = device.createDescriptorSetLayout(layout_info); @@ -360,19 +325,16 @@ void PipelineCache::BuildLayout() { .descriptorUpdateEntryCount = set.binding_count, .pDescriptorUpdateEntries = update_entries.data(), .templateType = vk::DescriptorUpdateTemplateType::eDescriptorSet, - .descriptorSetLayout = descriptor_set_layouts[i] - }; + .descriptorSetLayout = descriptor_set_layouts[i]}; // Create descriptor set update template update_templates[i] = device.createDescriptorUpdateTemplate(template_info); } - const vk::PipelineLayoutCreateInfo layout_info = { - .setLayoutCount = RASTERIZER_SET_COUNT, - .pSetLayouts = descriptor_set_layouts.data(), - .pushConstantRangeCount = 0, - .pPushConstantRanges = nullptr - }; + const vk::PipelineLayoutCreateInfo layout_info = {.setLayoutCount = RASTERIZER_SET_COUNT, + .pSetLayouts = descriptor_set_layouts.data(), + .pushConstantRangeCount = 0, + .pPushConstantRanges = nullptr}; layout = device.createPipelineLayout(layout_info); } @@ -389,16 +351,14 @@ vk::Pipeline PipelineCache::BuildPipeline(const PipelineInfo& info) { } shader_stages[shader_count++] = vk::PipelineShaderStageCreateInfo{ - .stage = ToVkShaderStage(i), - .module = shader, - .pName = "main" - }; + .stage = ToVkShaderStage(i), .module = shader, .pName = "main"}; } /** - * Vulkan doesn't intuitively support fixed attributes. To avoid duplicating the data and increasing - * data upload, when the fixed flag is true, we specify VK_VERTEX_INPUT_RATE_INSTANCE as the input rate. - * Since one instance is all we render, the shader will always read the single attribute. + * Vulkan doesn't intuitively support fixed attributes. To avoid duplicating the data and + * increasing data upload, when the fixed flag is true, we specify VK_VERTEX_INPUT_RATE_INSTANCE + * as the input rate. Since one instance is all we render, the shader will always read the + * single attribute. */ std::array bindings; for (u32 i = 0; i < info.vertex_layout.binding_count; i++) { @@ -407,33 +367,28 @@ vk::Pipeline PipelineCache::BuildPipeline(const PipelineInfo& info) { .binding = binding.binding, .stride = binding.stride, .inputRate = binding.fixed.Value() ? vk::VertexInputRate::eInstance - : vk::VertexInputRate::eVertex - }; + : vk::VertexInputRate::eVertex}; } // Populate vertex attribute structures std::array attributes; for (u32 i = 0; i < info.vertex_layout.attribute_count; i++) { const auto& attr = info.vertex_layout.attributes[i]; - attributes[i] = vk::VertexInputAttributeDescription{ - .location = attr.location, - .binding = attr.binding, - .format = ToVkAttributeFormat(attr), - .offset = attr.offset - }; + attributes[i] = vk::VertexInputAttributeDescription{.location = attr.location, + .binding = attr.binding, + .format = ToVkAttributeFormat(attr), + .offset = attr.offset}; } const vk::PipelineVertexInputStateCreateInfo vertex_input_info = { .vertexBindingDescriptionCount = info.vertex_layout.binding_count, .pVertexBindingDescriptions = bindings.data(), .vertexAttributeDescriptionCount = info.vertex_layout.attribute_count, - .pVertexAttributeDescriptions = attributes.data() - }; + .pVertexAttributeDescriptions = attributes.data()}; const vk::PipelineInputAssemblyStateCreateInfo input_assembly = { .topology = PicaToVK::PrimitiveTopology(info.rasterization.topology), - .primitiveRestartEnable = false - }; + .primitiveRestartEnable = false}; const vk::PipelineRasterizationStateCreateInfo raster_state = { .depthClampEnable = false, @@ -441,13 +396,10 @@ vk::Pipeline PipelineCache::BuildPipeline(const PipelineInfo& info) { .cullMode = PicaToVK::CullMode(info.rasterization.cull_mode), .frontFace = PicaToVK::FrontFace(info.rasterization.cull_mode), .depthBiasEnable = false, - .lineWidth = 1.0f - }; + .lineWidth = 1.0f}; const vk::PipelineMultisampleStateCreateInfo multisampling = { - .rasterizationSamples = vk::SampleCountFlagBits::e1, - .sampleShadingEnable = false - }; + .rasterizationSamples = vk::SampleCountFlagBits::e1, .sampleShadingEnable = false}; const vk::PipelineColorBlendAttachmentState colorblend_attachment = { .blendEnable = info.blending.blend_enable.Value(), @@ -458,34 +410,22 @@ vk::Pipeline PipelineCache::BuildPipeline(const PipelineInfo& info) { .dstAlphaBlendFactor = PicaToVK::BlendFunc(info.blending.dst_alpha_blend_factor), .alphaBlendOp = PicaToVK::BlendEquation(info.blending.alpha_blend_eq), .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | - vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA - }; + vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA}; const vk::PipelineColorBlendStateCreateInfo color_blending = { .logicOpEnable = info.blending.logic_op_enable.Value(), .logicOp = PicaToVK::LogicOp(info.blending.logic_op), .attachmentCount = 1, .pAttachments = &colorblend_attachment, - .blendConstants = std::array{1.0f, 1.0f, 1.0f, 1.0f} - }; + .blendConstants = std::array{1.0f, 1.0f, 1.0f, 1.0f}}; const vk::Viewport viewport = { - .x = 0.0f, - .y = 0.0f, - .width = 1.0f, - .height = 1.0f, - .minDepth = 0.0f, - .maxDepth = 1.0f - }; + .x = 0.0f, .y = 0.0f, .width = 1.0f, .height = 1.0f, .minDepth = 0.0f, .maxDepth = 1.0f}; - const vk::Rect2D scissor = { - .offset = {0, 0}, - .extent = {1, 1} - }; + const vk::Rect2D scissor = {.offset = {0, 0}, .extent = {1, 1}}; - vk::PipelineViewportDepthClipControlCreateInfoEXT depth_clip_control = { - .negativeOneToOne = true - }; + vk::PipelineViewportDepthClipControlCreateInfoEXT depth_clip_control = {.negativeOneToOne = + true}; const vk::PipelineViewportStateCreateInfo viewport_info = { .pNext = &depth_clip_control, @@ -515,17 +455,14 @@ vk::Pipeline PipelineCache::BuildPipeline(const PipelineInfo& info) { }; const vk::PipelineDynamicStateCreateInfo dynamic_info = { - .dynamicStateCount = - extended_dynamic_states ? static_cast(dynamic_states.size()) : 6u, - .pDynamicStates = dynamic_states.data() - }; + .dynamicStateCount = extended_dynamic_states ? static_cast(dynamic_states.size()) : 6u, + .pDynamicStates = dynamic_states.data()}; const vk::StencilOpState stencil_op_state = { .failOp = PicaToVK::StencilOp(info.depth_stencil.stencil_fail_op), .passOp = PicaToVK::StencilOp(info.depth_stencil.stencil_pass_op), .depthFailOp = PicaToVK::StencilOp(info.depth_stencil.stencil_depth_fail_op), - .compareOp = PicaToVK::CompareFunc(info.depth_stencil.stencil_compare_op) - }; + .compareOp = PicaToVK::CompareFunc(info.depth_stencil.stencil_compare_op)}; const vk::PipelineDepthStencilStateCreateInfo depth_info = { .depthTestEnable = static_cast(info.depth_stencil.depth_test_enable.Value()), @@ -534,8 +471,7 @@ vk::Pipeline PipelineCache::BuildPipeline(const PipelineInfo& info) { .depthBoundsTestEnable = false, .stencilTestEnable = static_cast(info.depth_stencil.stencil_test_enable.Value()), .front = stencil_op_state, - .back = stencil_op_state - }; + .back = stencil_op_state}; const vk::GraphicsPipelineCreateInfo pipeline_info = { .stageCount = shader_count, @@ -549,16 +485,15 @@ vk::Pipeline PipelineCache::BuildPipeline(const PipelineInfo& info) { .pColorBlendState = &color_blending, .pDynamicState = &dynamic_info, .layout = layout, - .renderPass = renderpass_cache.GetRenderpass(info.color_attachment, - info.depth_attachment, false) - }; + .renderPass = + renderpass_cache.GetRenderpass(info.color_attachment, info.depth_attachment, false)}; if (const auto result = device.createGraphicsPipeline(pipeline_cache, pipeline_info); - result.result == vk::Result::eSuccess) { + result.result == vk::Result::eSuccess) { return result.value; } else { - LOG_CRITICAL(Render_Vulkan, "Graphics pipeline creation failed!"); - UNREACHABLE(); + LOG_CRITICAL(Render_Vulkan, "Graphics pipeline creation failed!"); + UNREACHABLE(); } return VK_NULL_HANDLE; @@ -573,8 +508,7 @@ void PipelineCache::BindDescriptorSets() { const vk::DescriptorSetAllocateInfo alloc_info = { .descriptorPool = scheduler.GetDescriptorPool(), .descriptorSetCount = 1, - .pSetLayouts = &descriptor_set_layouts[i] - }; + .pSetLayouts = &descriptor_set_layouts[i]}; vk::DescriptorSet set = device.allocateDescriptorSets(alloc_info)[0]; device.updateDescriptorSetWithTemplate(set, update_templates[i], update_data[i][0]); @@ -586,8 +520,8 @@ void PipelineCache::BindDescriptorSets() { // Bind the descriptor sets vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); - command_buffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, layout, 0, RASTERIZER_SET_COUNT, - descriptor_sets.data(), 0, nullptr); + command_buffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, layout, 0, + RASTERIZER_SET_COUNT, descriptor_sets.data(), 0, nullptr); } void PipelineCache::LoadDiskCache() { @@ -596,10 +530,7 @@ void PipelineCache::LoadDiskCache() { } const std::string cache_file_path = GetPipelineCacheDir() + DIR_SEP "pipelines.bin"; - vk::PipelineCacheCreateInfo cache_info = { - .initialDataSize = 0, - .pInitialData = nullptr - }; + vk::PipelineCacheCreateInfo cache_info = {.initialDataSize = 0, .pInitialData = nullptr}; FileUtil::IOFile cache_file{cache_file_path, "r"}; if (cache_file.IsOpen()) { @@ -664,16 +595,18 @@ bool PipelineCache::IsCacheValid(const u8* data, u32 size) const { } if (u32 vendor_id = instance.GetVendorID(); header.vendorID != vendor_id) { - LOG_ERROR(Render_Vulkan, - "Pipeline cache failed validation: Incorrect vendor ID (file: {:#X}, device: {:#X})", - header.vendorID, vendor_id); + LOG_ERROR( + Render_Vulkan, + "Pipeline cache failed validation: Incorrect vendor ID (file: {:#X}, device: {:#X})", + header.vendorID, vendor_id); return false; } if (u32 device_id = instance.GetDeviceID(); header.deviceID != device_id) { - LOG_ERROR(Render_Vulkan, - "Pipeline cache failed validation: Incorrect device ID (file: {:#X}, device: {:#X})", - header.deviceID, device_id); + LOG_ERROR( + Render_Vulkan, + "Pipeline cache failed validation: Incorrect device ID (file: {:#X}, device: {:#X})", + header.deviceID, device_id); return false; } diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index 23456f77e..8a7ec0484 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h @@ -8,11 +8,11 @@ #include "common/bit_field.h" #include "common/hash.h" #include "video_core/rasterizer_cache/pixel_format.h" +#include "video_core/regs.h" #include "video_core/renderer_vulkan/vk_common.h" #include "video_core/renderer_vulkan/vk_shader.h" #include "video_core/renderer_vulkan/vk_shader_gen.h" #include "video_core/shader/shader_cache.h" -#include "video_core/regs.h" namespace Vulkan { @@ -22,13 +22,7 @@ constexpr u32 MAX_VERTEX_BINDINGS = 16; constexpr u32 MAX_DESCRIPTORS = 8; constexpr u32 MAX_DESCRIPTOR_SETS = 6; -enum class AttribType : u32 { - Float = 0, - Int = 1, - Short = 2, - Byte = 3, - Ubyte = 4 -}; +enum class AttribType : u32 { Float = 0, Int = 1, Short = 2, Byte = 3, Ubyte = 4 }; /** * The pipeline state is tightly packed with bitfields to reduce @@ -110,9 +104,9 @@ struct PipelineInfo { bool IsDepthWriteEnabled() const { const bool has_stencil = depth_attachment == VideoCore::PixelFormat::D24S8; const bool depth_write = - depth_stencil.depth_test_enable && depth_stencil.depth_write_enable; - const bool stencil_write = - has_stencil && depth_stencil.stencil_test_enable && depth_stencil.stencil_write_mask != 0; + depth_stencil.depth_test_enable && depth_stencil.depth_write_enable; + const bool stencil_write = has_stencil && depth_stencil.stencil_test_enable && + depth_stencil.stencil_write_mask != 0; return depth_write || stencil_write; } @@ -133,16 +127,15 @@ using DescriptorSetData = std::array; /** * Vulkan specialized PICA shader caches */ -using ProgrammableVertexShaders = - Pica::Shader::ShaderDoubleCache; +using ProgrammableVertexShaders = Pica::Shader::ShaderDoubleCache; -using FixedGeometryShaders = - Pica::Shader::ShaderCache; +using FixedGeometryShaders = Pica::Shader::ShaderCache; using FragmentShaders = Pica::Shader::ShaderCache; - class Instance; class TaskScheduler; class RenderpassCache; @@ -153,7 +146,8 @@ class RenderpassCache; */ class PipelineCache { public: - PipelineCache(const Instance& instance, TaskScheduler& scheduler, RenderpassCache& renderpass_cache); + PipelineCache(const Instance& instance, TaskScheduler& scheduler, + RenderpassCache& renderpass_cache); ~PipelineCache(); /// Binds a pipeline using the provided information @@ -250,11 +244,7 @@ private: std::array descriptor_sets; // Bound shader modules - enum ProgramType : u32 { - VS = 0, - GS = 2, - FS = 1 - }; + enum ProgramType : u32 { VS = 0, GS = 2, FS = 1 }; std::array current_shaders; std::array shader_hashes; diff --git a/src/video_core/renderer_vulkan/vk_platform.cpp b/src/video_core/renderer_vulkan/vk_platform.cpp index 9a29107c5..5c07d5e87 100644 --- a/src/video_core/renderer_vulkan/vk_platform.cpp +++ b/src/video_core/renderer_vulkan/vk_platform.cpp @@ -3,16 +3,16 @@ // Refer to the license.txt file included. // Include the vulkan platform specific header -#if defined(ANDROID) || defined (__ANDROID__) - #define VK_USE_PLATFORM_ANDROID_KHR +#if defined(ANDROID) || defined(__ANDROID__) +#define VK_USE_PLATFORM_ANDROID_KHR #elif defined(_WIN32) - #define VK_USE_PLATFORM_WIN32_KHR +#define VK_USE_PLATFORM_WIN32_KHR #elif defined(__APPLE__) - #define VK_USE_PLATFORM_MACOS_MVK - #define VK_USE_PLATFORM_METAL_EXT +#define VK_USE_PLATFORM_MACOS_MVK +#define VK_USE_PLATFORM_METAL_EXT #else - #define VK_USE_PLATFORM_WAYLAND_KHR - #define VK_USE_PLATFORM_XLIB_KHR +#define VK_USE_PLATFORM_WAYLAND_KHR +#define VK_USE_PLATFORM_XLIB_KHR #endif #define VULKAN_HPP_NO_CONSTRUCTORS @@ -33,9 +33,7 @@ vk::SurfaceKHR CreateSurface(vk::Instance instance, const Frontend::EmuWindow& e #if defined(VK_USE_PLATFORM_WIN32_KHR) if (window_info.type == Frontend::WindowSystemType::Windows) { const vk::Win32SurfaceCreateInfoKHR win32_ci = { - .hinstance = nullptr, - .hwnd = static_cast(window_info.render_surface) - }; + .hinstance = nullptr, .hwnd = static_cast(window_info.render_surface)}; if (instance.createWin32SurfaceKHR(&win32_ci, nullptr, &surface) != vk::Result::eSuccess) { LOG_CRITICAL(Render_Vulkan, "Failed to initialize Win32 surface"); @@ -46,8 +44,7 @@ vk::SurfaceKHR CreateSurface(vk::Instance instance, const Frontend::EmuWindow& e if (window_info.type == Frontend::WindowSystemType::X11) { const vk::XlibSurfaceCreateInfoKHR xlib_ci = { .dpy = static_cast(window_info.display_connection), - .window = reinterpret_cast(window_info.render_surface) - }; + .window = reinterpret_cast(window_info.render_surface)}; if (instance.createXlibSurfaceKHR(&xlib_ci, nullptr, &surface) != vk::Result::eSuccess) { LOG_ERROR(Render_Vulkan, "Failed to initialize Xlib surface"); @@ -58,10 +55,10 @@ vk::SurfaceKHR CreateSurface(vk::Instance instance, const Frontend::EmuWindow& e if (window_info.type == Frontend::WindowSystemType::Wayland) { const vk::WaylandSurfaceCreateInfoKHR wayland_ci = { .display = static_cast(window_info.display_connection), - .surface = static_cast(window_info.render_surface) - }; + .surface = static_cast(window_info.render_surface)}; - if (instance.createWaylandSurfaceKHR(&wayland_ci, nullptr, &surface) != vk::Result::eSuccess) { + if (instance.createWaylandSurfaceKHR(&wayland_ci, nullptr, &surface) != + vk::Result::eSuccess) { LOG_ERROR(Render_Vulkan, "Failed to initialize Wayland surface"); UNREACHABLE(); } @@ -75,7 +72,8 @@ vk::SurfaceKHR CreateSurface(vk::Instance instance, const Frontend::EmuWindow& e return surface; } -std::vector GetInstanceExtensions(Frontend::WindowSystemType window_type, bool enable_debug_utils) { +std::vector GetInstanceExtensions(Frontend::WindowSystemType window_type, + bool enable_debug_utils) { const auto properties = vk::enumerateInstanceExtensionProperties(); if (properties.empty()) { LOG_ERROR(Render_Vulkan, "Failed to query extension properties"); diff --git a/src/video_core/renderer_vulkan/vk_platform.h b/src/video_core/renderer_vulkan/vk_platform.h index c588909f6..078ed8df9 100644 --- a/src/video_core/renderer_vulkan/vk_platform.h +++ b/src/video_core/renderer_vulkan/vk_platform.h @@ -11,11 +11,12 @@ namespace Frontend { class EmuWindow; enum class WindowSystemType : u8; -} +} // namespace Frontend namespace Vulkan { -std::vector GetInstanceExtensions(Frontend::WindowSystemType window_type, bool enable_debug_utils); +std::vector GetInstanceExtensions(Frontend::WindowSystemType window_type, + bool enable_debug_utils); vk::SurfaceKHR CreateSurface(vk::Instance instance, const Frontend::EmuWindow& emu_window); diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 5e63503cd..c2ad411f3 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -12,8 +12,8 @@ #include "video_core/regs_rasterizer.h" #include "video_core/renderer_vulkan/pica_to_vk.h" #include "video_core/renderer_vulkan/renderer_vulkan.h" -#include "video_core/renderer_vulkan/vk_rasterizer.h" #include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_rasterizer.h" #include "video_core/renderer_vulkan/vk_task_scheduler.h" #include "video_core/video_core.h" @@ -26,7 +26,8 @@ MICROPROFILE_DEFINE(OpenGL_Drawing, "OpenGL", "Drawing", MP_RGB(128, 128, 192)); MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255)); MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); -RasterizerVulkan::HardwareVertex::HardwareVertex(const Pica::Shader::OutputVertex& v, bool flip_quaternion) { +RasterizerVulkan::HardwareVertex::HardwareVertex(const Pica::Shader::OutputVertex& v, + bool flip_quaternion) { position[0] = v.pos.x.ToFloat32(); position[1] = v.pos.y.ToFloat32(); position[2] = v.pos.z.ToFloat32(); @@ -98,31 +99,31 @@ constexpr u32 INDEX_BUFFER_SIZE = 8 * 1024 * 1024; constexpr u32 UNIFORM_BUFFER_SIZE = 16 * 1024 * 1024; constexpr u32 TEXTURE_BUFFER_SIZE = 16 * 1024 * 1024; -constexpr std::array TEXTURE_BUFFER_LF_FORMATS = { - vk::Format::eR32G32Sfloat -}; +constexpr std::array TEXTURE_BUFFER_LF_FORMATS = {vk::Format::eR32G32Sfloat}; -constexpr std::array TEXTURE_BUFFER_FORMATS = { - vk::Format::eR32G32Sfloat, - vk::Format::eR32G32B32A32Sfloat -}; +constexpr std::array TEXTURE_BUFFER_FORMATS = {vk::Format::eR32G32Sfloat, + vk::Format::eR32G32B32A32Sfloat}; RasterizerVulkan::RasterizerVulkan(Frontend::EmuWindow& emu_window, const Instance& instance, TaskScheduler& scheduler, TextureRuntime& runtime, RenderpassCache& renderpass_cache) - : instance{instance}, scheduler{scheduler}, runtime{runtime}, renderpass_cache{renderpass_cache}, - res_cache{*this, runtime}, pipeline_cache{instance, scheduler, renderpass_cache}, - vertex_buffer{instance, scheduler, VERTEX_BUFFER_SIZE, vk::BufferUsageFlagBits::eVertexBuffer, {}}, - uniform_buffer{instance, scheduler, UNIFORM_BUFFER_SIZE, vk::BufferUsageFlagBits::eUniformBuffer, {}}, - index_buffer{instance, scheduler, INDEX_BUFFER_SIZE, vk::BufferUsageFlagBits::eIndexBuffer, {}}, - texture_buffer{instance, scheduler, TEXTURE_BUFFER_SIZE, vk::BufferUsageFlagBits::eUniformTexelBuffer, - TEXTURE_BUFFER_FORMATS}, - texture_lf_buffer{instance, scheduler, TEXTURE_BUFFER_SIZE, vk::BufferUsageFlagBits::eUniformTexelBuffer, - TEXTURE_BUFFER_LF_FORMATS} { + : instance{instance}, scheduler{scheduler}, runtime{runtime}, + renderpass_cache{renderpass_cache}, res_cache{*this, runtime}, + pipeline_cache{instance, scheduler, renderpass_cache}, + vertex_buffer{ + instance, scheduler, VERTEX_BUFFER_SIZE, vk::BufferUsageFlagBits::eVertexBuffer, {}}, + uniform_buffer{ + instance, scheduler, UNIFORM_BUFFER_SIZE, vk::BufferUsageFlagBits::eUniformBuffer, {}}, + index_buffer{ + instance, scheduler, INDEX_BUFFER_SIZE, vk::BufferUsageFlagBits::eIndexBuffer, {}}, + texture_buffer{instance, scheduler, TEXTURE_BUFFER_SIZE, + vk::BufferUsageFlagBits::eUniformTexelBuffer, TEXTURE_BUFFER_FORMATS}, + texture_lf_buffer{instance, scheduler, TEXTURE_BUFFER_SIZE, + vk::BufferUsageFlagBits::eUniformTexelBuffer, TEXTURE_BUFFER_LF_FORMATS} { // Create a 1x1 clear texture to use in the NULL case, - default_texture = runtime.Allocate(1, 1, VideoCore::PixelFormat::RGBA8, - VideoCore::TextureType::Texture2D); + default_texture = + runtime.Allocate(1, 1, VideoCore::PixelFormat::RGBA8, VideoCore::TextureType::Texture2D); runtime.Transition(scheduler.GetUploadCommandBuffer(), default_texture, vk::ImageLayout::eShaderReadOnlyOptimal, 0, 1); @@ -142,8 +143,7 @@ RasterizerVulkan::RasterizerVulkan(Frontend::EmuWindow& emu_window, const Instan .min_filter = Pica::TexturingRegs::TextureConfig::TextureFilter::Linear, .mip_filter = Pica::TexturingRegs::TextureConfig::TextureFilter::Linear, .wrap_s = Pica::TexturingRegs::TextureConfig::WrapMode::ClampToBorder, - .wrap_t = Pica::TexturingRegs::TextureConfig::WrapMode::ClampToBorder - }; + .wrap_t = Pica::TexturingRegs::TextureConfig::WrapMode::ClampToBorder}; default_sampler = CreateSampler(default_sampler_info); @@ -194,7 +194,7 @@ RasterizerVulkan::~RasterizerVulkan() { void RasterizerVulkan::LoadDiskResources(const std::atomic_bool& stop_loading, const VideoCore::DiskResourceLoadCallback& callback) { - //shader_program_manager->LoadDiskCache(stop_loading, callback); + // shader_program_manager->LoadDiskCache(stop_loading, callback); } void RasterizerVulkan::SyncEntireState() { @@ -327,7 +327,8 @@ RasterizerVulkan::VertexArrayInfo RasterizerVulkan::AnalyzeVertexArray(bool is_i return {vertex_min, vertex_max, vs_input_size}; } -void RasterizerVulkan::SetupVertexArray(u32 vs_input_size, u32 vs_input_index_min, u32 vs_input_index_max) { +void RasterizerVulkan::SetupVertexArray(u32 vs_input_size, u32 vs_input_index_min, + u32 vs_input_index_max) { auto [array_ptr, array_offset, _] = vertex_buffer.Map(vs_input_size, 4); /** @@ -358,10 +359,12 @@ void RasterizerVulkan::SetupVertexArray(u32 vs_input_size, u32 vs_input_index_mi u32 attribute_index = loader.GetComponent(comp); if (attribute_index < 12) { if (u32 size = vertex_attributes.GetNumElements(attribute_index); size != 0) { - offset = Common::AlignUp(offset, vertex_attributes.GetElementSizeInBytes(attribute_index)); + offset = Common::AlignUp( + offset, vertex_attributes.GetElementSizeInBytes(attribute_index)); const u32 input_reg = regs.vs.GetRegisterForAttribute(attribute_index); - const u32 attrib_format = static_cast(vertex_attributes.GetFormat(attribute_index)); + const u32 attrib_format = + static_cast(vertex_attributes.GetFormat(attribute_index)); const AttribType type = vs_attrib_types[attrib_format]; // Define the attribute @@ -377,13 +380,15 @@ void RasterizerVulkan::SetupVertexArray(u32 vs_input_size, u32 vs_input_index_mi } } else { - // Attribute ids 12, 13, 14 and 15 signify 4, 8, 12 and 16-byte paddings respectively + // Attribute ids 12, 13, 14 and 15 signify 4, 8, 12 and 16-byte paddings + // respectively offset = Common::AlignUp(offset, 4); offset += (attribute_index - 11) * 4; } } - const PAddr data_addr = base_address + loader.data_offset + (vs_input_index_min * loader.byte_count); + const PAddr data_addr = + base_address + loader.data_offset + (vs_input_index_min * loader.byte_count); const u32 vertex_num = vs_input_index_max - vs_input_index_min + 1; const u32 data_size = loader.byte_count * vertex_num; @@ -409,12 +414,8 @@ void RasterizerVulkan::SetupVertexArray(u32 vs_input_size, u32 vs_input_index_mi const u32 reg = regs.vs.GetRegisterForAttribute(i); if (!enable_attributes[reg]) { const auto& attr = Pica::g_state.input_default_attributes.attr[i]; - const std::array data = { - attr.x.ToFloat32(), - attr.y.ToFloat32(), - attr.z.ToFloat32(), - attr.w.ToFloat32() - }; + const std::array data = {attr.x.ToFloat32(), attr.y.ToFloat32(), attr.z.ToFloat32(), + attr.w.ToFloat32()}; // Copy the data to the end of the buffer const u32 data_size = sizeof(float) * static_cast(data.size()); @@ -448,7 +449,8 @@ void RasterizerVulkan::SetupVertexArray(u32 vs_input_size, u32 vs_input_index_mi // Bind the vertex buffers with all the bindings vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); - command_buffer.bindVertexBuffers(0, layout.binding_count, buffers.data(), binding_offsets.data()); + command_buffer.bindVertexBuffers(0, layout.binding_count, buffers.data(), + binding_offsets.data()); } bool RasterizerVulkan::SetupVertexShader() { @@ -548,7 +550,7 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { const auto& regs = Pica::g_state.regs; const bool shadow_rendering = regs.framebuffer.output_merger.fragment_operation_mode == - Pica::FramebufferRegs::FragmentOperationMode::Shadow; + Pica::FramebufferRegs::FragmentOperationMode::Shadow; const bool has_stencil = regs.framebuffer.framebuffer.depth_format == Pica::FramebufferRegs::DepthFormat::D24S8; const bool write_color_fb = shadow_rendering || pipeline_info.blending.color_write_mask.Value(); @@ -558,7 +560,7 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { const bool using_depth_fb = !shadow_rendering && regs.framebuffer.framebuffer.GetDepthBufferPhysicalAddress() != 0 && (write_depth_fb || regs.framebuffer.output_merger.depth_test_enable != 0 || - (has_stencil && pipeline_info.depth_stencil.stencil_test_enable)); + (has_stencil && pipeline_info.depth_stencil.stencil_test_enable)); const auto viewport_rect_unscaled = Common::Rectangle{ // These registers hold half-width and half-height, so must be multiplied by 2 @@ -576,9 +578,9 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { res_cache.GetFramebufferSurfaces(using_color_fb, using_depth_fb, viewport_rect_unscaled); pipeline_info.color_attachment = - color_surface ? color_surface->pixel_format : VideoCore::PixelFormat::Invalid; + color_surface ? color_surface->pixel_format : VideoCore::PixelFormat::Invalid; pipeline_info.depth_attachment = - depth_surface ? depth_surface->pixel_format : VideoCore::PixelFormat::Invalid; + depth_surface ? depth_surface->pixel_format : VideoCore::PixelFormat::Invalid; const u16 res_scale = color_surface != nullptr ? color_surface->res_scale @@ -596,8 +598,7 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { surfaces_rect.left, surfaces_rect.right)), // Right static_cast(std::clamp(static_cast(surfaces_rect.bottom) + viewport_rect_unscaled.bottom * res_scale, - surfaces_rect.bottom, surfaces_rect.top)) - }; + surfaces_rect.bottom, surfaces_rect.top))}; if (uniform_block_data.data.framebuffer_scale != res_scale) { uniform_block_data.data.framebuffer_scale = res_scale; @@ -606,13 +607,17 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { // Scissor checks are window-, not viewport-relative, which means that if the cached texture // sub-rect changes, the scissor bounds also need to be updated. - int scissor_x1 = static_cast(surfaces_rect.left + regs.rasterizer.scissor_test.x1 * res_scale); - int scissor_y1 = static_cast(surfaces_rect.bottom + regs.rasterizer.scissor_test.y1 * res_scale); + int scissor_x1 = + static_cast(surfaces_rect.left + regs.rasterizer.scissor_test.x1 * res_scale); + int scissor_y1 = + static_cast(surfaces_rect.bottom + regs.rasterizer.scissor_test.y1 * res_scale); // x2, y2 have +1 added to cover the entire pixel area, otherwise you might get cracks when // scaling or doing multisampling. - int scissor_x2 = static_cast(surfaces_rect.left + (regs.rasterizer.scissor_test.x2 + 1) * res_scale); - int scissor_y2 = static_cast(surfaces_rect.bottom + (regs.rasterizer.scissor_test.y2 + 1) * res_scale); + int scissor_x2 = + static_cast(surfaces_rect.left + (regs.rasterizer.scissor_test.x2 + 1) * res_scale); + int scissor_y2 = + static_cast(surfaces_rect.bottom + (regs.rasterizer.scissor_test.y2 + 1) * res_scale); if (uniform_block_data.data.scissor_x1 != scissor_x1 || uniform_block_data.data.scissor_x2 != scissor_x2 || @@ -626,10 +631,11 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { uniform_block_data.dirty = true; } - auto CheckBarrier = [this, &color_surface = color_surface](vk::ImageView image_view, u32 texture_index) { + auto CheckBarrier = [this, &color_surface = color_surface](vk::ImageView image_view, + u32 texture_index) { if (color_surface && color_surface->alloc.image_view == image_view) { - //auto temp_tex = backend->CreateTexture(texture->GetInfo()); - //temp_tex->CopyFrom(texture); + // auto temp_tex = backend->CreateTexture(texture->GetInfo()); + // temp_tex->CopyFrom(texture); pipeline_cache.BindTexture(texture_index, image_view); } else { pipeline_cache.BindTexture(texture_index, image_view); @@ -650,25 +656,23 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { }; const auto BindSampler = [&](u32 binding, SamplerInfo& info, - const Pica::TexturingRegs::TextureConfig& config) { - // TODO(GPUCode): Cubemaps don't contain any mipmaps for now, so sampling from them returns nothing - // Always sample from the base level until mipmaps for texture cubes are implemented - // NOTE: There are no Vulkan filter modes that directly correspond to OpenGL minification filters - // GL_LINEAR/GL_NEAREST so emulate them by setting - // minLod = 0, and maxLod = 0.25, and using minFilter = VK_FILTER_LINEAR or minFilter = VK_FILTER_NEAREST - const bool skip_mipmap = - config.type == Pica::TexturingRegs::TextureConfig::TextureCube; - info = SamplerInfo{ - .mag_filter = config.mag_filter, - .min_filter = config.min_filter, - .mip_filter = config.mip_filter, - .wrap_s = config.wrap_s, - .wrap_t = config.wrap_t, - .border_color = config.border_color.raw, - .lod_min = skip_mipmap ? 0.f : static_cast(config.lod.min_level), - .lod_max = skip_mipmap ? 0.25f : static_cast(config.lod.max_level), - .lod_bias = static_cast(config.lod.bias) - }; + const Pica::TexturingRegs::TextureConfig& config) { + // TODO(GPUCode): Cubemaps don't contain any mipmaps for now, so sampling from them returns + // nothing Always sample from the base level until mipmaps for texture cubes are implemented + // NOTE: There are no Vulkan filter modes that directly correspond to OpenGL minification + // filters GL_LINEAR/GL_NEAREST so emulate them by setting minLod = 0, and maxLod = 0.25, + // and using minFilter = VK_FILTER_LINEAR or minFilter = VK_FILTER_NEAREST + const bool skip_mipmap = config.type == Pica::TexturingRegs::TextureConfig::TextureCube; + info = + SamplerInfo{.mag_filter = config.mag_filter, + .min_filter = config.min_filter, + .mip_filter = config.mip_filter, + .wrap_s = config.wrap_s, + .wrap_t = config.wrap_t, + .border_color = config.border_color.raw, + .lod_min = skip_mipmap ? 0.f : static_cast(config.lod.min_level), + .lod_max = skip_mipmap ? 0.25f : static_cast(config.lod.max_level), + .lod_bias = static_cast(config.lod.bias)}; // Search the cache and bind the appropriate sampler if (auto it = samplers.find(info); it != samplers.end()) { @@ -722,14 +726,13 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { .pz = regs.texturing.GetCubePhysicalAddress(CubeFace::PositiveZ), .nz = regs.texturing.GetCubePhysicalAddress(CubeFace::NegativeZ), .width = texture.config.width, - .format = texture.format - }; + .format = texture.format}; auto surface = res_cache.GetTextureCube(config); if (surface != nullptr) { runtime.Transition(scheduler.GetRenderCommandBuffer(), surface->alloc, - vk::ImageLayout::eShaderReadOnlyOptimal, - 0, surface->alloc.levels, 0, 6); + vk::ImageLayout::eShaderReadOnlyOptimal, 0, + surface->alloc.levels, 0, 6); pipeline_cache.BindTexture(3, surface->alloc.image_view); } else { pipeline_cache.BindTexture(3, default_texture.image_view); @@ -749,8 +752,8 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { auto surface = res_cache.GetTextureSurface(texture); if (surface != nullptr) { runtime.Transition(scheduler.GetRenderCommandBuffer(), surface->alloc, - vk::ImageLayout::eShaderReadOnlyOptimal, - 0, surface->alloc.levels); + vk::ImageLayout::eShaderReadOnlyOptimal, 0, + surface->alloc.levels); CheckBarrier(surface->alloc.image_view, texture_index); } else { // Can occur when texture addr is null or its memory is unmapped/invalid @@ -760,7 +763,7 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { // the geometry in question. // For example: a bug in Pokemon X/Y causes NULL-texture squares to be drawn // on the male character's face, which in the OpenGL default appear black. - //state.texture_units[texture_index].texture_2d = default_texture; + // state.texture_units[texture_index].texture_2d = default_texture; pipeline_cache.BindTexture(texture_index, default_texture.image_view); } } else { @@ -769,8 +772,8 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { } } - // NOTE: From here onwards its a safe zone to set the draw state, doing that any earlier will cause - // issues as the rasterizer cache might cause a scheduler switch and invalidate our state + // NOTE: From here onwards its a safe zone to set the draw state, doing that any earlier will + // cause issues as the rasterizer cache might cause a scheduler switch and invalidate our state // Sync the viewport pipeline_cache.SetViewport(surfaces_rect.left + viewport_rect_unscaled.left * res_scale, @@ -793,7 +796,8 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { // Viewport can have negative offsets or larger dimensions than our framebuffer sub-rect. // Enable scissor test to prevent drawing outside of the framebuffer region - pipeline_cache.SetScissor(draw_rect.left, draw_rect.bottom, draw_rect.GetWidth(), draw_rect.GetHeight()); + pipeline_cache.SetScissor(draw_rect.left, draw_rect.bottom, draw_rect.GetWidth(), + draw_rect.GetHeight()); auto valid_surface = color_surface ? color_surface : depth_surface; const FramebufferInfo framebuffer_info = { @@ -802,8 +806,7 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { .renderpass = renderpass_cache.GetRenderpass(pipeline_info.color_attachment, pipeline_info.depth_attachment, false), .width = valid_surface->GetScaledWidth(), - .height = valid_surface->GetScaledHeight() - }; + .height = valid_surface->GetScaledHeight()}; auto [it, new_framebuffer] = framebuffers.try_emplace(framebuffer_info, vk::Framebuffer{}); if (new_framebuffer) { @@ -813,29 +816,26 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); if (color_surface) { runtime.Transition(command_buffer, color_surface->alloc, - vk::ImageLayout::eColorAttachmentOptimal, - 0, color_surface->alloc.levels); + vk::ImageLayout::eColorAttachmentOptimal, 0, + color_surface->alloc.levels); } if (depth_surface) { runtime.Transition(command_buffer, depth_surface->alloc, - vk::ImageLayout::eDepthStencilAttachmentOptimal, - 0, depth_surface->alloc.levels); + vk::ImageLayout::eDepthStencilAttachmentOptimal, 0, + depth_surface->alloc.levels); } const vk::RenderPassBeginInfo renderpass_begin = { - .renderPass = - renderpass_cache.GetRenderpass(pipeline_info.color_attachment, - pipeline_info.depth_attachment, false), + .renderPass = renderpass_cache.GetRenderpass(pipeline_info.color_attachment, + pipeline_info.depth_attachment, false), .framebuffer = it->second, - .renderArea = vk::Rect2D{ - .offset = {static_cast(draw_rect.left), static_cast(draw_rect.bottom)}, - .extent = {draw_rect.GetWidth(), draw_rect.GetHeight()} - }, + .renderArea = vk::Rect2D{.offset = {static_cast(draw_rect.left), + static_cast(draw_rect.bottom)}, + .extent = {draw_rect.GetWidth(), draw_rect.GetHeight()}}, .clearValueCount = 0, - .pClearValues = nullptr - }; + .pClearValues = nullptr}; renderpass_cache.EnterRenderpass(renderpass_begin); @@ -853,7 +853,8 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { // that when base_vertex is zero the GPU will start drawing from the current mapped // offset not the start of the buffer. vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); - command_buffer.bindVertexBuffers(0, vertex_buffer.GetHandle(), vertex_buffer.GetBufferOffset()); + command_buffer.bindVertexBuffers(0, vertex_buffer.GetHandle(), + vertex_buffer.GetBufferOffset()); const u32 max_vertices = VERTEX_BUFFER_SIZE / sizeof(HardwareVertex); const u32 batch_size = static_cast(vertex_batch.size()); @@ -874,11 +875,8 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { // Mark framebuffer surfaces as dirty const VideoCore::Rect2D draw_rect_unscaled = { - draw_rect.left / res_scale, - draw_rect.top / res_scale, - draw_rect.right / res_scale, - draw_rect.bottom / res_scale - }; + draw_rect.left / res_scale, draw_rect.top / res_scale, draw_rect.right / res_scale, + draw_rect.bottom / res_scale}; if (color_surface != nullptr && write_color_fb) { auto interval = color_surface->GetSubRectInterval(draw_rect_unscaled); @@ -1429,14 +1427,14 @@ bool RasterizerVulkan::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransfe dst_params.UpdateParams(); auto [src_surface, src_rect] = - res_cache.GetSurfaceSubRect(src_params, VideoCore::ScaleMatch::Ignore, true); + res_cache.GetSurfaceSubRect(src_params, VideoCore::ScaleMatch::Ignore, true); if (src_surface == nullptr) return false; dst_params.res_scale = src_surface->res_scale; auto [dst_surface, dst_rect] = - res_cache.GetSurfaceSubRect(dst_params, VideoCore::ScaleMatch::Upscale, false); + res_cache.GetSurfaceSubRect(dst_params, VideoCore::ScaleMatch::Upscale, false); if (dst_surface == nullptr) { return false; } @@ -1521,7 +1519,7 @@ bool RasterizerVulkan::AccelerateTextureCopy(const GPU::Regs::DisplayTransferCon res_cache.GetSurfaceSubRect(dst_params, VideoCore::ScaleMatch::Upscale, load_gap); if (!dst_surface || dst_surface->type == VideoCore::SurfaceType::Texture || - !res_cache.BlitSurfaces(src_surface, src_rect, dst_surface, dst_rect)) { + !res_cache.BlitSurfaces(src_surface, src_rect, dst_surface, dst_rect)) { return false; } @@ -1590,8 +1588,7 @@ vk::Sampler RasterizerVulkan::CreateSampler(const SamplerInfo& info) { .minLod = info.lod_min, .maxLod = info.lod_max, .borderColor = vk::BorderColor::eIntOpaqueBlack, - .unnormalizedCoordinates = false - }; + .unnormalizedCoordinates = false}; vk::Device device = instance.GetDevice(); return device.createSampler(sampler_info); @@ -1609,14 +1606,12 @@ vk::Framebuffer RasterizerVulkan::CreateFramebuffer(const FramebufferInfo& info) attachments[attachment_count++] = info.depth; } - const vk::FramebufferCreateInfo framebuffer_info = { - .renderPass = info.renderpass, - .attachmentCount = attachment_count, - .pAttachments = attachments.data(), - .width = info.width, - .height = info.height, - .layers = 1 - }; + const vk::FramebufferCreateInfo framebuffer_info = {.renderPass = info.renderpass, + .attachmentCount = attachment_count, + .pAttachments = attachments.data(), + .width = info.width, + .height = info.height, + .layers = 1}; vk::Device device = instance.GetDevice(); return device.createFramebuffer(framebuffer_info); @@ -1660,7 +1655,8 @@ void RasterizerVulkan::SyncCullMode() { } void RasterizerVulkan::SyncDepthScale() { - float depth_scale = Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_range).ToFloat32(); + float depth_scale = + Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_range).ToFloat32(); if (depth_scale != uniform_block_data.data.depth_scale) { uniform_block_data.data.depth_scale = depth_scale; @@ -1669,7 +1665,8 @@ void RasterizerVulkan::SyncDepthScale() { } void RasterizerVulkan::SyncDepthOffset() { - float depth_offset = Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_near_plane).ToFloat32(); + float depth_offset = + Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_near_plane).ToFloat32(); if (depth_offset != uniform_block_data.data.depth_offset) { uniform_block_data.data.depth_offset = depth_offset; @@ -1678,18 +1675,25 @@ void RasterizerVulkan::SyncDepthOffset() { } void RasterizerVulkan::SyncBlendEnabled() { - pipeline_info.blending.blend_enable.Assign(Pica::g_state.regs.framebuffer.output_merger.alphablend_enable); + pipeline_info.blending.blend_enable.Assign( + Pica::g_state.regs.framebuffer.output_merger.alphablend_enable); } void RasterizerVulkan::SyncBlendFuncs() { const auto& regs = Pica::g_state.regs; - pipeline_info.blending.color_blend_eq.Assign(regs.framebuffer.output_merger.alpha_blending.blend_equation_rgb); - pipeline_info.blending.alpha_blend_eq.Assign(regs.framebuffer.output_merger.alpha_blending.blend_equation_a); - pipeline_info.blending.src_color_blend_factor.Assign(regs.framebuffer.output_merger.alpha_blending.factor_source_rgb); - pipeline_info.blending.dst_color_blend_factor.Assign(regs.framebuffer.output_merger.alpha_blending.factor_dest_rgb); - pipeline_info.blending.src_alpha_blend_factor.Assign(regs.framebuffer.output_merger.alpha_blending.factor_source_a); - pipeline_info.blending.dst_alpha_blend_factor.Assign(regs.framebuffer.output_merger.alpha_blending.factor_dest_a); + pipeline_info.blending.color_blend_eq.Assign( + regs.framebuffer.output_merger.alpha_blending.blend_equation_rgb); + pipeline_info.blending.alpha_blend_eq.Assign( + regs.framebuffer.output_merger.alpha_blending.blend_equation_a); + pipeline_info.blending.src_color_blend_factor.Assign( + regs.framebuffer.output_merger.alpha_blending.factor_source_rgb); + pipeline_info.blending.dst_color_blend_factor.Assign( + regs.framebuffer.output_merger.alpha_blending.factor_dest_rgb); + pipeline_info.blending.src_alpha_blend_factor.Assign( + regs.framebuffer.output_merger.alpha_blending.factor_source_a); + pipeline_info.blending.dst_alpha_blend_factor.Assign( + regs.framebuffer.output_merger.alpha_blending.factor_dest_a); } void RasterizerVulkan::SyncBlendColor() { @@ -1764,14 +1768,15 @@ void RasterizerVulkan::SyncStencilWriteMask() { : 0; vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); - command_buffer.setStencilWriteMask(vk::StencilFaceFlagBits::eFrontAndBack, pipeline_info.depth_stencil.stencil_write_mask); + command_buffer.setStencilWriteMask(vk::StencilFaceFlagBits::eFrontAndBack, + pipeline_info.depth_stencil.stencil_write_mask); } void RasterizerVulkan::SyncDepthWriteMask() { const auto& regs = Pica::g_state.regs; const bool write_enable = (regs.framebuffer.framebuffer.allow_depth_stencil_write != 0 && - regs.framebuffer.output_merger.depth_write_enable); + regs.framebuffer.output_merger.depth_write_enable); if (instance.IsExtendedDynamicStateSupported()) { vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); @@ -1784,13 +1789,16 @@ void RasterizerVulkan::SyncDepthWriteMask() { void RasterizerVulkan::SyncStencilTest() { const auto& regs = Pica::g_state.regs; - const bool test_enable = regs.framebuffer.output_merger.stencil_test.enable && - regs.framebuffer.framebuffer.depth_format == Pica::FramebufferRegs::DepthFormat::D24S8; + const bool test_enable = + regs.framebuffer.output_merger.stencil_test.enable && + regs.framebuffer.framebuffer.depth_format == Pica::FramebufferRegs::DepthFormat::D24S8; const auto& stencil_test = regs.framebuffer.output_merger.stencil_test; vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); - command_buffer.setStencilCompareMask(vk::StencilFaceFlagBits::eFrontAndBack, stencil_test.input_mask); - command_buffer.setStencilReference(vk::StencilFaceFlagBits::eFrontAndBack, stencil_test.reference_value); + command_buffer.setStencilCompareMask(vk::StencilFaceFlagBits::eFrontAndBack, + stencil_test.input_mask); + command_buffer.setStencilReference(vk::StencilFaceFlagBits::eFrontAndBack, + stencil_test.reference_value); if (instance.IsExtendedDynamicStateSupported()) { command_buffer.setStencilTestEnableEXT(test_enable); @@ -1814,10 +1822,10 @@ void RasterizerVulkan::SyncDepthTest() { const auto& regs = Pica::g_state.regs; const bool test_enabled = regs.framebuffer.output_merger.depth_test_enable == 1 || - regs.framebuffer.output_merger.depth_write_enable == 1; + regs.framebuffer.output_merger.depth_write_enable == 1; const auto compare_op = regs.framebuffer.output_merger.depth_test_enable == 1 - ? regs.framebuffer.output_merger.depth_test_func.Value() - : Pica::FramebufferRegs::CompareFunc::Always; + ? regs.framebuffer.output_merger.depth_test_func.Value() + : Pica::FramebufferRegs::CompareFunc::Always; if (instance.IsExtendedDynamicStateSupported()) { vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); @@ -1830,7 +1838,8 @@ void RasterizerVulkan::SyncDepthTest() { } void RasterizerVulkan::SyncCombinerColor() { - auto combiner_color = PicaToVK::ColorRGBA8(Pica::g_state.regs.texturing.tev_combiner_buffer_color.raw); + auto combiner_color = + PicaToVK::ColorRGBA8(Pica::g_state.regs.texturing.tev_combiner_buffer_color.raw); if (combiner_color != uniform_block_data.data.tev_combiner_buffer_color) { uniform_block_data.data.tev_combiner_buffer_color = combiner_color; uniform_block_data.dirty = true; @@ -1893,8 +1902,7 @@ void RasterizerVulkan::SyncLightPosition(int light_index) { const Common::Vec3f position = { Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].x).ToFloat32(), Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].y).ToFloat32(), - Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].z).ToFloat32() - }; + Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].z).ToFloat32()}; if (position != uniform_block_data.data.light_src[light_index].position) { uniform_block_data.data.light_src[light_index].position = position; @@ -1913,8 +1921,9 @@ void RasterizerVulkan::SyncLightSpotDirection(int light_index) { } void RasterizerVulkan::SyncLightDistanceAttenuationBias(int light_index) { - float dist_atten_bias = Pica::float20::FromRaw(Pica::g_state.regs.lighting.light[light_index].dist_atten_bias) - .ToFloat32(); + float dist_atten_bias = + Pica::float20::FromRaw(Pica::g_state.regs.lighting.light[light_index].dist_atten_bias) + .ToFloat32(); if (dist_atten_bias != uniform_block_data.data.light_src[light_index].dist_atten_bias) { uniform_block_data.data.light_src[light_index].dist_atten_bias = dist_atten_bias; @@ -1923,8 +1932,9 @@ void RasterizerVulkan::SyncLightDistanceAttenuationBias(int light_index) { } void RasterizerVulkan::SyncLightDistanceAttenuationScale(int light_index) { - float dist_atten_scale = Pica::float20::FromRaw(Pica::g_state.regs.lighting.light[light_index].dist_atten_scale) - .ToFloat32(); + float dist_atten_scale = + Pica::float20::FromRaw(Pica::g_state.regs.lighting.light[light_index].dist_atten_scale) + .ToFloat32(); if (dist_atten_scale != uniform_block_data.data.light_src[light_index].dist_atten_scale) { uniform_block_data.data.light_src[light_index].dist_atten_scale = dist_atten_scale; @@ -2032,23 +2042,24 @@ void RasterizerVulkan::SyncAndUploadLUTs() { auto [buffer, offset, invalidate] = texture_buffer.Map(max_size, sizeof(Common::Vec4f)); // helper function for SyncProcTexNoiseLUT/ColorMap/AlphaMap - auto SyncProcTexValueLUT = [this, &buffer = buffer, &offset = offset, &invalidate = invalidate, &bytes_used]( - const std::array& lut, - std::array& lut_data, int& lut_offset) { - std::array new_data; - std::transform(lut.begin(), lut.end(), new_data.begin(), [](const auto& entry) { - return Common::Vec2f{entry.ToFloat(), entry.DiffToFloat()}; - }); + auto SyncProcTexValueLUT = + [this, &buffer = buffer, &offset = offset, &invalidate = invalidate, + &bytes_used](const std::array& lut, + std::array& lut_data, int& lut_offset) { + std::array new_data; + std::transform(lut.begin(), lut.end(), new_data.begin(), [](const auto& entry) { + return Common::Vec2f{entry.ToFloat(), entry.DiffToFloat()}; + }); - if (new_data != lut_data || invalidate) { - lut_data = new_data; - std::memcpy(buffer + bytes_used, new_data.data(), - new_data.size() * sizeof(Common::Vec2f)); - lut_offset = static_cast((offset + bytes_used) / sizeof(Common::Vec2f)); - uniform_block_data.dirty = true; - bytes_used += new_data.size() * sizeof(Common::Vec2f); - } - }; + if (new_data != lut_data || invalidate) { + lut_data = new_data; + std::memcpy(buffer + bytes_used, new_data.data(), + new_data.size() * sizeof(Common::Vec2f)); + lut_offset = static_cast((offset + bytes_used) / sizeof(Common::Vec2f)); + uniform_block_data.dirty = true; + bytes_used += new_data.size() * sizeof(Common::Vec2f); + } + }; // Sync the proctex noise lut if (uniform_block_data.proctex_noise_lut_dirty || invalidate) { @@ -2130,20 +2141,22 @@ void RasterizerVulkan::UploadUniforms(bool accelerate_draw) { u32 used_bytes = 0; const u32 uniform_size = static_cast(uniform_size_aligned_vs + uniform_size_aligned_fs); - auto [uniforms, offset, invalidate] = uniform_buffer.Map(uniform_size, - static_cast(uniform_buffer_alignment)); + auto [uniforms, offset, invalidate] = + uniform_buffer.Map(uniform_size, static_cast(uniform_buffer_alignment)); if (sync_vs) { Pica::Shader::VSUniformData vs_uniforms; vs_uniforms.uniforms.SetFromRegs(Pica::g_state.regs.vs, Pica::g_state.vs); std::memcpy(uniforms + used_bytes, &vs_uniforms, sizeof(vs_uniforms)); - pipeline_cache.BindBuffer(0, uniform_buffer.GetHandle(), offset + used_bytes, sizeof(vs_uniforms)); + pipeline_cache.BindBuffer(0, uniform_buffer.GetHandle(), offset + used_bytes, + sizeof(vs_uniforms)); used_bytes += static_cast(uniform_size_aligned_vs); } if (sync_fs || invalidate) { - std::memcpy(uniforms + used_bytes, &uniform_block_data.data, sizeof(Pica::Shader::UniformData)); + std::memcpy(uniforms + used_bytes, &uniform_block_data.data, + sizeof(Pica::Shader::UniformData)); pipeline_cache.BindBuffer(1, uniform_buffer.GetHandle(), offset + used_bytes, sizeof(uniform_block_data.data)); diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index e2c3f0633..7a5d683b4 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -9,8 +9,8 @@ #include "video_core/rasterizer_accelerated.h" #include "video_core/regs_lighting.h" #include "video_core/regs_texturing.h" -#include "video_core/renderer_vulkan/vk_stream_buffer.h" #include "video_core/renderer_vulkan/vk_pipeline_cache.h" +#include "video_core/renderer_vulkan/vk_stream_buffer.h" #include "video_core/renderer_vulkan/vk_texture_runtime.h" #include "video_core/shader/shader.h" #include "video_core/shader/shader_uniforms.h" @@ -55,7 +55,7 @@ struct FramebufferInfo { auto operator<=>(const FramebufferInfo&) const noexcept = default; }; -} +} // namespace Vulkan namespace std { template <> @@ -77,9 +77,11 @@ namespace Vulkan { class RasterizerVulkan : public VideoCore::RasterizerAccelerated { friend class RendererVulkan; + public: - explicit RasterizerVulkan(Frontend::EmuWindow& emu_window, const Instance& instance, TaskScheduler& scheduler, - TextureRuntime& runtime, RenderpassCache& renderpass_cache); + explicit RasterizerVulkan(Frontend::EmuWindow& emu_window, const Instance& instance, + TaskScheduler& scheduler, TextureRuntime& runtime, + RenderpassCache& renderpass_cache); ~RasterizerVulkan() override; void LoadDiskResources(const std::atomic_bool& stop_loading, diff --git a/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp b/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp index fd9d96af7..5e80fb11d 100644 --- a/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp @@ -4,29 +4,39 @@ #define VULKAN_HPP_NO_CONSTRUCTORS #include "common/assert.h" -#include "video_core/renderer_vulkan/vk_renderpass_cache.h" #include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_renderpass_cache.h" #include "video_core/renderer_vulkan/vk_task_scheduler.h" namespace Vulkan { VideoCore::PixelFormat ToFormatColor(u32 index) { switch (index) { - case 0: return VideoCore::PixelFormat::RGBA8; - case 1: return VideoCore::PixelFormat::RGB8; - case 2: return VideoCore::PixelFormat::RGB5A1; - case 3: return VideoCore::PixelFormat::RGB565; - case 4: return VideoCore::PixelFormat::RGBA4; - default: return VideoCore::PixelFormat::Invalid; + case 0: + return VideoCore::PixelFormat::RGBA8; + case 1: + return VideoCore::PixelFormat::RGB8; + case 2: + return VideoCore::PixelFormat::RGB5A1; + case 3: + return VideoCore::PixelFormat::RGB565; + case 4: + return VideoCore::PixelFormat::RGBA4; + default: + return VideoCore::PixelFormat::Invalid; } } VideoCore::PixelFormat ToFormatDepth(u32 index) { switch (index) { - case 0: return VideoCore::PixelFormat::D16; - case 1: return VideoCore::PixelFormat::D24; - case 3: return VideoCore::PixelFormat::D24S8; - default: return VideoCore::PixelFormat::Invalid; + case 0: + return VideoCore::PixelFormat::D16; + case 1: + return VideoCore::PixelFormat::D24; + case 3: + return VideoCore::PixelFormat::D24S8; + default: + return VideoCore::PixelFormat::Invalid; } } @@ -39,22 +49,20 @@ RenderpassCache::RenderpassCache(const Instance& instance, TaskScheduler& schedu const FormatTraits depth_traits = instance.GetTraits(ToFormatDepth(depth)); const vk::Format color_format = - color_traits.attachment_support ? color_traits.native : color_traits.fallback; + color_traits.attachment_support ? color_traits.native : color_traits.fallback; const vk::Format depth_format = - depth_traits.attachment_support ? depth_traits.native : depth_traits.fallback; + depth_traits.attachment_support ? depth_traits.native : depth_traits.fallback; if (color_format == vk::Format::eUndefined && depth_format == vk::Format::eUndefined) { continue; } - cached_renderpasses[color][depth][0] = CreateRenderPass(color_format, depth_format, - vk::AttachmentLoadOp::eLoad, - vk::ImageLayout::eColorAttachmentOptimal, - vk::ImageLayout::eColorAttachmentOptimal); - cached_renderpasses[color][depth][1] = CreateRenderPass(color_format, depth_format, - vk::AttachmentLoadOp::eClear, - vk::ImageLayout::eColorAttachmentOptimal, - vk::ImageLayout::eColorAttachmentOptimal); + cached_renderpasses[color][depth][0] = CreateRenderPass( + color_format, depth_format, vk::AttachmentLoadOp::eLoad, + vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eColorAttachmentOptimal); + cached_renderpasses[color][depth][1] = CreateRenderPass( + color_format, depth_format, vk::AttachmentLoadOp::eClear, + vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eColorAttachmentOptimal); } } } @@ -102,26 +110,28 @@ void RenderpassCache::ExitRenderpass() { void RenderpassCache::CreatePresentRenderpass(vk::Format format) { if (!present_renderpass) { - present_renderpass = CreateRenderPass(format, vk::Format::eUndefined, - vk::AttachmentLoadOp::eClear, - vk::ImageLayout::eUndefined, - vk::ImageLayout::ePresentSrcKHR); + present_renderpass = + CreateRenderPass(format, vk::Format::eUndefined, vk::AttachmentLoadOp::eClear, + vk::ImageLayout::eUndefined, vk::ImageLayout::ePresentSrcKHR); } } -vk::RenderPass RenderpassCache::GetRenderpass(VideoCore::PixelFormat color, VideoCore::PixelFormat depth, - bool is_clear) const { +vk::RenderPass RenderpassCache::GetRenderpass(VideoCore::PixelFormat color, + VideoCore::PixelFormat depth, bool is_clear) const { const u32 color_index = - color == VideoCore::PixelFormat::Invalid ? MAX_COLOR_FORMATS : static_cast(color); - const u32 depth_index = - depth == VideoCore::PixelFormat::Invalid ? MAX_DEPTH_FORMATS : (static_cast(depth) - 14); + color == VideoCore::PixelFormat::Invalid ? MAX_COLOR_FORMATS : static_cast(color); + const u32 depth_index = depth == VideoCore::PixelFormat::Invalid + ? MAX_DEPTH_FORMATS + : (static_cast(depth) - 14); ASSERT(color_index <= MAX_COLOR_FORMATS && depth_index <= MAX_DEPTH_FORMATS); return cached_renderpasses[color_index][depth_index][is_clear]; } -vk::RenderPass RenderpassCache::CreateRenderPass(vk::Format color, vk::Format depth, vk::AttachmentLoadOp load_op, - vk::ImageLayout initial_layout, vk::ImageLayout final_layout) const { +vk::RenderPass RenderpassCache::CreateRenderPass(vk::Format color, vk::Format depth, + vk::AttachmentLoadOp load_op, + vk::ImageLayout initial_layout, + vk::ImageLayout final_layout) const { // Define attachments u32 attachment_count = 0; std::array attachments; @@ -132,20 +142,17 @@ vk::RenderPass RenderpassCache::CreateRenderPass(vk::Format color, vk::Format de vk::AttachmentReference depth_attachment_ref{}; if (color != vk::Format::eUndefined) { - attachments[attachment_count] = vk::AttachmentDescription{ - .format = color, - .loadOp = load_op, - .storeOp = vk::AttachmentStoreOp::eStore, - .stencilLoadOp = vk::AttachmentLoadOp::eDontCare, - .stencilStoreOp = vk::AttachmentStoreOp::eDontCare, - .initialLayout = initial_layout, - .finalLayout = final_layout - }; + attachments[attachment_count] = + vk::AttachmentDescription{.format = color, + .loadOp = load_op, + .storeOp = vk::AttachmentStoreOp::eStore, + .stencilLoadOp = vk::AttachmentLoadOp::eDontCare, + .stencilStoreOp = vk::AttachmentStoreOp::eDontCare, + .initialLayout = initial_layout, + .finalLayout = final_layout}; color_attachment_ref = vk::AttachmentReference{ - .attachment = attachment_count++, - .layout = vk::ImageLayout::eColorAttachmentOptimal - }; + .attachment = attachment_count++, .layout = vk::ImageLayout::eColorAttachmentOptimal}; use_color = true; } @@ -158,40 +165,35 @@ vk::RenderPass RenderpassCache::CreateRenderPass(vk::Format color, vk::Format de .stencilLoadOp = vk::AttachmentLoadOp::eLoad, .stencilStoreOp = vk::AttachmentStoreOp::eStore, .initialLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal, - .finalLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal - }; + .finalLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal}; - depth_attachment_ref = vk::AttachmentReference{ - .attachment = attachment_count++, - .layout = vk::ImageLayout::eDepthStencilAttachmentOptimal - }; + depth_attachment_ref = + vk::AttachmentReference{.attachment = attachment_count++, + .layout = vk::ImageLayout::eDepthStencilAttachmentOptimal}; use_depth = true; } // We also require only one subpass - const vk::SubpassDescription subpass = { - .pipelineBindPoint = vk::PipelineBindPoint::eGraphics, - .inputAttachmentCount = 0, - .pInputAttachments = nullptr, - .colorAttachmentCount = use_color ? 1u : 0u, - .pColorAttachments = &color_attachment_ref, - .pResolveAttachments = 0, - .pDepthStencilAttachment = use_depth ? &depth_attachment_ref : nullptr - }; + const vk::SubpassDescription subpass = {.pipelineBindPoint = vk::PipelineBindPoint::eGraphics, + .inputAttachmentCount = 0, + .pInputAttachments = nullptr, + .colorAttachmentCount = use_color ? 1u : 0u, + .pColorAttachments = &color_attachment_ref, + .pResolveAttachments = 0, + .pDepthStencilAttachment = + use_depth ? &depth_attachment_ref : nullptr}; - const vk::RenderPassCreateInfo renderpass_info = { - .attachmentCount = attachment_count, - .pAttachments = attachments.data(), - .subpassCount = 1, - .pSubpasses = &subpass, - .dependencyCount = 0, - .pDependencies = nullptr - }; + const vk::RenderPassCreateInfo renderpass_info = {.attachmentCount = attachment_count, + .pAttachments = attachments.data(), + .subpassCount = 1, + .pSubpasses = &subpass, + .dependencyCount = 0, + .pDependencies = nullptr}; // Create the renderpass vk::Device device = instance.GetDevice(); return device.createRenderPass(renderpass_info); } -} // namespace VideoCore::Vulkan +} // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_renderpass_cache.h b/src/video_core/renderer_vulkan/vk_renderpass_cache.h index 37aaa83d1..34670386a 100644 --- a/src/video_core/renderer_vulkan/vk_renderpass_cache.h +++ b/src/video_core/renderer_vulkan/vk_renderpass_cache.h @@ -30,8 +30,8 @@ public: void CreatePresentRenderpass(vk::Format format); /// Returns the renderpass associated with the color-depth format pair - [[nodiscard]] vk::RenderPass GetRenderpass(VideoCore::PixelFormat color, VideoCore::PixelFormat depth, - bool is_clear) const; + [[nodiscard]] vk::RenderPass GetRenderpass(VideoCore::PixelFormat color, + VideoCore::PixelFormat depth, bool is_clear) const; /// Returns the swapchain clear renderpass [[nodiscard]] vk::RenderPass GetPresentRenderpass() const { return present_renderpass; @@ -44,8 +44,9 @@ public: private: /// Creates a renderpass configured appropriately and stores it in cached_renderpasses - vk::RenderPass CreateRenderPass(vk::Format color, vk::Format depth, vk::AttachmentLoadOp load_op, - vk::ImageLayout initial_layout, vk::ImageLayout final_layout) const; + vk::RenderPass CreateRenderPass(vk::Format color, vk::Format depth, + vk::AttachmentLoadOp load_op, vk::ImageLayout initial_layout, + vk::ImageLayout final_layout) const; private: const Instance& instance; @@ -53,7 +54,7 @@ private: vk::RenderPass active_renderpass = VK_NULL_HANDLE; vk::RenderPass present_renderpass{}; - vk::RenderPass cached_renderpasses[MAX_COLOR_FORMATS+1][MAX_DEPTH_FORMATS+1][2]; + vk::RenderPass cached_renderpasses[MAX_COLOR_FORMATS + 1][MAX_DEPTH_FORMATS + 1][2]; }; } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_shader.cpp b/src/video_core/renderer_vulkan/vk_shader.cpp index ce0038328..d0a54a200 100644 --- a/src/video_core/renderer_vulkan/vk_shader.cpp +++ b/src/video_core/renderer_vulkan/vk_shader.cpp @@ -3,121 +3,120 @@ // Refer to the license.txt file included. #define VULKAN_HPP_NO_CONSTRUCTORS +#include +#include +#include #include "common/assert.h" #include "common/logging/log.h" #include "video_core/renderer_vulkan/vk_shader.h" -#include -#include -#include namespace Vulkan { -constexpr TBuiltInResource DefaultTBuiltInResource = { - .maxLights = 32, - .maxClipPlanes = 6, - .maxTextureUnits = 32, - .maxTextureCoords = 32, - .maxVertexAttribs = 64, - .maxVertexUniformComponents = 4096, - .maxVaryingFloats = 64, - .maxVertexTextureImageUnits = 32, - .maxCombinedTextureImageUnits = 80, - .maxTextureImageUnits = 32, - .maxFragmentUniformComponents = 4096, - .maxDrawBuffers = 32, - .maxVertexUniformVectors = 128, - .maxVaryingVectors = 8, - .maxFragmentUniformVectors = 16, - .maxVertexOutputVectors = 16, - .maxFragmentInputVectors = 15, - .minProgramTexelOffset = -8, - .maxProgramTexelOffset = 7, - .maxClipDistances = 8, - .maxComputeWorkGroupCountX = 65535, - .maxComputeWorkGroupCountY = 65535, - .maxComputeWorkGroupCountZ = 65535, - .maxComputeWorkGroupSizeX = 1024, - .maxComputeWorkGroupSizeY = 1024, - .maxComputeWorkGroupSizeZ = 64, - .maxComputeUniformComponents = 1024, - .maxComputeTextureImageUnits = 16, - .maxComputeImageUniforms = 8, - .maxComputeAtomicCounters = 8, - .maxComputeAtomicCounterBuffers = 1, - .maxVaryingComponents = 60, - .maxVertexOutputComponents = 64, - .maxGeometryInputComponents = 64, - .maxGeometryOutputComponents = 128, - .maxFragmentInputComponents = 128, - .maxImageUnits = 8, - .maxCombinedImageUnitsAndFragmentOutputs = 8, - .maxCombinedShaderOutputResources = 8, - .maxImageSamples = 0, - .maxVertexImageUniforms = 0, - .maxTessControlImageUniforms = 0, - .maxTessEvaluationImageUniforms = 0, - .maxGeometryImageUniforms = 0, - .maxFragmentImageUniforms = 8, - .maxCombinedImageUniforms = 8, - .maxGeometryTextureImageUnits = 16, - .maxGeometryOutputVertices = 256, - .maxGeometryTotalOutputComponents = 1024, - .maxGeometryUniformComponents = 1024, - .maxGeometryVaryingComponents = 64, - .maxTessControlInputComponents = 128, - .maxTessControlOutputComponents = 128, - .maxTessControlTextureImageUnits = 16, - .maxTessControlUniformComponents = 1024, - .maxTessControlTotalOutputComponents = 4096, - .maxTessEvaluationInputComponents = 128, - .maxTessEvaluationOutputComponents = 128, - .maxTessEvaluationTextureImageUnits = 16, - .maxTessEvaluationUniformComponents = 1024, - .maxTessPatchComponents = 120, - .maxPatchVertices = 32, - .maxTessGenLevel = 64, - .maxViewports = 16, - .maxVertexAtomicCounters = 0, - .maxTessControlAtomicCounters = 0, - .maxTessEvaluationAtomicCounters = 0, - .maxGeometryAtomicCounters = 0, - .maxFragmentAtomicCounters = 8, - .maxCombinedAtomicCounters = 8, - .maxAtomicCounterBindings = 1, - .maxVertexAtomicCounterBuffers = 0, - .maxTessControlAtomicCounterBuffers = 0, - .maxTessEvaluationAtomicCounterBuffers = 0, - .maxGeometryAtomicCounterBuffers = 0, - .maxFragmentAtomicCounterBuffers = 1, - .maxCombinedAtomicCounterBuffers = 1, - .maxAtomicCounterBufferSize = 16384, - .maxTransformFeedbackBuffers = 4, - .maxTransformFeedbackInterleavedComponents = 64, - .maxCullDistances = 8, - .maxCombinedClipAndCullDistances = 8, - .maxSamples = 4, - .maxMeshOutputVerticesNV = 256, - .maxMeshOutputPrimitivesNV = 512, - .maxMeshWorkGroupSizeX_NV = 32, - .maxMeshWorkGroupSizeY_NV = 1, - .maxMeshWorkGroupSizeZ_NV = 1, - .maxTaskWorkGroupSizeX_NV = 32, - .maxTaskWorkGroupSizeY_NV = 1, - .maxTaskWorkGroupSizeZ_NV = 1, - .maxMeshViewCountNV = 4, - .maxDualSourceDrawBuffersEXT = 1, - .limits = TLimits{ - .nonInductiveForLoops = 1, - .whileLoops = 1, - .doWhileLoops = 1, - .generalUniformIndexing = 1, - .generalAttributeMatrixVectorIndexing = 1, - .generalVaryingIndexing = 1, - .generalSamplerIndexing = 1, - .generalVariableIndexing = 1, - .generalConstantMatrixVectorIndexing = 1, - } -}; +constexpr TBuiltInResource DefaultTBuiltInResource = {.maxLights = 32, + .maxClipPlanes = 6, + .maxTextureUnits = 32, + .maxTextureCoords = 32, + .maxVertexAttribs = 64, + .maxVertexUniformComponents = 4096, + .maxVaryingFloats = 64, + .maxVertexTextureImageUnits = 32, + .maxCombinedTextureImageUnits = 80, + .maxTextureImageUnits = 32, + .maxFragmentUniformComponents = 4096, + .maxDrawBuffers = 32, + .maxVertexUniformVectors = 128, + .maxVaryingVectors = 8, + .maxFragmentUniformVectors = 16, + .maxVertexOutputVectors = 16, + .maxFragmentInputVectors = 15, + .minProgramTexelOffset = -8, + .maxProgramTexelOffset = 7, + .maxClipDistances = 8, + .maxComputeWorkGroupCountX = 65535, + .maxComputeWorkGroupCountY = 65535, + .maxComputeWorkGroupCountZ = 65535, + .maxComputeWorkGroupSizeX = 1024, + .maxComputeWorkGroupSizeY = 1024, + .maxComputeWorkGroupSizeZ = 64, + .maxComputeUniformComponents = 1024, + .maxComputeTextureImageUnits = 16, + .maxComputeImageUniforms = 8, + .maxComputeAtomicCounters = 8, + .maxComputeAtomicCounterBuffers = 1, + .maxVaryingComponents = 60, + .maxVertexOutputComponents = 64, + .maxGeometryInputComponents = 64, + .maxGeometryOutputComponents = 128, + .maxFragmentInputComponents = 128, + .maxImageUnits = 8, + .maxCombinedImageUnitsAndFragmentOutputs = 8, + .maxCombinedShaderOutputResources = 8, + .maxImageSamples = 0, + .maxVertexImageUniforms = 0, + .maxTessControlImageUniforms = 0, + .maxTessEvaluationImageUniforms = 0, + .maxGeometryImageUniforms = 0, + .maxFragmentImageUniforms = 8, + .maxCombinedImageUniforms = 8, + .maxGeometryTextureImageUnits = 16, + .maxGeometryOutputVertices = 256, + .maxGeometryTotalOutputComponents = 1024, + .maxGeometryUniformComponents = 1024, + .maxGeometryVaryingComponents = 64, + .maxTessControlInputComponents = 128, + .maxTessControlOutputComponents = 128, + .maxTessControlTextureImageUnits = 16, + .maxTessControlUniformComponents = 1024, + .maxTessControlTotalOutputComponents = 4096, + .maxTessEvaluationInputComponents = 128, + .maxTessEvaluationOutputComponents = 128, + .maxTessEvaluationTextureImageUnits = 16, + .maxTessEvaluationUniformComponents = 1024, + .maxTessPatchComponents = 120, + .maxPatchVertices = 32, + .maxTessGenLevel = 64, + .maxViewports = 16, + .maxVertexAtomicCounters = 0, + .maxTessControlAtomicCounters = 0, + .maxTessEvaluationAtomicCounters = 0, + .maxGeometryAtomicCounters = 0, + .maxFragmentAtomicCounters = 8, + .maxCombinedAtomicCounters = 8, + .maxAtomicCounterBindings = 1, + .maxVertexAtomicCounterBuffers = 0, + .maxTessControlAtomicCounterBuffers = 0, + .maxTessEvaluationAtomicCounterBuffers = 0, + .maxGeometryAtomicCounterBuffers = 0, + .maxFragmentAtomicCounterBuffers = 1, + .maxCombinedAtomicCounterBuffers = 1, + .maxAtomicCounterBufferSize = 16384, + .maxTransformFeedbackBuffers = 4, + .maxTransformFeedbackInterleavedComponents = + 64, + .maxCullDistances = 8, + .maxCombinedClipAndCullDistances = 8, + .maxSamples = 4, + .maxMeshOutputVerticesNV = 256, + .maxMeshOutputPrimitivesNV = 512, + .maxMeshWorkGroupSizeX_NV = 32, + .maxMeshWorkGroupSizeY_NV = 1, + .maxMeshWorkGroupSizeZ_NV = 1, + .maxTaskWorkGroupSizeX_NV = 32, + .maxTaskWorkGroupSizeY_NV = 1, + .maxTaskWorkGroupSizeZ_NV = 1, + .maxMeshViewCountNV = 4, + .maxDualSourceDrawBuffersEXT = 1, + .limits = TLimits{ + .nonInductiveForLoops = 1, + .whileLoops = 1, + .doWhileLoops = 1, + .generalUniformIndexing = 1, + .generalAttributeMatrixVectorIndexing = 1, + .generalVaryingIndexing = 1, + .generalSamplerIndexing = 1, + .generalVariableIndexing = 1, + .generalConstantMatrixVectorIndexing = 1, + }}; EShLanguage ToEshShaderStage(vk::ShaderStageFlagBits stage) { switch (stage) { @@ -162,7 +161,8 @@ vk::ShaderModule Compile(std::string_view code, vk::ShaderStageFlagBits stage, v } EProfile profile = ECoreProfile; - EShMessages messages = static_cast(EShMsgDefault | EShMsgSpvRules | EShMsgVulkanRules); + EShMessages messages = + static_cast(EShMsgDefault | EShMsgSpvRules | EShMsgVulkanRules); EShLanguage lang = ToEshShaderStage(stage); int default_version = 450; @@ -170,12 +170,15 @@ vk::ShaderModule Compile(std::string_view code, vk::ShaderStageFlagBits stage, v int pass_source_code_length = static_cast(code.size()); auto shader = std::make_unique(lang); - shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetLanguageVersion::EShTargetSpv_1_3); + shader->setEnvTarget(glslang::EShTargetSpv, + glslang::EShTargetLanguageVersion::EShTargetSpv_1_3); shader->setStringsWithLengths(&pass_source_code, &pass_source_code_length, 1); glslang::TShader::ForbidIncluder includer; - if (!shader->parse(&DefaultTBuiltInResource, default_version, profile, false, true, messages, includer)) { - LOG_CRITICAL(Render_Vulkan, "Shader Info Log:\n{}\n{}", shader->getInfoLog(), shader->getInfoDebugLog()); + if (!shader->parse(&DefaultTBuiltInResource, default_version, profile, false, true, messages, + includer)) { + LOG_CRITICAL(Render_Vulkan, "Shader Info Log:\n{}\n{}", shader->getInfoLog(), + shader->getInfoDebugLog()); return VK_NULL_HANDLE; } @@ -183,7 +186,8 @@ vk::ShaderModule Compile(std::string_view code, vk::ShaderStageFlagBits stage, v auto program = std::make_unique(); program->addShader(shader.get()); if (!program->link(messages)) { - LOG_CRITICAL(Render_Vulkan, "Program Info Log:\n{}\n{}", program->getInfoLog(), program->getInfoDebugLog()); + LOG_CRITICAL(Render_Vulkan, "Program Info Log:\n{}\n{}", program->getInfoLog(), + program->getInfoDebugLog()); return VK_NULL_HANDLE; } @@ -212,10 +216,8 @@ vk::ShaderModule Compile(std::string_view code, vk::ShaderStageFlagBits stage, v LOG_INFO(Render_Vulkan, "SPIR-V conversion messages: {}", spv_messages); } - const vk::ShaderModuleCreateInfo shader_info = { - .codeSize = out_code.size() * sizeof(u32), - .pCode = out_code.data() - }; + const vk::ShaderModuleCreateInfo shader_info = {.codeSize = out_code.size() * sizeof(u32), + .pCode = out_code.data()}; return device.createShaderModule(shader_info); } diff --git a/src/video_core/renderer_vulkan/vk_shader.h b/src/video_core/renderer_vulkan/vk_shader.h index 14d225d88..2fb8f380b 100644 --- a/src/video_core/renderer_vulkan/vk_shader.h +++ b/src/video_core/renderer_vulkan/vk_shader.h @@ -8,12 +8,9 @@ namespace Vulkan { -enum class ShaderOptimization { - High = 0, - Debug = 1 -}; +enum class ShaderOptimization { High = 0, Debug = 1 }; -vk::ShaderModule Compile(std::string_view code, vk::ShaderStageFlagBits stage, - vk::Device device, ShaderOptimization level); +vk::ShaderModule Compile(std::string_view code, vk::ShaderStageFlagBits stage, vk::Device device, + ShaderOptimization level); } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_shader_gen.cpp b/src/video_core/renderer_vulkan/vk_shader_gen.cpp index 2dc39f41a..17e55a766 100644 --- a/src/video_core/renderer_vulkan/vk_shader_gen.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_gen.cpp @@ -293,7 +293,8 @@ static std::string SampleTexture(const PicaFSConfig& config, unsigned texture_un // Only unit 0 respects the texturing type switch (state.texture0_type) { case TexturingRegs::TextureConfig::Texture2D: - return "textureLod(sampler2D(tex0, tex0_sampler), texcoord0, getLod(texcoord0 * vec2(textureSize(sampler2D(tex0, tex0_sampler), 0))))"; + return "textureLod(sampler2D(tex0, tex0_sampler), texcoord0, getLod(texcoord0 * " + "vec2(textureSize(sampler2D(tex0, tex0_sampler), 0))))"; case TexturingRegs::TextureConfig::Projection2D: // TODO (wwylele): find the exact LOD formula for projection texture return "textureProj(sampler2D(tex0, tex0_sampler), vec3(texcoord0, texcoord0_w))"; @@ -311,12 +312,15 @@ static std::string SampleTexture(const PicaFSConfig& config, unsigned texture_un return "texture(sampler2D(tex0, tex0_sampler), texcoord0)"; } case 1: - return "textureLod(sampler2D(tex1, tex1_sampler), texcoord1, getLod(texcoord1 * vec2(textureSize(sampler2D(tex1, tex1_sampler), 0))))"; + return "textureLod(sampler2D(tex1, tex1_sampler), texcoord1, getLod(texcoord1 * " + "vec2(textureSize(sampler2D(tex1, tex1_sampler), 0))))"; case 2: if (state.texture2_use_coord1) - return "textureLod(sampler2D(tex2, tex2_sampler), texcoord1, getLod(texcoord1 * vec2(textureSize(sampler2D(tex2, tex2_sampler), 0))))"; + return "textureLod(sampler2D(tex2, tex2_sampler), texcoord1, getLod(texcoord1 * " + "vec2(textureSize(sampler2D(tex2, tex2_sampler), 0))))"; else - return "textureLod(sampler2D(tex2, tex2_sampler), texcoord2, getLod(texcoord2 * vec2(textureSize(sampler2D(tex2, tex2_sampler), 0))))"; + return "textureLod(sampler2D(tex2, tex2_sampler), texcoord2, getLod(texcoord2 * " + "vec2(textureSize(sampler2D(tex2, tex2_sampler), 0))))"; case 3: if (state.proctex.enable) { return "ProcTex()"; @@ -1580,8 +1584,8 @@ void main() { return out; } -std::optional GenerateVertexShader( - const Pica::Shader::ShaderSetup& setup, const PicaVSConfig& config) { +std::optional GenerateVertexShader(const Pica::Shader::ShaderSetup& setup, + const PicaVSConfig& config) { /*std::string out = "#extension GL_ARB_separate_shader_objects : enable\n"; out += ShaderDecompiler::GetCommonDeclarations(); @@ -1626,7 +1630,8 @@ layout (std140) uniform vs_config { // output attributes declaration for (u32 i = 0; i < config.state.num_outputs; ++i) { - out += "layout(location = " + std::to_string(i) + ") out vec4 vs_out_attr" + std::to_string(i) + ";\n"; + out += "layout(location = " + std::to_string(i) + ") out vec4 vs_out_attr" + +std::to_string(i) + ";\n"; } out += "\nvoid main() {\n"; @@ -1648,7 +1653,8 @@ static std::string GetGSCommonSource(const PicaGSConfigCommonRaw& config) { out += '\n'; for (u32 i = 0; i < config.vs_output_attributes; ++i) { - out += ("layout(location = " + std::to_string(i) + ") in vec4 vs_out_attr" + std::to_string(i) + "[];\n"; + out += ("layout(location = " + std::to_string(i) + ") in vec4 vs_out_attr" + +std::to_string(i) + "[];\n"; } out += R"( diff --git a/src/video_core/renderer_vulkan/vk_shader_gen.h b/src/video_core/renderer_vulkan/vk_shader_gen.h index 7686edc25..cbf26ea15 100644 --- a/src/video_core/renderer_vulkan/vk_shader_gen.h +++ b/src/video_core/renderer_vulkan/vk_shader_gen.h @@ -203,8 +203,8 @@ std::string GenerateTrivialVertexShader(); * Generates the GLSL vertex shader program source code for the given VS program * @returns String of the shader source code; boost::none on failure */ -std::optional GenerateVertexShader( - const Pica::Shader::ShaderSetup& setup, const PicaVSConfig& config); +std::optional GenerateVertexShader(const Pica::Shader::ShaderSetup& setup, + const PicaVSConfig& config); /** * Generates the GLSL fixed geometry shader program source code for non-GS PICA pipeline diff --git a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp index d8f4aee34..5d06d5935 100644 --- a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp +++ b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp @@ -7,9 +7,9 @@ #include "common/alignment.h" #include "common/assert.h" #include "common/logging/log.h" +#include "video_core/renderer_vulkan/vk_instance.h" #include "video_core/renderer_vulkan/vk_stream_buffer.h" #include "video_core/renderer_vulkan/vk_task_scheduler.h" -#include "video_core/renderer_vulkan/vk_instance.h" namespace Vulkan { @@ -21,13 +21,13 @@ inline auto ToVkAccessStageFlags(vk::BufferUsageFlagBits usage) { vk::PipelineStageFlagBits::eVertexInput); break; case vk::BufferUsageFlagBits::eIndexBuffer: - result = std::make_pair(vk::AccessFlagBits::eIndexRead, - vk::PipelineStageFlagBits::eVertexInput); + result = + std::make_pair(vk::AccessFlagBits::eIndexRead, vk::PipelineStageFlagBits::eVertexInput); case vk::BufferUsageFlagBits::eUniformBuffer: result = std::make_pair(vk::AccessFlagBits::eUniformRead, vk::PipelineStageFlagBits::eVertexShader | - vk::PipelineStageFlagBits::eGeometryShader | - vk::PipelineStageFlagBits::eFragmentShader); + vk::PipelineStageFlagBits::eGeometryShader | + vk::PipelineStageFlagBits::eFragmentShader); case vk::BufferUsageFlagBits::eUniformTexelBuffer: result = std::make_pair(vk::AccessFlagBits::eShaderRead, vk::PipelineStageFlagBits::eFragmentShader); @@ -41,24 +41,20 @@ inline auto ToVkAccessStageFlags(vk::BufferUsageFlagBits usage) { StagingBuffer::StagingBuffer(const Instance& instance, u32 size, vk::BufferUsageFlags usage) : instance{instance} { - const vk::BufferCreateInfo buffer_info = { - .size = size, - .usage = usage - }; + const vk::BufferCreateInfo buffer_info = {.size = size, .usage = usage}; const VmaAllocationCreateInfo alloc_create_info = { .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | - VMA_ALLOCATION_CREATE_MAPPED_BIT, - .usage = VMA_MEMORY_USAGE_AUTO_PREFER_HOST - }; + VMA_ALLOCATION_CREATE_MAPPED_BIT, + .usage = VMA_MEMORY_USAGE_AUTO_PREFER_HOST}; VkBuffer unsafe_buffer = VK_NULL_HANDLE; VkBufferCreateInfo unsafe_buffer_info = static_cast(buffer_info); VmaAllocationInfo alloc_info; VmaAllocator allocator = instance.GetAllocator(); - vmaCreateBuffer(allocator, &unsafe_buffer_info, &alloc_create_info, - &unsafe_buffer, &allocation, &alloc_info); + vmaCreateBuffer(allocator, &unsafe_buffer_info, &alloc_create_info, &unsafe_buffer, &allocation, + &alloc_info); buffer = vk::Buffer{unsafe_buffer}; mapped = std::span{reinterpret_cast(alloc_info.pMappedData), size}; @@ -68,27 +64,25 @@ StagingBuffer::~StagingBuffer() { vmaDestroyBuffer(instance.GetAllocator(), static_cast(buffer), allocation); } -StreamBuffer::StreamBuffer(const Instance& instance, TaskScheduler& scheduler, - u32 size, vk::BufferUsageFlagBits usage, std::span view_formats) - : instance{instance}, scheduler{scheduler}, staging{instance, size, vk::BufferUsageFlagBits::eTransferSrc}, +StreamBuffer::StreamBuffer(const Instance& instance, TaskScheduler& scheduler, u32 size, + vk::BufferUsageFlagBits usage, std::span view_formats) + : instance{instance}, scheduler{scheduler}, staging{instance, size, + vk::BufferUsageFlagBits::eTransferSrc}, usage{usage}, total_size{size} { const vk::BufferCreateInfo buffer_info = { - .size = total_size, - .usage = usage | vk::BufferUsageFlagBits::eTransferDst - }; + .size = total_size, .usage = usage | vk::BufferUsageFlagBits::eTransferDst}; - const VmaAllocationCreateInfo alloc_create_info = { - .usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE - }; + const VmaAllocationCreateInfo alloc_create_info = {.usage = + VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE}; VkBuffer unsafe_buffer = VK_NULL_HANDLE; VkBufferCreateInfo unsafe_buffer_info = static_cast(buffer_info); VmaAllocationInfo alloc_info; VmaAllocator allocator = instance.GetAllocator(); - vmaCreateBuffer(allocator, &unsafe_buffer_info, &alloc_create_info, - &unsafe_buffer, &allocation, &alloc_info); + vmaCreateBuffer(allocator, &unsafe_buffer_info, &alloc_create_info, &unsafe_buffer, &allocation, + &alloc_info); buffer = vk::Buffer{unsafe_buffer}; @@ -97,11 +91,7 @@ StreamBuffer::StreamBuffer(const Instance& instance, TaskScheduler& scheduler, vk::Device device = instance.GetDevice(); for (std::size_t i = 0; i < view_formats.size(); i++) { const vk::BufferViewCreateInfo view_info = { - .buffer = buffer, - .format = view_formats[i], - .offset = 0, - .range = total_size - }; + .buffer = buffer, .format = view_formats[i], .offset = 0, .range = total_size}; views[i] = device.createBufferView(view_info); } @@ -138,7 +128,6 @@ std::tuple StreamBuffer::Map(u32 size, u32 alignment) { const u32 buffer_offset = current_bucket * bucket_size + bucket.offset; u8* mapped = reinterpret_cast(staging.mapped.data() + buffer_offset); return std::make_tuple(mapped, buffer_offset, invalidate); - } void StreamBuffer::Commit(u32 size) { @@ -156,10 +145,7 @@ void StreamBuffer::Flush() { const u32 flush_start = current_bucket * bucket_size; const vk::BufferCopy copy_region = { - .srcOffset = flush_start, - .dstOffset = flush_start, - .size = flush_size - }; + .srcOffset = flush_start, .dstOffset = flush_start, .size = flush_size}; vmaFlushAllocation(allocator, allocation, flush_start, flush_size); command_buffer.copyBuffer(staging.buffer, buffer, copy_region); @@ -173,8 +159,7 @@ void StreamBuffer::Flush() { .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .buffer = buffer, .offset = flush_start, - .size = flush_size - }; + .size = flush_size}; command_buffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, stage_mask, vk::DependencyFlagBits::eByRegion, {}, buffer_barrier, {}); diff --git a/src/video_core/renderer_vulkan/vk_stream_buffer.h b/src/video_core/renderer_vulkan/vk_stream_buffer.h index c7aefb1be..4c3881ba7 100644 --- a/src/video_core/renderer_vulkan/vk_stream_buffer.h +++ b/src/video_core/renderer_vulkan/vk_stream_buffer.h @@ -33,8 +33,8 @@ struct StagingBuffer { class StreamBuffer { public: - StreamBuffer(const Instance& instance, TaskScheduler& scheduler, - u32 size, vk::BufferUsageFlagBits usage, std::span views); + StreamBuffer(const Instance& instance, TaskScheduler& scheduler, u32 size, + vk::BufferUsageFlagBits usage, std::span views); ~StreamBuffer(); std::tuple Map(u32 size, u32 alignment = 0); diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index 361b12628..c4fee5f00 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp @@ -5,9 +5,9 @@ #define VULKAN_HPP_NO_CONSTRUCTORS #include #include "common/logging/log.h" -#include "video_core/renderer_vulkan/vk_swapchain.h" #include "video_core/renderer_vulkan/vk_instance.h" #include "video_core/renderer_vulkan/vk_renderpass_cache.h" +#include "video_core/renderer_vulkan/vk_swapchain.h" namespace Vulkan { @@ -44,7 +44,7 @@ void Swapchain::Create(u32 width, u32 height, bool vsync_enabled) { const bool exclusive = queue_family_indices[0] == queue_family_indices[1]; const u32 queue_family_indices_count = exclusive ? 1u : 2u; const vk::SharingMode sharing_mode = - exclusive ? vk::SharingMode::eExclusive : vk::SharingMode::eConcurrent; + exclusive ? vk::SharingMode::eExclusive : vk::SharingMode::eConcurrent; const vk::SwapchainCreateInfoKHR swapchain_info = { .surface = surface, .minImageCount = image_count, @@ -55,12 +55,11 @@ void Swapchain::Create(u32 width, u32 height, bool vsync_enabled) { .imageUsage = vk::ImageUsageFlagBits::eColorAttachment, .imageSharingMode = sharing_mode, .queueFamilyIndexCount = queue_family_indices_count, - .pQueueFamilyIndices = queue_family_indices.data(), + .pQueueFamilyIndices = queue_family_indices.data(), .preTransform = transform, .presentMode = present_mode, .clipped = true, - .oldSwapchain = swapchain - }; + .oldSwapchain = swapchain}; vk::Device device = instance.GetDevice(); vk::SwapchainKHR new_swapchain = device.createSwapchainKHR(swapchain_info); @@ -87,34 +86,25 @@ void Swapchain::Create(u32 width, u32 height, bool vsync_enabled) { .image = image, .viewType = vk::ImageViewType::e2D, .format = surface_format.format, - .subresourceRange = { - .aspectMask = vk::ImageAspectFlagBits::eColor, - .baseMipLevel = 0, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = 1 - } - }; + .subresourceRange = {.aspectMask = vk::ImageAspectFlagBits::eColor, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1}}; vk::ImageView image_view = device.createImageView(view_info); const std::array attachments{image_view}; - const vk::FramebufferCreateInfo framebuffer_info = { - .renderPass = present_renderpass, - .attachmentCount = 1, - .pAttachments = attachments.data(), - .width = extent.width, - .height = extent.height, - .layers = 1 - }; + const vk::FramebufferCreateInfo framebuffer_info = {.renderPass = present_renderpass, + .attachmentCount = 1, + .pAttachments = attachments.data(), + .width = extent.width, + .height = extent.height, + .layers = 1}; vk::Framebuffer framebuffer = device.createFramebuffer(framebuffer_info); - return Image{ - .image = image, - .image_view = image_view, - .framebuffer = framebuffer - }; + return Image{.image = image, .image_view = image_view, .framebuffer = framebuffer}; }); } @@ -141,13 +131,11 @@ void Swapchain::AcquireNextImage(vk::Semaphore signal_acquired) { } void Swapchain::Present(vk::Semaphore wait_for_present) { - const vk::PresentInfoKHR present_info = { - .waitSemaphoreCount = 1, - .pWaitSemaphores = &wait_for_present, - .swapchainCount = 1, - .pSwapchains = &swapchain, - .pImageIndices = ¤t_image - }; + const vk::PresentInfoKHR present_info = {.waitSemaphoreCount = 1, + .pWaitSemaphores = &wait_for_present, + .swapchainCount = 1, + .pSwapchains = &swapchain, + .pImageIndices = ¤t_image}; vk::Queue present_queue = instance.GetPresentQueue(); vk::Result result = present_queue.presentKHR(present_info); @@ -181,7 +169,7 @@ void Swapchain::Configure(u32 width, u32 height) { } else { auto it = std::ranges::find_if(formats, [](vk::SurfaceFormatKHR format) -> bool { return format.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear && - format.format == vk::Format::eB8G8R8A8Unorm; + format.format == vk::Format::eB8G8R8A8Unorm; }); if (it == formats.end()) { @@ -196,9 +184,8 @@ void Swapchain::Configure(u32 width, u32 height) { // FIFO is guaranteed by the Vulkan standard to be available present_mode = vk::PresentModeKHR::eFifo; - auto iter = std::ranges::find_if(modes, [](vk::PresentModeKHR mode) { - return vk::PresentModeKHR::eMailbox == mode; - }); + auto iter = std::ranges::find_if( + modes, [](vk::PresentModeKHR mode) { return vk::PresentModeKHR::eMailbox == mode; }); // Prefer Mailbox if present for lowest latency if (iter != modes.end()) { @@ -210,10 +197,10 @@ void Swapchain::Configure(u32 width, u32 height) { extent = capabilities.currentExtent; if (capabilities.currentExtent.width == std::numeric_limits::max()) { - extent.width = std::clamp(width, capabilities.minImageExtent.width, - capabilities.maxImageExtent.width); + extent.width = + std::clamp(width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width); extent.height = std::clamp(height, capabilities.minImageExtent.height, - capabilities.maxImageExtent.height); + capabilities.maxImageExtent.height); } // Select number of images in swap chain, we prefer one buffer in the background to work on diff --git a/src/video_core/renderer_vulkan/vk_task_scheduler.cpp b/src/video_core/renderer_vulkan/vk_task_scheduler.cpp index fb601b6b7..ceeb1a58d 100644 --- a/src/video_core/renderer_vulkan/vk_task_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_task_scheduler.cpp @@ -6,8 +6,8 @@ #include "common/assert.h" #include "common/logging/log.h" #include "video_core/renderer_vulkan/renderer_vulkan.h" -#include "video_core/renderer_vulkan/vk_task_scheduler.h" #include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_task_scheduler.h" namespace Vulkan { @@ -16,8 +16,7 @@ TaskScheduler::TaskScheduler(const Instance& instance, RendererVulkan& renderer) vk::Device device = instance.GetDevice(); const vk::CommandPoolCreateInfo command_pool_info = { .flags = vk::CommandPoolCreateFlagBits::eResetCommandBuffer, - .queueFamilyIndex = instance.GetGraphicsQueueFamilyIndex() - }; + .queueFamilyIndex = instance.GetGraphicsQueueFamilyIndex()}; command_pool = device.createCommandPool(command_pool_info); @@ -25,11 +24,8 @@ TaskScheduler::TaskScheduler(const Instance& instance, RendererVulkan& renderer) if (instance.IsTimelineSemaphoreSupported()) { const vk::StructureChain timeline_info = { vk::SemaphoreCreateInfo{}, - vk::SemaphoreTypeCreateInfo{ - .semaphoreType = vk::SemaphoreType::eTimeline, - .initialValue = 0 - } - }; + vk::SemaphoreTypeCreateInfo{.semaphoreType = vk::SemaphoreType::eTimeline, + .initialValue = 0}}; timeline = device.createSemaphore(timeline_info.get()); } @@ -40,22 +36,19 @@ TaskScheduler::TaskScheduler(const Instance& instance, RendererVulkan& renderer) vk::DescriptorPoolSize{vk::DescriptorType::eSampledImage, 2048}, vk::DescriptorPoolSize{vk::DescriptorType::eCombinedImageSampler, 512}, vk::DescriptorPoolSize{vk::DescriptorType::eSampler, 2048}, - vk::DescriptorPoolSize{vk::DescriptorType::eUniformTexelBuffer, 1024} - }; + vk::DescriptorPoolSize{vk::DescriptorType::eUniformTexelBuffer, 1024}}; const vk::DescriptorPoolCreateInfo descriptor_pool_info = { .maxSets = 2048, .poolSizeCount = static_cast(pool_sizes.size()), - .pPoolSizes = pool_sizes.data() - }; + .pPoolSizes = pool_sizes.data()}; persistent_descriptor_pool = device.createDescriptorPool(descriptor_pool_info); - const vk::CommandBufferAllocateInfo buffer_info = { - .commandPool = command_pool, - .level = vk::CommandBufferLevel::ePrimary, - .commandBufferCount = 2 * SCHEDULER_COMMAND_COUNT - }; + const vk::CommandBufferAllocateInfo buffer_info = {.commandPool = command_pool, + .level = vk::CommandBufferLevel::ePrimary, + .commandBufferCount = + 2 * SCHEDULER_COMMAND_COUNT}; const auto command_buffers = device.allocateCommandBuffers(buffer_info); for (std::size_t i = 0; i < commands.size(); i++) { @@ -70,8 +63,7 @@ TaskScheduler::TaskScheduler(const Instance& instance, RendererVulkan& renderer) } const vk::CommandBufferBeginInfo begin_info = { - .flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit - }; + .flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit}; // Begin first command auto& command = commands[current_command]; @@ -106,13 +98,11 @@ void TaskScheduler::Synchronize(u32 slot) { if (command.fence_counter > completed_counter) { if (instance.IsTimelineSemaphoreSupported()) { const vk::SemaphoreWaitInfo wait_info = { - .semaphoreCount = 1, - .pSemaphores = &timeline, - .pValues = &command.fence_counter - }; + .semaphoreCount = 1, .pSemaphores = &timeline, .pValues = &command.fence_counter}; if (device.waitSemaphores(wait_info, UINT64_MAX) != vk::Result::eSuccess) { - LOG_ERROR(Render_Vulkan, "Waiting for fence counter {} failed!", command.fence_counter); + LOG_ERROR(Render_Vulkan, "Waiting for fence counter {} failed!", + command.fence_counter); UNREACHABLE(); } @@ -161,8 +151,7 @@ void TaskScheduler::Submit(SubmitMode mode) { .waitSemaphoreValueCount = wait_semaphore_count, .pWaitSemaphoreValues = wait_values.data(), .signalSemaphoreValueCount = signal_semaphore_count, - .pSignalSemaphoreValues = signal_values.data() - }; + .pSignalSemaphoreValues = signal_values.data()}; const std::array wait_stage_masks = { vk::PipelineStageFlagBits::eAllCommands, @@ -187,7 +176,7 @@ void TaskScheduler::Submit(SubmitMode mode) { const u32 signal_semaphore_count = swapchain_sync ? 1u : 0u; const u32 wait_semaphore_count = swapchain_sync ? 1u : 0u; const vk::PipelineStageFlags wait_stage_masks = - vk::PipelineStageFlagBits::eColorAttachmentOutput; + vk::PipelineStageFlagBits::eColorAttachmentOutput; const vk::SubmitInfo submit_info = { .waitSemaphoreCount = wait_semaphore_count, @@ -228,8 +217,7 @@ vk::CommandBuffer TaskScheduler::GetUploadCommandBuffer() { auto& command = commands[current_command]; if (!command.use_upload_buffer) { const vk::CommandBufferBeginInfo begin_info = { - .flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit - }; + .flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit}; command.upload_command_buffer.begin(begin_info); command.use_upload_buffer = true; @@ -246,8 +234,7 @@ void TaskScheduler::SwitchSlot() { Synchronize(current_command); const vk::CommandBufferBeginInfo begin_info = { - .flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit - }; + .flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit}; // Begin the next command buffer. command.render_command_buffer.begin(begin_info); @@ -255,4 +242,4 @@ void TaskScheduler::SwitchSlot() { command.use_upload_buffer = false; } -} // namespace Vulkan +} // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_task_scheduler.h b/src/video_core/renderer_vulkan/vk_task_scheduler.h index 1cf0923e7..53cbe97fc 100644 --- a/src/video_core/renderer_vulkan/vk_task_scheduler.h +++ b/src/video_core/renderer_vulkan/vk_task_scheduler.h @@ -4,11 +4,11 @@ #pragma once -#include #include #include -#include "common/common_types.h" +#include #include "common/common_funcs.h" +#include "common/common_types.h" #include "video_core/renderer_vulkan/vk_common.h" namespace Vulkan { @@ -19,7 +19,7 @@ class RendererVulkan; enum class SubmitMode : u8 { SwapchainSynced = 1 << 0, ///< Synchronizes command buffer execution with the swapchain - Flush = 1 << 1, ///< Causes a GPU command flush, useful for texture downloads + Flush = 1 << 1, ///< Causes a GPU command flush, useful for texture downloads Shutdown = 1 << 2 ///< Submits all current commands without starting a new command buffer }; @@ -102,4 +102,4 @@ private: u32 current_command = 0; }; -} // namespace Vulkan +} // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp index d389d32d6..06305e7f4 100644 --- a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp @@ -39,15 +39,17 @@ TextureRuntime::TextureRuntime(const Instance& instance, TaskScheduler& schedule for (auto& buffer : staging_buffers) { buffer = std::make_unique(instance, STAGING_BUFFER_SIZE, vk::BufferUsageFlagBits::eTransferSrc | - vk::BufferUsageFlagBits::eTransferDst); + vk::BufferUsageFlagBits::eTransferDst); } - auto Register = [this](VideoCore::PixelFormat dest, std::unique_ptr&& obj) { + auto Register = [this](VideoCore::PixelFormat dest, + std::unique_ptr&& obj) { const u32 dst_index = static_cast(dest); return reinterpreters[dst_index].push_back(std::move(obj)); }; - Register(VideoCore::PixelFormat::RGBA8, std::make_unique(instance, scheduler, *this)); + Register(VideoCore::PixelFormat::RGBA8, + std::make_unique(instance, scheduler, *this)); } TextureRuntime::~TextureRuntime() { @@ -81,12 +83,10 @@ StagingData TextureRuntime::FindStaging(u32 size, bool upload) { } const auto& buffer = staging_buffers[current_slot]; - return StagingData{ - .buffer = buffer->buffer, - .size = size, - .mapped = buffer->mapped.subspan(offset, size), - .buffer_offset = offset - }; + return StagingData{.buffer = buffer->buffer, + .size = size, + .mapped = buffer->mapped.subspan(offset, size), + .buffer_offset = offset}; } void TextureRuntime::Finish() { @@ -102,11 +102,7 @@ ImageAlloc TextureRuntime::Allocate(u32 width, u32 height, VideoCore::PixelForma const u32 layers = type == VideoCore::TextureType::CubeMap ? 6 : 1; const VideoCore::HostTextureTag key = { - .format = format, - .width = width, - .height = height, - .layers = layers - }; + .format = format, .width = width, .height = height, .layers = layers}; // Attempt to recycle an unused allocation if (auto it = texture_recycler.find(key); it != texture_recycler.end()) { @@ -123,22 +119,18 @@ ImageAlloc TextureRuntime::Allocate(u32 width, u32 height, VideoCore::PixelForma const vk::ImageUsageFlags vk_usage = is_suitable ? traits.usage : GetImageUsage(aspect); const u32 levels = std::bit_width(std::max(width, height)); - const vk::ImageCreateInfo image_info = { - .flags = type == VideoCore::TextureType::CubeMap ? - vk::ImageCreateFlagBits::eCubeCompatible : - vk::ImageCreateFlags{}, - .imageType = vk::ImageType::e2D, - .format = vk_format, - .extent = {width, height, 1}, - .mipLevels = levels, - .arrayLayers = layers, - .samples = vk::SampleCountFlagBits::e1, - .usage = vk_usage - }; + const vk::ImageCreateInfo image_info = {.flags = type == VideoCore::TextureType::CubeMap + ? vk::ImageCreateFlagBits::eCubeCompatible + : vk::ImageCreateFlags{}, + .imageType = vk::ImageType::e2D, + .format = vk_format, + .extent = {width, height, 1}, + .mipLevels = levels, + .arrayLayers = layers, + .samples = vk::SampleCountFlagBits::e1, + .usage = vk_usage}; - const VmaAllocationCreateInfo alloc_info = { - .usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE - }; + const VmaAllocationCreateInfo alloc_info = {.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE}; VkImage unsafe_image{}; VkImageCreateInfo unsafe_image_info = static_cast(image_info); @@ -152,36 +144,28 @@ ImageAlloc TextureRuntime::Allocate(u32 width, u32 height, VideoCore::PixelForma } vk::Image image = vk::Image{unsafe_image}; - const vk::ImageViewCreateInfo view_info = { - .image = image, - .viewType = type == VideoCore::TextureType::CubeMap ? - vk::ImageViewType::eCube : - vk::ImageViewType::e2D, - .format = vk_format, - .subresourceRange = { - .aspectMask = aspect, - .baseMipLevel = 0, - .levelCount = levels, - .baseArrayLayer = 0, - .layerCount = layers - } - }; + const vk::ImageViewCreateInfo view_info = {.image = image, + .viewType = type == VideoCore::TextureType::CubeMap + ? vk::ImageViewType::eCube + : vk::ImageViewType::e2D, + .format = vk_format, + .subresourceRange = {.aspectMask = aspect, + .baseMipLevel = 0, + .levelCount = levels, + .baseArrayLayer = 0, + .layerCount = layers}}; // Also create a base mip view in case this is used as an attachment const vk::ImageViewCreateInfo base_view_info = { .image = image, - .viewType = type == VideoCore::TextureType::CubeMap ? - vk::ImageViewType::eCube : - vk::ImageViewType::e2D, + .viewType = type == VideoCore::TextureType::CubeMap ? vk::ImageViewType::eCube + : vk::ImageViewType::e2D, .format = vk_format, - .subresourceRange = { - .aspectMask = aspect, - .baseMipLevel = 0, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = layers - } - }; + .subresourceRange = {.aspectMask = aspect, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = layers}}; vk::Device device = instance.GetDevice(); vk::ImageView image_view = device.createImageView(view_info); @@ -193,44 +177,38 @@ ImageAlloc TextureRuntime::Allocate(u32 width, u32 height, VideoCore::PixelForma if (format == VideoCore::PixelFormat::D24S8) { vk::ImageViewCreateInfo view_info = { .image = image, - .viewType = type == VideoCore::TextureType::CubeMap ? - vk::ImageViewType::eCube : - vk::ImageViewType::e2D, + .viewType = type == VideoCore::TextureType::CubeMap ? vk::ImageViewType::eCube + : vk::ImageViewType::e2D, .format = vk_format, - .subresourceRange = { - .aspectMask = vk::ImageAspectFlagBits::eDepth, - .baseMipLevel = 0, - .levelCount = levels, - .baseArrayLayer = 0, - .layerCount = layers - } - }; + .subresourceRange = {.aspectMask = vk::ImageAspectFlagBits::eDepth, + .baseMipLevel = 0, + .levelCount = levels, + .baseArrayLayer = 0, + .layerCount = layers}}; depth_view = device.createImageView(view_info); view_info.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eStencil; stencil_view = device.createImageView(view_info); } - return ImageAlloc{ - .image = image, - .image_view = image_view, - .base_view = base_view, - .depth_view = depth_view, - .stencil_view = stencil_view, - .allocation = allocation, - .format = vk_format, - .aspect = aspect, - .levels = levels, - .layers = layers - }; + return ImageAlloc{.image = image, + .image_view = image_view, + .base_view = base_view, + .depth_view = depth_view, + .stencil_view = stencil_view, + .allocation = allocation, + .format = vk_format, + .aspect = aspect, + .levels = levels, + .layers = layers}; } void TextureRuntime::Recycle(const VideoCore::HostTextureTag tag, ImageAlloc&& alloc) { texture_recycler.emplace(tag, std::move(alloc)); } -void TextureRuntime::FormatConvert(const Surface& surface, bool upload, - std::span source, std::span dest) { +void TextureRuntime::FormatConvert(const Surface& surface, bool upload, std::span source, + std::span dest) { if (!surface.NeedsConvert()) { std::memcpy(dest.data(), source.data(), source.size()); return; @@ -267,7 +245,8 @@ void TextureRuntime::FormatConvert(const Surface& surface, bool upload, } LOG_WARNING(Render_Vulkan, "Missing format convertion: {} {} {}", - vk::to_string(surface.traits.native), upload ? "->" : "<-", vk::to_string(surface.alloc.format)); + vk::to_string(surface.traits.native), upload ? "->" : "<-", + vk::to_string(surface.alloc.format)); } bool TextureRuntime::ClearTexture(Surface& surface, const VideoCore::TextureClear& clear, @@ -276,36 +255,37 @@ bool TextureRuntime::ClearTexture(Surface& surface, const VideoCore::TextureClea renderpass_cache.ExitRenderpass(); vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); - Transition(command_buffer, surface.alloc, vk::ImageLayout::eTransferDstOptimal, - 0, surface.alloc.levels, 0, surface.texture_type == VideoCore::TextureType::CubeMap ? 6 : 1); + Transition(command_buffer, surface.alloc, vk::ImageLayout::eTransferDstOptimal, 0, + surface.alloc.levels, 0, + surface.texture_type == VideoCore::TextureType::CubeMap ? 6 : 1); vk::ClearValue clear_value{}; if (aspect & vk::ImageAspectFlagBits::eColor) { clear_value.color = vk::ClearColorValue{ - .float32 = std::to_array({value.color[0], value.color[1], value.color[2], value.color[3]}) - }; - } else if (aspect & vk::ImageAspectFlagBits::eDepth || aspect & vk::ImageAspectFlagBits::eStencil) { - clear_value.depthStencil = vk::ClearDepthStencilValue{ - .depth = value.depth, - .stencil = value.stencil - }; + .float32 = + std::to_array({value.color[0], value.color[1], value.color[2], value.color[3]})}; + } else if (aspect & vk::ImageAspectFlagBits::eDepth || + aspect & vk::ImageAspectFlagBits::eStencil) { + clear_value.depthStencil = + vk::ClearDepthStencilValue{.depth = value.depth, .stencil = value.stencil}; } // For full clears we can use vkCmdClearColorImage/vkCmdClearDepthStencilImage if (clear.texture_rect == surface.GetScaledRect()) { - const vk::ImageSubresourceRange range = { - .aspectMask = aspect, - .baseMipLevel = clear.texture_level, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = 1 - }; + const vk::ImageSubresourceRange range = {.aspectMask = aspect, + .baseMipLevel = clear.texture_level, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1}; if (aspect & vk::ImageAspectFlagBits::eColor) { - command_buffer.clearColorImage(surface.alloc.image, vk::ImageLayout::eTransferDstOptimal, - clear_value.color, range); - } else if (aspect & vk::ImageAspectFlagBits::eDepth || aspect & vk::ImageAspectFlagBits::eStencil) { - command_buffer.clearDepthStencilImage(surface.alloc.image, vk::ImageLayout::eTransferDstOptimal, + command_buffer.clearColorImage(surface.alloc.image, + vk::ImageLayout::eTransferDstOptimal, clear_value.color, + range); + } else if (aspect & vk::ImageAspectFlagBits::eDepth || + aspect & vk::ImageAspectFlagBits::eStencil) { + command_buffer.clearDepthStencilImage(surface.alloc.image, + vk::ImageLayout::eTransferDstOptimal, clear_value.depthStencil, range); } } else { @@ -313,26 +293,28 @@ bool TextureRuntime::ClearTexture(Surface& surface, const VideoCore::TextureClea vk::RenderPass clear_renderpass{}; ImageAlloc& alloc = surface.alloc; if (aspect & vk::ImageAspectFlagBits::eColor) { - clear_renderpass = renderpass_cache.GetRenderpass(surface.pixel_format, - VideoCore::PixelFormat::Invalid, true); - Transition(command_buffer, alloc, vk::ImageLayout::eColorAttachmentOptimal, 0, alloc.levels); - } else if (aspect & vk::ImageAspectFlagBits::eDepth || aspect & vk::ImageAspectFlagBits::eStencil) { + clear_renderpass = renderpass_cache.GetRenderpass( + surface.pixel_format, VideoCore::PixelFormat::Invalid, true); + Transition(command_buffer, alloc, vk::ImageLayout::eColorAttachmentOptimal, 0, + alloc.levels); + } else if (aspect & vk::ImageAspectFlagBits::eDepth || + aspect & vk::ImageAspectFlagBits::eStencil) { clear_renderpass = renderpass_cache.GetRenderpass(VideoCore::PixelFormat::Invalid, surface.pixel_format, true); - Transition(command_buffer, alloc, vk::ImageLayout::eDepthStencilAttachmentOptimal, 0, alloc.levels); + Transition(command_buffer, alloc, vk::ImageLayout::eDepthStencilAttachmentOptimal, 0, + alloc.levels); } - auto [it, new_framebuffer] = clear_framebuffers.try_emplace(alloc.image_view, vk::Framebuffer{}); - if (new_framebuffer) {\ + auto [it, new_framebuffer] = + clear_framebuffers.try_emplace(alloc.image_view, vk::Framebuffer{}); + if (new_framebuffer) { const vk::ImageView framebuffer_view = surface.GetFramebufferView(); - const vk::FramebufferCreateInfo framebuffer_info = { - .renderPass = clear_renderpass, - .attachmentCount = 1, - .pAttachments = &framebuffer_view, - .width = surface.GetScaledWidth(), - .height = surface.GetScaledHeight(), - .layers = 1 - }; + const vk::FramebufferCreateInfo framebuffer_info = {.renderPass = clear_renderpass, + .attachmentCount = 1, + .pAttachments = &framebuffer_view, + .width = surface.GetScaledWidth(), + .height = surface.GetScaledHeight(), + .layers = 1}; vk::Device device = instance.GetDevice(); it->second = device.createFramebuffer(framebuffer_info); @@ -341,13 +323,12 @@ bool TextureRuntime::ClearTexture(Surface& surface, const VideoCore::TextureClea const vk::RenderPassBeginInfo clear_begin_info = { .renderPass = clear_renderpass, .framebuffer = it->second, - .renderArea = vk::Rect2D{ - .offset = {static_cast(clear.texture_rect.left), static_cast(clear.texture_rect.bottom)}, - .extent = {clear.texture_rect.GetWidth(), clear.texture_rect.GetHeight()} - }, + .renderArea = vk::Rect2D{.offset = {static_cast(clear.texture_rect.left), + static_cast(clear.texture_rect.bottom)}, + .extent = {clear.texture_rect.GetWidth(), + clear.texture_rect.GetHeight()}}, .clearValueCount = 1, - .pClearValues = &clear_value - }; + .pClearValues = &clear_value}; renderpass_cache.EnterRenderpass(clear_begin_info); renderpass_cache.ExitRenderpass(); @@ -356,30 +337,28 @@ bool TextureRuntime::ClearTexture(Surface& surface, const VideoCore::TextureClea return true; } -bool TextureRuntime::CopyTextures(Surface& source, Surface& dest, const VideoCore::TextureCopy& copy) { +bool TextureRuntime::CopyTextures(Surface& source, Surface& dest, + const VideoCore::TextureCopy& copy) { renderpass_cache.ExitRenderpass(); const vk::ImageCopy image_copy = { - .srcSubresource = { - .aspectMask = ToVkAspect(source.type), - .mipLevel = copy.src_level, - .baseArrayLayer = 0, - .layerCount = 1 - }, + .srcSubresource = {.aspectMask = ToVkAspect(source.type), + .mipLevel = copy.src_level, + .baseArrayLayer = 0, + .layerCount = 1}, .srcOffset = {static_cast(copy.src_offset.x), static_cast(copy.src_offset.y), 0}, - .dstSubresource = { - .aspectMask = ToVkAspect(dest.type), - .mipLevel = copy.dst_level, - .baseArrayLayer = 0, - .layerCount = 1 - }, + .dstSubresource = {.aspectMask = ToVkAspect(dest.type), + .mipLevel = copy.dst_level, + .baseArrayLayer = 0, + .layerCount = 1}, .dstOffset = {static_cast(copy.dst_offset.x), static_cast(copy.dst_offset.y), 0}, - .extent = {copy.extent.width, copy.extent.height, 1} - }; + .extent = {copy.extent.width, copy.extent.height, 1}}; vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); - Transition(command_buffer, source.alloc, vk::ImageLayout::eTransferSrcOptimal, 0, source.alloc.levels); - Transition(command_buffer, dest.alloc, vk::ImageLayout::eTransferDstOptimal, 0, dest.alloc.levels); + Transition(command_buffer, source.alloc, vk::ImageLayout::eTransferSrcOptimal, 0, + source.alloc.levels); + Transition(command_buffer, dest.alloc, vk::ImageLayout::eTransferDstOptimal, 0, + dest.alloc.levels); command_buffer.copyImage(source.alloc.image, vk::ImageLayout::eTransferSrcOptimal, dest.alloc.image, vk::ImageLayout::eTransferDstOptimal, image_copy); @@ -387,45 +366,41 @@ bool TextureRuntime::CopyTextures(Surface& source, Surface& dest, const VideoCor return true; } -bool TextureRuntime::BlitTextures(Surface& source, Surface& dest, const VideoCore::TextureBlit& blit) { +bool TextureRuntime::BlitTextures(Surface& source, Surface& dest, + const VideoCore::TextureBlit& blit) { renderpass_cache.ExitRenderpass(); vk::CommandBuffer command_buffer = scheduler.GetRenderCommandBuffer(); - Transition(command_buffer, source.alloc, vk::ImageLayout::eTransferSrcOptimal, - 0, source.alloc.levels, 0, source.texture_type == VideoCore::TextureType::CubeMap ? 6 : 1); - Transition(command_buffer, dest.alloc, vk::ImageLayout::eTransferDstOptimal, - 0, dest.alloc.levels, 0, dest.texture_type == VideoCore::TextureType::CubeMap ? 6 : 1); + Transition(command_buffer, source.alloc, vk::ImageLayout::eTransferSrcOptimal, 0, + source.alloc.levels, 0, + source.texture_type == VideoCore::TextureType::CubeMap ? 6 : 1); + Transition(command_buffer, dest.alloc, vk::ImageLayout::eTransferDstOptimal, 0, + dest.alloc.levels, 0, dest.texture_type == VideoCore::TextureType::CubeMap ? 6 : 1); - const std::array source_offsets = { - vk::Offset3D{static_cast(blit.src_rect.left), static_cast(blit.src_rect.bottom), 0}, - vk::Offset3D{static_cast(blit.src_rect.right), static_cast(blit.src_rect.top), 1} - }; + const std::array source_offsets = {vk::Offset3D{static_cast(blit.src_rect.left), + static_cast(blit.src_rect.bottom), 0}, + vk::Offset3D{static_cast(blit.src_rect.right), + static_cast(blit.src_rect.top), 1}}; - const std::array dest_offsets = { - vk::Offset3D{static_cast(blit.dst_rect.left), static_cast(blit.dst_rect.bottom), 0}, - vk::Offset3D{static_cast(blit.dst_rect.right), static_cast(blit.dst_rect.top), 1} - }; + const std::array dest_offsets = {vk::Offset3D{static_cast(blit.dst_rect.left), + static_cast(blit.dst_rect.bottom), 0}, + vk::Offset3D{static_cast(blit.dst_rect.right), + static_cast(blit.dst_rect.top), 1}}; - const vk::ImageBlit blit_area = { - .srcSubresource = { - .aspectMask = ToVkAspect(source.type), - .mipLevel = blit.src_level, - .baseArrayLayer = blit.src_layer, - .layerCount = 1 - }, - .srcOffsets = source_offsets, - .dstSubresource = { - .aspectMask = ToVkAspect(dest.type), - .mipLevel = blit.dst_level, - .baseArrayLayer = blit.dst_layer, - .layerCount = 1 - }, - .dstOffsets = dest_offsets - }; + const vk::ImageBlit blit_area = {.srcSubresource = {.aspectMask = ToVkAspect(source.type), + .mipLevel = blit.src_level, + .baseArrayLayer = blit.src_layer, + .layerCount = 1}, + .srcOffsets = source_offsets, + .dstSubresource = {.aspectMask = ToVkAspect(dest.type), + .mipLevel = blit.dst_level, + .baseArrayLayer = blit.dst_layer, + .layerCount = 1}, + .dstOffsets = dest_offsets}; command_buffer.blitImage(source.alloc.image, vk::ImageLayout::eTransferSrcOptimal, - dest.alloc.image, vk::ImageLayout::eTransferDstOptimal, - blit_area, vk::Filter::eNearest); + dest.alloc.image, vk::ImageLayout::eTransferDstOptimal, blit_area, + vk::Filter::eNearest); return true; } @@ -444,33 +419,23 @@ void TextureRuntime::GenerateMipmaps(Surface& surface, u32 max_level) { Transition(command_buffer, surface.alloc, vk::ImageLayout::eTransferSrcOptimal, i - 1, 1); Transition(command_buffer, surface.alloc, vk::ImageLayout::eTransferDstOptimal, i, 1); - const std::array source_offsets = { - vk::Offset3D{0, 0, 0}, - vk::Offset3D{current_width, current_height, 1} - }; + const std::array source_offsets = {vk::Offset3D{0, 0, 0}, + vk::Offset3D{current_width, current_height, 1}}; const std::array dest_offsets = { - vk::Offset3D{0, 0, 0}, - vk::Offset3D{current_width > 1 ? current_width / 2 : 1, - current_height > 1 ? current_height / 2 : 1, 1} - }; + vk::Offset3D{0, 0, 0}, vk::Offset3D{current_width > 1 ? current_width / 2 : 1, + current_height > 1 ? current_height / 2 : 1, 1}}; - const vk::ImageBlit blit_area = { - .srcSubresource = { - .aspectMask = aspect, - .mipLevel = i - 1, - .baseArrayLayer = 0, - .layerCount = 1 - }, - .srcOffsets = source_offsets, - .dstSubresource = { - .aspectMask = aspect, - .mipLevel = i, - .baseArrayLayer = 0, - .layerCount = 1 - }, - .dstOffsets = dest_offsets - }; + const vk::ImageBlit blit_area = {.srcSubresource = {.aspectMask = aspect, + .mipLevel = i - 1, + .baseArrayLayer = 0, + .layerCount = 1}, + .srcOffsets = source_offsets, + .dstSubresource = {.aspectMask = aspect, + .mipLevel = i, + .baseArrayLayer = 0, + .layerCount = 1}, + .dstOffsets = dest_offsets}; command_buffer.blitImage(surface.alloc.image, vk::ImageLayout::eTransferSrcOptimal, surface.alloc.image, vk::ImageLayout::eTransferDstOptimal, @@ -478,13 +443,14 @@ void TextureRuntime::GenerateMipmaps(Surface& surface, u32 max_level) { } } -const ReinterpreterList& TextureRuntime::GetPossibleReinterpretations(VideoCore::PixelFormat dest_format) const { +const ReinterpreterList& TextureRuntime::GetPossibleReinterpretations( + VideoCore::PixelFormat dest_format) const { return reinterpreters[static_cast(dest_format)]; } void TextureRuntime::Transition(vk::CommandBuffer command_buffer, ImageAlloc& alloc, - vk::ImageLayout new_layout, u32 level, u32 level_count, - u32 layer, u32 layer_count) { + vk::ImageLayout new_layout, u32 level, u32 level_count, u32 layer, + u32 layer_count) { if (new_layout == alloc.layout || !alloc.image) { return; } @@ -511,15 +477,16 @@ void TextureRuntime::Transition(vk::CommandBuffer command_buffer, ImageAlloc& al case vk::ImageLayout::eColorAttachmentOptimal: // Image was being used as a color attachment, so ensure all writes have completed. info.access = vk::AccessFlagBits::eColorAttachmentRead | - vk::AccessFlagBits::eColorAttachmentWrite; + vk::AccessFlagBits::eColorAttachmentWrite; info.stage = vk::PipelineStageFlagBits::eColorAttachmentOutput; break; case vk::ImageLayout::eDepthStencilAttachmentOptimal: - // Image was being used as a depthstencil attachment, so ensure all writes have completed. + // Image was being used as a depthstencil attachment, so ensure all writes have + // completed. info.access = vk::AccessFlagBits::eDepthStencilAttachmentRead | - vk::AccessFlagBits::eDepthStencilAttachmentWrite; + vk::AccessFlagBits::eDepthStencilAttachmentWrite; info.stage = vk::PipelineStageFlagBits::eEarlyFragmentTests | - vk::PipelineStageFlagBits::eLateFragmentTests; + vk::PipelineStageFlagBits::eLateFragmentTests; break; case vk::ImageLayout::ePresentSrcKHR: info.access = vk::AccessFlagBits::eNone; @@ -543,8 +510,8 @@ void TextureRuntime::Transition(vk::CommandBuffer command_buffer, ImageAlloc& al case vk::ImageLayout::eGeneral: info.access = vk::AccessFlagBits::eInputAttachmentRead; info.stage = vk::PipelineStageFlagBits::eColorAttachmentOutput | - vk::PipelineStageFlagBits::eFragmentShader | - vk::PipelineStageFlagBits::eComputeShader; + vk::PipelineStageFlagBits::eFragmentShader | + vk::PipelineStageFlagBits::eComputeShader; break; case vk::ImageLayout::eDepthStencilReadOnlyOptimal: // Image is going to be sampled from a compute shader @@ -568,18 +535,14 @@ void TextureRuntime::Transition(vk::CommandBuffer command_buffer, ImageAlloc& al .oldLayout = alloc.layout, .newLayout = new_layout, .image = alloc.image, - .subresourceRange = { - .aspectMask = alloc.aspect, - .baseMipLevel = /*level*/0, - .levelCount = /*level_count*/alloc.levels, - .baseArrayLayer = layer, - .layerCount = layer_count - } - }; + .subresourceRange = {.aspectMask = alloc.aspect, + .baseMipLevel = /*level*/ 0, + .levelCount = /*level_count*/ alloc.levels, + .baseArrayLayer = layer, + .layerCount = layer_count}}; - command_buffer.pipelineBarrier(source.stage, dest.stage, - vk::DependencyFlagBits::eByRegion, - {}, {}, barrier); + command_buffer.pipelineBarrier(source.stage, dest.stage, vk::DependencyFlagBits::eByRegion, {}, + {}, barrier); alloc.layout = new_layout; } @@ -589,7 +552,8 @@ Surface::Surface(VideoCore::SurfaceParams& params, TextureRuntime& runtime) scheduler{runtime.GetScheduler()}, traits{instance.GetTraits(pixel_format)} { if (pixel_format != VideoCore::PixelFormat::Invalid) { - alloc = runtime.Allocate(GetScaledWidth(), GetScaledHeight(), params.pixel_format, texture_type); + alloc = runtime.Allocate(GetScaledWidth(), GetScaledHeight(), params.pixel_format, + texture_type); } } @@ -599,8 +563,7 @@ Surface::~Surface() { .format = pixel_format, .width = GetScaledWidth(), .height = GetScaledHeight(), - .layers = texture_type == VideoCore::TextureType::CubeMap ? 6u : 1u - }; + .layers = texture_type == VideoCore::TextureType::CubeMap ? 6u : 1u}; runtime.Recycle(tag, std::move(alloc)); } @@ -622,21 +585,18 @@ void Surface::Upload(const VideoCore::BufferTextureCopy& upload, const StagingDa .bufferOffset = staging.buffer_offset, .bufferRowLength = rect.GetWidth(), .bufferImageHeight = rect.GetHeight(), - .imageSubresource = { - .aspectMask = alloc.aspect, - .mipLevel = upload.texture_level, - .baseArrayLayer = 0, - .layerCount = 1 - }, + .imageSubresource = {.aspectMask = alloc.aspect, + .mipLevel = upload.texture_level, + .baseArrayLayer = 0, + .layerCount = 1}, .imageOffset = {static_cast(rect.left), static_cast(rect.bottom), 0}, - .imageExtent = {rect.GetWidth(), rect.GetHeight(), 1} - }; + .imageExtent = {rect.GetWidth(), rect.GetHeight(), 1}}; - runtime.Transition(command_buffer, alloc, vk::ImageLayout::eTransferDstOptimal, 0, alloc.levels, - 0, texture_type == VideoCore::TextureType::CubeMap ? 6 : 1); + runtime.Transition(command_buffer, alloc, vk::ImageLayout::eTransferDstOptimal, 0, + alloc.levels, 0, + texture_type == VideoCore::TextureType::CubeMap ? 6 : 1); command_buffer.copyBufferToImage(staging.buffer, alloc.image, - vk::ImageLayout::eTransferDstOptimal, - copy_region); + vk::ImageLayout::eTransferDstOptimal, copy_region); } InvalidateAllWatcher(); @@ -665,15 +625,12 @@ void Surface::Download(const VideoCore::BufferTextureCopy& download, const Stagi .bufferOffset = staging.buffer_offset + download.buffer_offset, .bufferRowLength = rect.GetWidth(), .bufferImageHeight = rect.GetHeight(), - .imageSubresource = { - .aspectMask = alloc.aspect, - .mipLevel = download.texture_level, - .baseArrayLayer = 0, - .layerCount = 1 - }, + .imageSubresource = {.aspectMask = alloc.aspect, + .mipLevel = download.texture_level, + .baseArrayLayer = 0, + .layerCount = 1}, .imageOffset = {static_cast(rect.left), static_cast(rect.bottom), 0}, - .imageExtent = {rect.GetWidth(), rect.GetHeight(), 1} - }; + .imageExtent = {rect.GetWidth(), rect.GetHeight(), 1}}; if (alloc.aspect & vk::ImageAspectFlagBits::eColor) { copy_regions[region_count++] = copy_region; @@ -688,7 +645,8 @@ void Surface::Download(const VideoCore::BufferTextureCopy& download, const Stagi } } - runtime.Transition(command_buffer, alloc, vk::ImageLayout::eTransferSrcOptimal, 0, alloc.levels); + runtime.Transition(command_buffer, alloc, vk::ImageLayout::eTransferSrcOptimal, 0, + alloc.levels); // Copy pixel data to the staging buffer command_buffer.copyImageToBuffer(alloc.image, vk::ImageLayout::eTransferSrcOptimal, @@ -703,9 +661,8 @@ void Surface::Download(const VideoCore::BufferTextureCopy& download, const Stagi bool Surface::NeedsConvert() const { // RGBA8 needs a byteswap since R8G8B8A8UnormPack32 does not exist // D24S8 always needs an interleave pass even if natively supported - return alloc.format != traits.native || - pixel_format == VideoCore::PixelFormat::RGBA8 || - pixel_format == VideoCore::PixelFormat::D24S8; + return alloc.format != traits.native || pixel_format == VideoCore::PixelFormat::RGBA8 || + pixel_format == VideoCore::PixelFormat::D24S8; } u32 Surface::GetInternalBytesPerPixel() const { @@ -720,7 +677,8 @@ void Surface::ScaledDownload(const VideoCore::BufferTextureCopy& download) { const ImageAlloc unscaled_tex = runtime.Allocate(rect_width, rect_height, pixel_format, VideoCore::TextureType::Texture2D); runtime.BindFramebuffer(GL_DRAW_FRAMEBUFFER, 0, GL_TEXTURE_2D, type, unscaled_tex); - runtime.BindFramebuffer(GL_READ_FRAMEBUFFER, download.texture_level, GL_TEXTURE_2D, type, texture); + runtime.BindFramebuffer(GL_READ_FRAMEBUFFER, download.texture_level, GL_TEXTURE_2D, type, + texture); // Blit the scaled rectangle to the unscaled texture const VideoCore::Rect2D scaled_rect = download.texture_rect * res_scale; @@ -759,7 +717,8 @@ void Surface::ScaledUpload(const VideoCore::BufferTextureCopy& upload) { const auto& filterer = runtime.GetFilterer(); if (!filterer.Filter(unscaled_tex, unscaled_rect, texture, scaled_rect, type)) { runtime.BindFramebuffer(GL_READ_FRAMEBUFFER, 0, GL_TEXTURE_2D, type, unscaled_tex); - runtime.BindFramebuffer(GL_DRAW_FRAMEBUFFER, upload.texture_level, GL_TEXTURE_2D, type, texture); + runtime.BindFramebuffer(GL_DRAW_FRAMEBUFFER, upload.texture_level, GL_TEXTURE_2D, type, + texture); // If filtering fails, resort to normal blitting glBlitFramebuffer(0, 0, rect_width, rect_height, diff --git a/src/video_core/renderer_vulkan/vk_texture_runtime.h b/src/video_core/renderer_vulkan/vk_texture_runtime.h index 6a2df4f99..6e6976178 100644 --- a/src/video_core/renderer_vulkan/vk_texture_runtime.h +++ b/src/video_core/renderer_vulkan/vk_texture_runtime.h @@ -3,14 +3,14 @@ // Refer to the license.txt file included. #pragma once -#include #include +#include #include #include "video_core/rasterizer_cache/rasterizer_cache.h" #include "video_core/rasterizer_cache/surface_base.h" -#include "video_core/renderer_vulkan/vk_stream_buffer.h" #include "video_core/renderer_vulkan/vk_format_reinterpreter.h" #include "video_core/renderer_vulkan/vk_instance.h" +#include "video_core/renderer_vulkan/vk_stream_buffer.h" #include "video_core/renderer_vulkan/vk_task_scheduler.h" namespace Vulkan { @@ -47,6 +47,7 @@ class Surface; */ class TextureRuntime { friend class Surface; + public: TextureRuntime(const Instance& instance, TaskScheduler& scheduler, RenderpassCache& renderpass_cache); @@ -66,13 +67,12 @@ public: void Recycle(const VideoCore::HostTextureTag tag, ImageAlloc&& alloc); /// Performs required format convertions on the staging data - void FormatConvert(const Surface& surface, bool upload, - std::span source, std::span dest); + void FormatConvert(const Surface& surface, bool upload, std::span source, + std::span dest); /// Transitions the mip level range of the surface to new_layout - void Transition(vk::CommandBuffer command_buffer, ImageAlloc& alloc, - vk::ImageLayout new_layout, u32 level, u32 level_count, - u32 layer = 0, u32 layer_count = 1); + void Transition(vk::CommandBuffer command_buffer, ImageAlloc& alloc, vk::ImageLayout new_layout, + u32 level, u32 level_count, u32 layer = 0, u32 layer_count = 1); /// Fills the rectangle of the texture with the clear value provided bool ClearTexture(Surface& surface, const VideoCore::TextureClear& clear, @@ -89,7 +89,7 @@ public: /// Returns all source formats that support reinterpretation to the dest format [[nodiscard]] const ReinterpreterList& GetPossibleReinterpretations( - VideoCore::PixelFormat dest_format) const; + VideoCore::PixelFormat dest_format) const; /// Performs operations that need to be done on every scheduler slot switch void OnSlotSwitch(u32 new_slot); @@ -120,6 +120,7 @@ private: class Surface : public VideoCore::SurfaceBase { friend class TextureRuntime; friend class RasterizerVulkan; + public: Surface(VideoCore::SurfaceParams& params, TextureRuntime& runtime); ~Surface() override; diff --git a/src/video_core/shader/shader_cache.h b/src/video_core/shader/shader_cache.h index 4cf03da3c..64ee38e26 100644 --- a/src/video_core/shader/shader_cache.h +++ b/src/video_core/shader/shader_cache.h @@ -5,8 +5,8 @@ #pragma once #include -#include #include +#include #include "video_core/shader/shader.h" namespace Pica::Shader { @@ -15,7 +15,7 @@ template using ShaderCacheResult = std::pair>; template + std::string (*CodeGenerator)(const KeyType&)> class ShaderCache { public: ShaderCache() {} @@ -52,14 +52,16 @@ public: * different config values from the same shader program. */ template (*CodeGenerator)(const Pica::Shader::ShaderSetup&, const KeyType&)> + std::optional (*CodeGenerator)(const Pica::Shader::ShaderSetup&, + const KeyType&)> class ShaderDoubleCache { public: ShaderDoubleCache() = default; ~ShaderDoubleCache() = default; template - auto Get(const KeyType& key, const Pica::Shader::ShaderSetup& setup, Args&&... args) -> ShaderCacheResult { + auto Get(const KeyType& key, const Pica::Shader::ShaderSetup& setup, Args&&... args) + -> ShaderCacheResult { if (auto map_iter = shader_map.find(key); map_iter == shader_map.end()) { auto code = CodeGenerator(setup, key); if (!code) { diff --git a/src/video_core/shader/shader_uniforms.cpp b/src/video_core/shader/shader_uniforms.cpp index ec8336ca4..37414ec5c 100644 --- a/src/video_core/shader/shader_uniforms.cpp +++ b/src/video_core/shader/shader_uniforms.cpp @@ -8,7 +8,8 @@ namespace Pica::Shader { -void PicaUniformsData::SetFromRegs(const Pica::ShaderRegs& regs, const Pica::Shader::ShaderSetup& setup) { +void PicaUniformsData::SetFromRegs(const Pica::ShaderRegs& regs, + const Pica::Shader::ShaderSetup& setup) { std::transform(std::begin(setup.uniforms.b), std::end(setup.uniforms.b), std::begin(bools), [](bool value) -> BoolAligned { return {value ? 1 : 0}; }); std::transform(std::begin(regs.int_uniforms), std::end(regs.int_uniforms), std::begin(i), diff --git a/src/video_core/shader/shader_uniforms.h b/src/video_core/shader/shader_uniforms.h index 679f6d50e..553d5c579 100644 --- a/src/video_core/shader/shader_uniforms.h +++ b/src/video_core/shader/shader_uniforms.h @@ -95,5 +95,4 @@ static_assert(sizeof(VSUniformData) == 1856, static_assert(sizeof(VSUniformData) < 16384, "VSUniformData structure must be less than 16kb as per the OpenGL spec"); - } // namespace Pica::Shader diff --git a/src/video_core/texture/texture_decode.h b/src/video_core/texture/texture_decode.h index c3967435d..4fb79d47f 100644 --- a/src/video_core/texture/texture_decode.h +++ b/src/video_core/texture/texture_decode.h @@ -71,7 +71,6 @@ void ConvertBGRToRGB(std::span source, std::span des */ void ConvertBGRToRGBA(std::span source, std::span dest); - /** * Converts pixel data encoded in ABGR format to RGBA * diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h index 16a1decf0..ff4c5b198 100644 --- a/src/video_core/video_core.h +++ b/src/video_core/video_core.h @@ -47,11 +47,7 @@ extern Layout::FramebufferLayout g_screenshot_framebuffer_layout; extern Memory::MemorySystem* g_memory; -enum class ResultStatus { - Success, - ErrorRendererInit, - ErrorGenericDrivers -}; +enum class ResultStatus { Success, ErrorRendererInit, ErrorGenericDrivers }; /// Initialize the video core ResultStatus Init(Frontend::EmuWindow& emu_window, Memory::MemorySystem& memory); diff --git a/src/web_service/verify_user_jwt.cpp b/src/web_service/verify_user_jwt.cpp index 47c648f72..27e08db9e 100644 --- a/src/web_service/verify_user_jwt.cpp +++ b/src/web_service/verify_user_jwt.cpp @@ -3,8 +3,8 @@ // Refer to the license.txt file included. #include -#include "common/logging/log.h" #include +#include "common/logging/log.h" #include "common/web_result.h" #include "web_service/verify_user_jwt.h" #include "web_service/web_backend.h"