diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/core_timing.cpp | 10 | ||||
| -rw-r--r-- | src/core/core_timing.h | 1 | ||||
| -rw-r--r-- | src/core/file_sys/card_image.cpp | 7 | ||||
| -rw-r--r-- | src/core/hle/kernel/server_session.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/server_session.h | 7 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/sm/controller.cpp | 4 | ||||
| -rw-r--r-- | src/core/loader/loader.cpp | 12 | ||||
| -rw-r--r-- | src/core/loader/loader.h | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 44 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 159 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 101 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/maxwell_to_gl.h | 25 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 5 | ||||
| -rw-r--r-- | src/yuzu_cmd/yuzu.cpp | 4 |
16 files changed, 265 insertions, 128 deletions
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index f977d1b32..7953c8720 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp | |||
| @@ -56,6 +56,9 @@ static u64 event_fifo_id; | |||
| 56 | // to the event_queue by the emu thread | 56 | // to the event_queue by the emu thread |
| 57 | static Common::MPSCQueue<Event, false> ts_queue; | 57 | static Common::MPSCQueue<Event, false> ts_queue; |
| 58 | 58 | ||
| 59 | // the queue for unscheduling the events from other threads threadsafe | ||
| 60 | static Common::MPSCQueue<std::pair<const EventType*, u64>, false> unschedule_queue; | ||
| 61 | |||
| 59 | constexpr int MAX_SLICE_LENGTH = 20000; | 62 | constexpr int MAX_SLICE_LENGTH = 20000; |
| 60 | 63 | ||
| 61 | static s64 idled_cycles; | 64 | static s64 idled_cycles; |
| @@ -158,6 +161,10 @@ void UnscheduleEvent(const EventType* event_type, u64 userdata) { | |||
| 158 | } | 161 | } |
| 159 | } | 162 | } |
| 160 | 163 | ||
| 164 | void UnscheduleEventThreadsafe(const EventType* event_type, u64 userdata) { | ||
| 165 | unschedule_queue.Push(std::make_pair(event_type, userdata)); | ||
| 166 | } | ||
| 167 | |||
| 161 | void RemoveEvent(const EventType* event_type) { | 168 | void RemoveEvent(const EventType* event_type) { |
| 162 | auto itr = std::remove_if(event_queue.begin(), event_queue.end(), | 169 | auto itr = std::remove_if(event_queue.begin(), event_queue.end(), |
| 163 | [&](const Event& e) { return e.type == event_type; }); | 170 | [&](const Event& e) { return e.type == event_type; }); |
| @@ -194,6 +201,9 @@ void MoveEvents() { | |||
| 194 | 201 | ||
| 195 | void Advance() { | 202 | void Advance() { |
| 196 | MoveEvents(); | 203 | MoveEvents(); |
| 204 | for (std::pair<const EventType*, u64> ev; unschedule_queue.Pop(ev);) { | ||
| 205 | UnscheduleEvent(ev.first, ev.second); | ||
| 206 | } | ||
| 197 | 207 | ||
| 198 | int cycles_executed = slice_length - downcount; | 208 | int cycles_executed = slice_length - downcount; |
| 199 | global_timer += cycles_executed; | 209 | global_timer += cycles_executed; |
diff --git a/src/core/core_timing.h b/src/core/core_timing.h index dfa161c0d..9ed757bd7 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h | |||
| @@ -65,6 +65,7 @@ void ScheduleEvent(s64 cycles_into_future, const EventType* event_type, u64 user | |||
| 65 | void ScheduleEventThreadsafe(s64 cycles_into_future, const EventType* event_type, u64 userdata); | 65 | void ScheduleEventThreadsafe(s64 cycles_into_future, const EventType* event_type, u64 userdata); |
| 66 | 66 | ||
| 67 | void UnscheduleEvent(const EventType* event_type, u64 userdata); | 67 | void UnscheduleEvent(const EventType* event_type, u64 userdata); |
| 68 | void UnscheduleEventThreadsafe(const EventType* event_type, u64 userdata); | ||
| 68 | 69 | ||
| 69 | /// We only permit one event of each type in the queue at a time. | 70 | /// We only permit one event of each type in the queue at a time. |
| 70 | void RemoveEvent(const EventType* event_type); | 71 | void RemoveEvent(const EventType* event_type); |
diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp index 8e05b9d0e..060948f9e 100644 --- a/src/core/file_sys/card_image.cpp +++ b/src/core/file_sys/card_image.cpp | |||
| @@ -4,11 +4,14 @@ | |||
| 4 | 4 | ||
| 5 | #include <array> | 5 | #include <array> |
| 6 | #include <string> | 6 | #include <string> |
| 7 | #include <core/loader/loader.h> | 7 | |
| 8 | #include <fmt/ostream.h> | ||
| 9 | |||
| 8 | #include "common/logging/log.h" | 10 | #include "common/logging/log.h" |
| 9 | #include "core/file_sys/card_image.h" | 11 | #include "core/file_sys/card_image.h" |
| 10 | #include "core/file_sys/partition_filesystem.h" | 12 | #include "core/file_sys/partition_filesystem.h" |
| 11 | #include "core/file_sys/vfs_offset.h" | 13 | #include "core/file_sys/vfs_offset.h" |
| 14 | #include "core/loader/loader.h" | ||
| 12 | 15 | ||
| 13 | namespace FileSys { | 16 | namespace FileSys { |
| 14 | 17 | ||
| @@ -142,7 +145,7 @@ Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) { | |||
| 142 | const u16 error_id = static_cast<u16>(nca->GetStatus()); | 145 | const u16 error_id = static_cast<u16>(nca->GetStatus()); |
| 143 | LOG_CRITICAL(Loader, "Could not load NCA {}/{}, failed with error code {:04X} ({})", | 146 | LOG_CRITICAL(Loader, "Could not load NCA {}/{}, failed with error code {:04X} ({})", |
| 144 | partition_names[static_cast<size_t>(part)], nca->GetName(), error_id, | 147 | partition_names[static_cast<size_t>(part)], nca->GetName(), error_id, |
| 145 | Loader::GetMessageForResultStatus(nca->GetStatus())); | 148 | nca->GetStatus()); |
| 146 | } | 149 | } |
| 147 | } | 150 | } |
| 148 | 151 | ||
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index d09ca5992..51a1ec160 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp | |||
| @@ -152,7 +152,7 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) { | |||
| 152 | // Handle scenario when ConvertToDomain command was issued, as we must do the conversion at the | 152 | // Handle scenario when ConvertToDomain command was issued, as we must do the conversion at the |
| 153 | // end of the command such that only commands following this one are handled as domains | 153 | // end of the command such that only commands following this one are handled as domains |
| 154 | if (convert_to_domain) { | 154 | if (convert_to_domain) { |
| 155 | ASSERT_MSG(domain_request_handlers.empty(), "already a domain"); | 155 | ASSERT_MSG(IsSession(), "ServerSession is already a domain instance."); |
| 156 | domain_request_handlers = {hle_handler}; | 156 | domain_request_handlers = {hle_handler}; |
| 157 | convert_to_domain = false; | 157 | convert_to_domain = false; |
| 158 | } | 158 | } |
diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 2bce54fee..1a88e66b9 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h | |||
| @@ -97,7 +97,12 @@ public: | |||
| 97 | 97 | ||
| 98 | /// Returns true if the session has been converted to a domain, otherwise False | 98 | /// Returns true if the session has been converted to a domain, otherwise False |
| 99 | bool IsDomain() const { | 99 | bool IsDomain() const { |
| 100 | return !domain_request_handlers.empty(); | 100 | return !IsSession(); |
| 101 | } | ||
| 102 | |||
| 103 | /// Returns true if this session has not been converted to a domain, otherwise false. | ||
| 104 | bool IsSession() const { | ||
| 105 | return domain_request_handlers.empty(); | ||
| 101 | } | 106 | } |
| 102 | 107 | ||
| 103 | /// Converts the session to a domain at the end of the current command | 108 | /// Converts the session to a domain at the end of the current command |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index a1a7867ce..cf4f94822 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -167,7 +167,7 @@ void Thread::WakeAfterDelay(s64 nanoseconds) { | |||
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | void Thread::CancelWakeupTimer() { | 169 | void Thread::CancelWakeupTimer() { |
| 170 | CoreTiming::UnscheduleEvent(ThreadWakeupEventType, callback_handle); | 170 | CoreTiming::UnscheduleEventThreadsafe(ThreadWakeupEventType, callback_handle); |
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | static boost::optional<s32> GetNextProcessorId(u64 mask) { | 173 | static boost::optional<s32> GetNextProcessorId(u64 mask) { |
diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/controller.cpp index 518a0cc46..1cef73216 100644 --- a/src/core/hle/service/sm/controller.cpp +++ b/src/core/hle/service/sm/controller.cpp | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | namespace Service::SM { | 10 | namespace Service::SM { |
| 11 | 11 | ||
| 12 | void Controller::ConvertSessionToDomain(Kernel::HLERequestContext& ctx) { | 12 | void Controller::ConvertSessionToDomain(Kernel::HLERequestContext& ctx) { |
| 13 | ASSERT_MSG(!ctx.Session()->IsDomain(), "session is alread a domain"); | 13 | ASSERT_MSG(ctx.Session()->IsSession(), "Session is already a domain"); |
| 14 | ctx.Session()->ConvertToDomain(); | 14 | ctx.Session()->ConvertToDomain(); |
| 15 | 15 | ||
| 16 | IPC::ResponseBuilder rb{ctx, 3}; | 16 | IPC::ResponseBuilder rb{ctx, 3}; |
| @@ -41,7 +41,7 @@ void Controller::DuplicateSessionEx(Kernel::HLERequestContext& ctx) { | |||
| 41 | void Controller::QueryPointerBufferSize(Kernel::HLERequestContext& ctx) { | 41 | void Controller::QueryPointerBufferSize(Kernel::HLERequestContext& ctx) { |
| 42 | IPC::ResponseBuilder rb{ctx, 3}; | 42 | IPC::ResponseBuilder rb{ctx, 3}; |
| 43 | rb.Push(RESULT_SUCCESS); | 43 | rb.Push(RESULT_SUCCESS); |
| 44 | rb.Push<u32>(0x500); | 44 | rb.Push<u16>(0x500); |
| 45 | 45 | ||
| 46 | LOG_WARNING(Service, "(STUBBED) called"); | 46 | LOG_WARNING(Service, "(STUBBED) called"); |
| 47 | } | 47 | } |
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index b143f043c..5e07a3f10 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <memory> | 5 | #include <memory> |
| 6 | #include <ostream> | ||
| 6 | #include <string> | 7 | #include <string> |
| 7 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 8 | #include "common/string_util.h" | 9 | #include "common/string_util.h" |
| @@ -119,14 +120,9 @@ constexpr std::array<const char*, 36> RESULT_MESSAGES{ | |||
| 119 | "There is no control data available.", | 120 | "There is no control data available.", |
| 120 | }; | 121 | }; |
| 121 | 122 | ||
| 122 | std::string GetMessageForResultStatus(ResultStatus status) { | 123 | std::ostream& operator<<(std::ostream& os, ResultStatus status) { |
| 123 | return GetMessageForResultStatus(static_cast<u16>(status)); | 124 | os << RESULT_MESSAGES.at(static_cast<size_t>(status)); |
| 124 | } | 125 | return os; |
| 125 | |||
| 126 | std::string GetMessageForResultStatus(u16 status) { | ||
| 127 | if (status >= 36) | ||
| 128 | return ""; | ||
| 129 | return RESULT_MESSAGES[status]; | ||
| 130 | } | 126 | } |
| 131 | 127 | ||
| 132 | /** | 128 | /** |
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index 6dffe451a..b74cfbf8a 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <algorithm> | 7 | #include <algorithm> |
| 8 | #include <iosfwd> | ||
| 8 | #include <memory> | 9 | #include <memory> |
| 9 | #include <string> | 10 | #include <string> |
| 10 | #include <utility> | 11 | #include <utility> |
| @@ -94,8 +95,7 @@ enum class ResultStatus : u16 { | |||
| 94 | ErrorNoControl, | 95 | ErrorNoControl, |
| 95 | }; | 96 | }; |
| 96 | 97 | ||
| 97 | std::string GetMessageForResultStatus(ResultStatus status); | 98 | std::ostream& operator<<(std::ostream& os, ResultStatus status); |
| 98 | std::string GetMessageForResultStatus(u16 status); | ||
| 99 | 99 | ||
| 100 | /// Interface for loading an application | 100 | /// Interface for loading an application |
| 101 | class AppLoader : NonCopyable { | 101 | class AppLoader : NonCopyable { |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 52a649e2f..9d1549fe9 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -648,11 +648,11 @@ std::tuple<u8*, GLintptr, u32> RasterizerOpenGL::SetupConstBuffers( | |||
| 648 | 648 | ||
| 649 | if (used_buffer.IsIndirect()) { | 649 | if (used_buffer.IsIndirect()) { |
| 650 | // Buffer is accessed indirectly, so upload the entire thing | 650 | // Buffer is accessed indirectly, so upload the entire thing |
| 651 | size = buffer.size * sizeof(float); | 651 | size = buffer.size; |
| 652 | 652 | ||
| 653 | if (size > MaxConstbufferSize) { | 653 | if (size > MaxConstbufferSize) { |
| 654 | LOG_ERROR(HW_GPU, "indirect constbuffer size {} exceeds maximum {}", size, | 654 | LOG_CRITICAL(HW_GPU, "indirect constbuffer size {} exceeds maximum {}", size, |
| 655 | MaxConstbufferSize); | 655 | MaxConstbufferSize); |
| 656 | size = MaxConstbufferSize; | 656 | size = MaxConstbufferSize; |
| 657 | } | 657 | } |
| 658 | } else { | 658 | } else { |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 5d58ebd4f..b6947b97b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -94,11 +94,11 @@ struct FormatTuple { | |||
| 94 | static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ | 94 | static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ |
| 95 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // ABGR8U | 95 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // ABGR8U |
| 96 | {GL_RGBA8, GL_RGBA, GL_BYTE, ComponentType::SNorm, false}, // ABGR8S | 96 | {GL_RGBA8, GL_RGBA, GL_BYTE, ComponentType::SNorm, false}, // ABGR8S |
| 97 | {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, ComponentType::UNorm, false}, // B5G6R5 | 97 | {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, ComponentType::UNorm, false}, // B5G6R5U |
| 98 | {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, ComponentType::UNorm, | 98 | {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, ComponentType::UNorm, |
| 99 | false}, // A2B10G10R10 | 99 | false}, // A2B10G10R10U |
| 100 | {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, ComponentType::UNorm, false}, // A1B5G5R5 | 100 | {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, ComponentType::UNorm, false}, // A1B5G5R5U |
| 101 | {GL_R8, GL_RED, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // R8 | 101 | {GL_R8, GL_RED, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // R8U |
| 102 | {GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, ComponentType::UInt, false}, // R8UI | 102 | {GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, ComponentType::UInt, false}, // R8UI |
| 103 | {GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, ComponentType::Float, false}, // RGBA16F | 103 | {GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, ComponentType::Float, false}, // RGBA16F |
| 104 | {GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, ComponentType::UNorm, false}, // RGBA16U | 104 | {GL_RGBA16, GL_RGBA, GL_UNSIGNED_SHORT, ComponentType::UNorm, false}, // RGBA16U |
| @@ -119,13 +119,14 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form | |||
| 119 | {GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, | 119 | {GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm, |
| 120 | true}, // BC7U | 120 | true}, // BC7U |
| 121 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_4X4 | 121 | {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // ASTC_2D_4X4 |
| 122 | {GL_RG8, GL_RG, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // G8R8 | 122 | {GL_RG8, GL_RG, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // G8R8U |
| 123 | {GL_RG8, GL_RG, GL_BYTE, ComponentType::SNorm, false}, // G8R8S | ||
| 123 | {GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // BGRA8 | 124 | {GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // BGRA8 |
| 124 | {GL_RGBA32F, GL_RGBA, GL_FLOAT, ComponentType::Float, false}, // RGBA32F | 125 | {GL_RGBA32F, GL_RGBA, GL_FLOAT, ComponentType::Float, false}, // RGBA32F |
| 125 | {GL_RG32F, GL_RG, GL_FLOAT, ComponentType::Float, false}, // RG32F | 126 | {GL_RG32F, GL_RG, GL_FLOAT, ComponentType::Float, false}, // RG32F |
| 126 | {GL_R32F, GL_RED, GL_FLOAT, ComponentType::Float, false}, // R32F | 127 | {GL_R32F, GL_RED, GL_FLOAT, ComponentType::Float, false}, // R32F |
| 127 | {GL_R16F, GL_RED, GL_HALF_FLOAT, ComponentType::Float, false}, // R16F | 128 | {GL_R16F, GL_RED, GL_HALF_FLOAT, ComponentType::Float, false}, // R16F |
| 128 | {GL_R16, GL_RED, GL_UNSIGNED_SHORT, ComponentType::UNorm, false}, // R16UNORM | 129 | {GL_R16, GL_RED, GL_UNSIGNED_SHORT, ComponentType::UNorm, false}, // R16U |
| 129 | {GL_R16_SNORM, GL_RED, GL_SHORT, ComponentType::SNorm, false}, // R16S | 130 | {GL_R16_SNORM, GL_RED, GL_SHORT, ComponentType::SNorm, false}, // R16S |
| 130 | {GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // R16UI | 131 | {GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // R16UI |
| 131 | {GL_R16I, GL_RED_INTEGER, GL_SHORT, ComponentType::SInt, false}, // R16I | 132 | {GL_R16I, GL_RED_INTEGER, GL_SHORT, ComponentType::SInt, false}, // R16I |
| @@ -242,10 +243,10 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU | |||
| 242 | // clang-format off | 243 | // clang-format off |
| 243 | MortonCopy<true, PixelFormat::ABGR8U>, | 244 | MortonCopy<true, PixelFormat::ABGR8U>, |
| 244 | MortonCopy<true, PixelFormat::ABGR8S>, | 245 | MortonCopy<true, PixelFormat::ABGR8S>, |
| 245 | MortonCopy<true, PixelFormat::B5G6R5>, | 246 | MortonCopy<true, PixelFormat::B5G6R5U>, |
| 246 | MortonCopy<true, PixelFormat::A2B10G10R10>, | 247 | MortonCopy<true, PixelFormat::A2B10G10R10U>, |
| 247 | MortonCopy<true, PixelFormat::A1B5G5R5>, | 248 | MortonCopy<true, PixelFormat::A1B5G5R5U>, |
| 248 | MortonCopy<true, PixelFormat::R8>, | 249 | MortonCopy<true, PixelFormat::R8U>, |
| 249 | MortonCopy<true, PixelFormat::R8UI>, | 250 | MortonCopy<true, PixelFormat::R8UI>, |
| 250 | MortonCopy<true, PixelFormat::RGBA16F>, | 251 | MortonCopy<true, PixelFormat::RGBA16F>, |
| 251 | MortonCopy<true, PixelFormat::RGBA16U>, | 252 | MortonCopy<true, PixelFormat::RGBA16U>, |
| @@ -260,13 +261,14 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU | |||
| 260 | MortonCopy<true, PixelFormat::DXN2SNORM>, | 261 | MortonCopy<true, PixelFormat::DXN2SNORM>, |
| 261 | MortonCopy<true, PixelFormat::BC7U>, | 262 | MortonCopy<true, PixelFormat::BC7U>, |
| 262 | MortonCopy<true, PixelFormat::ASTC_2D_4X4>, | 263 | MortonCopy<true, PixelFormat::ASTC_2D_4X4>, |
| 263 | MortonCopy<true, PixelFormat::G8R8>, | 264 | MortonCopy<true, PixelFormat::G8R8U>, |
| 265 | MortonCopy<true, PixelFormat::G8R8S>, | ||
| 264 | MortonCopy<true, PixelFormat::BGRA8>, | 266 | MortonCopy<true, PixelFormat::BGRA8>, |
| 265 | MortonCopy<true, PixelFormat::RGBA32F>, | 267 | MortonCopy<true, PixelFormat::RGBA32F>, |
| 266 | MortonCopy<true, PixelFormat::RG32F>, | 268 | MortonCopy<true, PixelFormat::RG32F>, |
| 267 | MortonCopy<true, PixelFormat::R32F>, | 269 | MortonCopy<true, PixelFormat::R32F>, |
| 268 | MortonCopy<true, PixelFormat::R16F>, | 270 | MortonCopy<true, PixelFormat::R16F>, |
| 269 | MortonCopy<true, PixelFormat::R16UNORM>, | 271 | MortonCopy<true, PixelFormat::R16U>, |
| 270 | MortonCopy<true, PixelFormat::R16S>, | 272 | MortonCopy<true, PixelFormat::R16S>, |
| 271 | MortonCopy<true, PixelFormat::R16UI>, | 273 | MortonCopy<true, PixelFormat::R16UI>, |
| 272 | MortonCopy<true, PixelFormat::R16I>, | 274 | MortonCopy<true, PixelFormat::R16I>, |
| @@ -295,10 +297,10 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU | |||
| 295 | // clang-format off | 297 | // clang-format off |
| 296 | MortonCopy<false, PixelFormat::ABGR8U>, | 298 | MortonCopy<false, PixelFormat::ABGR8U>, |
| 297 | MortonCopy<false, PixelFormat::ABGR8S>, | 299 | MortonCopy<false, PixelFormat::ABGR8S>, |
| 298 | MortonCopy<false, PixelFormat::B5G6R5>, | 300 | MortonCopy<false, PixelFormat::B5G6R5U>, |
| 299 | MortonCopy<false, PixelFormat::A2B10G10R10>, | 301 | MortonCopy<false, PixelFormat::A2B10G10R10U>, |
| 300 | MortonCopy<false, PixelFormat::A1B5G5R5>, | 302 | MortonCopy<false, PixelFormat::A1B5G5R5U>, |
| 301 | MortonCopy<false, PixelFormat::R8>, | 303 | MortonCopy<false, PixelFormat::R8U>, |
| 302 | MortonCopy<false, PixelFormat::R8UI>, | 304 | MortonCopy<false, PixelFormat::R8UI>, |
| 303 | MortonCopy<false, PixelFormat::RGBA16F>, | 305 | MortonCopy<false, PixelFormat::RGBA16F>, |
| 304 | MortonCopy<false, PixelFormat::RGBA16U>, | 306 | MortonCopy<false, PixelFormat::RGBA16U>, |
| @@ -315,13 +317,14 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU | |||
| 315 | nullptr, | 317 | nullptr, |
| 316 | nullptr, | 318 | nullptr, |
| 317 | nullptr, | 319 | nullptr, |
| 318 | MortonCopy<false, PixelFormat::G8R8>, | 320 | MortonCopy<false, PixelFormat::G8R8U>, |
| 321 | MortonCopy<false, PixelFormat::G8R8S>, | ||
| 319 | MortonCopy<false, PixelFormat::BGRA8>, | 322 | MortonCopy<false, PixelFormat::BGRA8>, |
| 320 | MortonCopy<false, PixelFormat::RGBA32F>, | 323 | MortonCopy<false, PixelFormat::RGBA32F>, |
| 321 | MortonCopy<false, PixelFormat::RG32F>, | 324 | MortonCopy<false, PixelFormat::RG32F>, |
| 322 | MortonCopy<false, PixelFormat::R32F>, | 325 | MortonCopy<false, PixelFormat::R32F>, |
| 323 | MortonCopy<false, PixelFormat::R16F>, | 326 | MortonCopy<false, PixelFormat::R16F>, |
| 324 | MortonCopy<false, PixelFormat::R16UNORM>, | 327 | MortonCopy<false, PixelFormat::R16U>, |
| 325 | MortonCopy<false, PixelFormat::R16S>, | 328 | MortonCopy<false, PixelFormat::R16S>, |
| 326 | MortonCopy<false, PixelFormat::R16UI>, | 329 | MortonCopy<false, PixelFormat::R16UI>, |
| 327 | MortonCopy<false, PixelFormat::R16I>, | 330 | MortonCopy<false, PixelFormat::R16I>, |
| @@ -461,7 +464,7 @@ static void ConvertS8Z24ToZ24S8(std::vector<u8>& data, u32 width, u32 height) { | |||
| 461 | } | 464 | } |
| 462 | 465 | ||
| 463 | static void ConvertG8R8ToR8G8(std::vector<u8>& data, u32 width, u32 height) { | 466 | static void ConvertG8R8ToR8G8(std::vector<u8>& data, u32 width, u32 height) { |
| 464 | const auto bpp{CachedSurface::GetGLBytesPerPixel(PixelFormat::G8R8)}; | 467 | const auto bpp{CachedSurface::GetGLBytesPerPixel(PixelFormat::G8R8U)}; |
| 465 | for (size_t y = 0; y < height; ++y) { | 468 | for (size_t y = 0; y < height; ++y) { |
| 466 | for (size_t x = 0; x < width; ++x) { | 469 | for (size_t x = 0; x < width; ++x) { |
| 467 | const size_t offset{bpp * (y * width + x)}; | 470 | const size_t offset{bpp * (y * width + x)}; |
| @@ -493,7 +496,8 @@ static void ConvertFormatAsNeeded_LoadGLBuffer(std::vector<u8>& data, PixelForma | |||
| 493 | ConvertS8Z24ToZ24S8(data, width, height); | 496 | ConvertS8Z24ToZ24S8(data, width, height); |
| 494 | break; | 497 | break; |
| 495 | 498 | ||
| 496 | case PixelFormat::G8R8: | 499 | case PixelFormat::G8R8U: |
| 500 | case PixelFormat::G8R8S: | ||
| 497 | // Convert the G8R8 color format to R8G8, as OpenGL does not support G8R8. | 501 | // Convert the G8R8 color format to R8G8, as OpenGL does not support G8R8. |
| 498 | ConvertG8R8ToR8G8(data, width, height); | 502 | ConvertG8R8ToR8G8(data, width, height); |
| 499 | break; | 503 | break; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 0de87d8c2..55cf3782c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -25,10 +25,10 @@ struct SurfaceParams { | |||
| 25 | enum class PixelFormat { | 25 | enum class PixelFormat { |
| 26 | ABGR8U = 0, | 26 | ABGR8U = 0, |
| 27 | ABGR8S = 1, | 27 | ABGR8S = 1, |
| 28 | B5G6R5 = 2, | 28 | B5G6R5U = 2, |
| 29 | A2B10G10R10 = 3, | 29 | A2B10G10R10U = 3, |
| 30 | A1B5G5R5 = 4, | 30 | A1B5G5R5U = 4, |
| 31 | R8 = 5, | 31 | R8U = 5, |
| 32 | R8UI = 6, | 32 | R8UI = 6, |
| 33 | RGBA16F = 7, | 33 | RGBA16F = 7, |
| 34 | RGBA16U = 8, | 34 | RGBA16U = 8, |
| @@ -43,36 +43,37 @@ struct SurfaceParams { | |||
| 43 | DXN2SNORM = 17, | 43 | DXN2SNORM = 17, |
| 44 | BC7U = 18, | 44 | BC7U = 18, |
| 45 | ASTC_2D_4X4 = 19, | 45 | ASTC_2D_4X4 = 19, |
| 46 | G8R8 = 20, | 46 | G8R8U = 20, |
| 47 | BGRA8 = 21, | 47 | G8R8S = 21, |
| 48 | RGBA32F = 22, | 48 | BGRA8 = 22, |
| 49 | RG32F = 23, | 49 | RGBA32F = 23, |
| 50 | R32F = 24, | 50 | RG32F = 24, |
| 51 | R16F = 25, | 51 | R32F = 25, |
| 52 | R16UNORM = 26, | 52 | R16F = 26, |
| 53 | R16S = 27, | 53 | R16U = 27, |
| 54 | R16UI = 28, | 54 | R16S = 28, |
| 55 | R16I = 29, | 55 | R16UI = 29, |
| 56 | RG16 = 30, | 56 | R16I = 30, |
| 57 | RG16F = 31, | 57 | RG16 = 31, |
| 58 | RG16UI = 32, | 58 | RG16F = 32, |
| 59 | RG16I = 33, | 59 | RG16UI = 33, |
| 60 | RG16S = 34, | 60 | RG16I = 34, |
| 61 | RGB32F = 35, | 61 | RG16S = 35, |
| 62 | SRGBA8 = 36, | 62 | RGB32F = 36, |
| 63 | RG8U = 37, | 63 | SRGBA8 = 37, |
| 64 | RG8S = 38, | 64 | RG8U = 38, |
| 65 | RG32UI = 39, | 65 | RG8S = 39, |
| 66 | R32UI = 40, | 66 | RG32UI = 40, |
| 67 | R32UI = 41, | ||
| 67 | 68 | ||
| 68 | MaxColorFormat, | 69 | MaxColorFormat, |
| 69 | 70 | ||
| 70 | // DepthStencil formats | 71 | // DepthStencil formats |
| 71 | Z24S8 = 41, | 72 | Z24S8 = 42, |
| 72 | S8Z24 = 42, | 73 | S8Z24 = 43, |
| 73 | Z32F = 43, | 74 | Z32F = 44, |
| 74 | Z16 = 44, | 75 | Z16 = 45, |
| 75 | Z32FS8 = 45, | 76 | Z32FS8 = 46, |
| 76 | 77 | ||
| 77 | MaxDepthStencilFormat, | 78 | MaxDepthStencilFormat, |
| 78 | 79 | ||
| @@ -112,10 +113,10 @@ struct SurfaceParams { | |||
| 112 | constexpr std::array<u32, MaxPixelFormat> compression_factor_table = {{ | 113 | constexpr std::array<u32, MaxPixelFormat> compression_factor_table = {{ |
| 113 | 1, // ABGR8U | 114 | 1, // ABGR8U |
| 114 | 1, // ABGR8S | 115 | 1, // ABGR8S |
| 115 | 1, // B5G6R5 | 116 | 1, // B5G6R5U |
| 116 | 1, // A2B10G10R10 | 117 | 1, // A2B10G10R10U |
| 117 | 1, // A1B5G5R5 | 118 | 1, // A1B5G5R5U |
| 118 | 1, // R8 | 119 | 1, // R8U |
| 119 | 1, // R8UI | 120 | 1, // R8UI |
| 120 | 1, // RGBA16F | 121 | 1, // RGBA16F |
| 121 | 1, // RGBA16U | 122 | 1, // RGBA16U |
| @@ -130,13 +131,14 @@ struct SurfaceParams { | |||
| 130 | 4, // DXN2SNORM | 131 | 4, // DXN2SNORM |
| 131 | 4, // BC7U | 132 | 4, // BC7U |
| 132 | 4, // ASTC_2D_4X4 | 133 | 4, // ASTC_2D_4X4 |
| 133 | 1, // G8R8 | 134 | 1, // G8R8U |
| 135 | 1, // G8R8S | ||
| 134 | 1, // BGRA8 | 136 | 1, // BGRA8 |
| 135 | 1, // RGBA32F | 137 | 1, // RGBA32F |
| 136 | 1, // RG32F | 138 | 1, // RG32F |
| 137 | 1, // R32F | 139 | 1, // R32F |
| 138 | 1, // R16F | 140 | 1, // R16F |
| 139 | 1, // R16UNORM | 141 | 1, // R16U |
| 140 | 1, // R16S | 142 | 1, // R16S |
| 141 | 1, // R16UI | 143 | 1, // R16UI |
| 142 | 1, // R16I | 144 | 1, // R16I |
| @@ -169,10 +171,10 @@ struct SurfaceParams { | |||
| 169 | constexpr std::array<u32, MaxPixelFormat> bpp_table = {{ | 171 | constexpr std::array<u32, MaxPixelFormat> bpp_table = {{ |
| 170 | 32, // ABGR8U | 172 | 32, // ABGR8U |
| 171 | 32, // ABGR8S | 173 | 32, // ABGR8S |
| 172 | 16, // B5G6R5 | 174 | 16, // B5G6R5U |
| 173 | 32, // A2B10G10R10 | 175 | 32, // A2B10G10R10U |
| 174 | 16, // A1B5G5R5 | 176 | 16, // A1B5G5R5U |
| 175 | 8, // R8 | 177 | 8, // R8U |
| 176 | 8, // R8UI | 178 | 8, // R8UI |
| 177 | 64, // RGBA16F | 179 | 64, // RGBA16F |
| 178 | 64, // RGBA16U | 180 | 64, // RGBA16U |
| @@ -187,13 +189,14 @@ struct SurfaceParams { | |||
| 187 | 128, // DXN2SNORM | 189 | 128, // DXN2SNORM |
| 188 | 128, // BC7U | 190 | 128, // BC7U |
| 189 | 32, // ASTC_2D_4X4 | 191 | 32, // ASTC_2D_4X4 |
| 190 | 16, // G8R8 | 192 | 16, // G8R8U |
| 193 | 16, // G8R8S | ||
| 191 | 32, // BGRA8 | 194 | 32, // BGRA8 |
| 192 | 128, // RGBA32F | 195 | 128, // RGBA32F |
| 193 | 64, // RG32F | 196 | 64, // RG32F |
| 194 | 32, // R32F | 197 | 32, // R32F |
| 195 | 16, // R16F | 198 | 16, // R16F |
| 196 | 16, // R16UNORM | 199 | 16, // R16U |
| 197 | 16, // R16S | 200 | 16, // R16S |
| 198 | 16, // R16UI | 201 | 16, // R16UI |
| 199 | 16, // R16I | 202 | 16, // R16I |
| @@ -253,7 +256,7 @@ struct SurfaceParams { | |||
| 253 | case Tegra::RenderTargetFormat::BGRA8_UNORM: | 256 | case Tegra::RenderTargetFormat::BGRA8_UNORM: |
| 254 | return PixelFormat::BGRA8; | 257 | return PixelFormat::BGRA8; |
| 255 | case Tegra::RenderTargetFormat::RGB10_A2_UNORM: | 258 | case Tegra::RenderTargetFormat::RGB10_A2_UNORM: |
| 256 | return PixelFormat::A2B10G10R10; | 259 | return PixelFormat::A2B10G10R10U; |
| 257 | case Tegra::RenderTargetFormat::RGBA16_FLOAT: | 260 | case Tegra::RenderTargetFormat::RGBA16_FLOAT: |
| 258 | return PixelFormat::RGBA16F; | 261 | return PixelFormat::RGBA16F; |
| 259 | case Tegra::RenderTargetFormat::RGBA16_UNORM: | 262 | case Tegra::RenderTargetFormat::RGBA16_UNORM: |
| @@ -267,11 +270,11 @@ struct SurfaceParams { | |||
| 267 | case Tegra::RenderTargetFormat::R11G11B10_FLOAT: | 270 | case Tegra::RenderTargetFormat::R11G11B10_FLOAT: |
| 268 | return PixelFormat::R11FG11FB10F; | 271 | return PixelFormat::R11FG11FB10F; |
| 269 | case Tegra::RenderTargetFormat::B5G6R5_UNORM: | 272 | case Tegra::RenderTargetFormat::B5G6R5_UNORM: |
| 270 | return PixelFormat::B5G6R5; | 273 | return PixelFormat::B5G6R5U; |
| 271 | case Tegra::RenderTargetFormat::RGBA32_UINT: | 274 | case Tegra::RenderTargetFormat::RGBA32_UINT: |
| 272 | return PixelFormat::RGBA32UI; | 275 | return PixelFormat::RGBA32UI; |
| 273 | case Tegra::RenderTargetFormat::R8_UNORM: | 276 | case Tegra::RenderTargetFormat::R8_UNORM: |
| 274 | return PixelFormat::R8; | 277 | return PixelFormat::R8U; |
| 275 | case Tegra::RenderTargetFormat::R8_UINT: | 278 | case Tegra::RenderTargetFormat::R8_UINT: |
| 276 | return PixelFormat::R8UI; | 279 | return PixelFormat::R8UI; |
| 277 | case Tegra::RenderTargetFormat::RG16_FLOAT: | 280 | case Tegra::RenderTargetFormat::RG16_FLOAT: |
| @@ -291,7 +294,7 @@ struct SurfaceParams { | |||
| 291 | case Tegra::RenderTargetFormat::R16_FLOAT: | 294 | case Tegra::RenderTargetFormat::R16_FLOAT: |
| 292 | return PixelFormat::R16F; | 295 | return PixelFormat::R16F; |
| 293 | case Tegra::RenderTargetFormat::R16_UNORM: | 296 | case Tegra::RenderTargetFormat::R16_UNORM: |
| 294 | return PixelFormat::R16UNORM; | 297 | return PixelFormat::R16U; |
| 295 | case Tegra::RenderTargetFormat::R16_SNORM: | 298 | case Tegra::RenderTargetFormat::R16_SNORM: |
| 296 | return PixelFormat::R16S; | 299 | return PixelFormat::R16S; |
| 297 | case Tegra::RenderTargetFormat::R16_UINT: | 300 | case Tegra::RenderTargetFormat::R16_UINT: |
| @@ -325,15 +328,33 @@ struct SurfaceParams { | |||
| 325 | static_cast<u32>(component_type)); | 328 | static_cast<u32>(component_type)); |
| 326 | UNREACHABLE(); | 329 | UNREACHABLE(); |
| 327 | case Tegra::Texture::TextureFormat::B5G6R5: | 330 | case Tegra::Texture::TextureFormat::B5G6R5: |
| 328 | return PixelFormat::B5G6R5; | 331 | switch (component_type) { |
| 332 | case Tegra::Texture::ComponentType::UNORM: | ||
| 333 | return PixelFormat::B5G6R5U; | ||
| 334 | } | ||
| 335 | LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", | ||
| 336 | static_cast<u32>(component_type)); | ||
| 337 | UNREACHABLE(); | ||
| 329 | case Tegra::Texture::TextureFormat::A2B10G10R10: | 338 | case Tegra::Texture::TextureFormat::A2B10G10R10: |
| 330 | return PixelFormat::A2B10G10R10; | 339 | switch (component_type) { |
| 340 | case Tegra::Texture::ComponentType::UNORM: | ||
| 341 | return PixelFormat::A2B10G10R10U; | ||
| 342 | } | ||
| 343 | LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", | ||
| 344 | static_cast<u32>(component_type)); | ||
| 345 | UNREACHABLE(); | ||
| 331 | case Tegra::Texture::TextureFormat::A1B5G5R5: | 346 | case Tegra::Texture::TextureFormat::A1B5G5R5: |
| 332 | return PixelFormat::A1B5G5R5; | 347 | switch (component_type) { |
| 348 | case Tegra::Texture::ComponentType::UNORM: | ||
| 349 | return PixelFormat::A1B5G5R5U; | ||
| 350 | } | ||
| 351 | LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", | ||
| 352 | static_cast<u32>(component_type)); | ||
| 353 | UNREACHABLE(); | ||
| 333 | case Tegra::Texture::TextureFormat::R8: | 354 | case Tegra::Texture::TextureFormat::R8: |
| 334 | switch (component_type) { | 355 | switch (component_type) { |
| 335 | case Tegra::Texture::ComponentType::UNORM: | 356 | case Tegra::Texture::ComponentType::UNORM: |
| 336 | return PixelFormat::R8; | 357 | return PixelFormat::R8U; |
| 337 | case Tegra::Texture::ComponentType::UINT: | 358 | case Tegra::Texture::ComponentType::UINT: |
| 338 | return PixelFormat::R8UI; | 359 | return PixelFormat::R8UI; |
| 339 | } | 360 | } |
| @@ -341,11 +362,33 @@ struct SurfaceParams { | |||
| 341 | static_cast<u32>(component_type)); | 362 | static_cast<u32>(component_type)); |
| 342 | UNREACHABLE(); | 363 | UNREACHABLE(); |
| 343 | case Tegra::Texture::TextureFormat::G8R8: | 364 | case Tegra::Texture::TextureFormat::G8R8: |
| 344 | return PixelFormat::G8R8; | 365 | switch (component_type) { |
| 366 | case Tegra::Texture::ComponentType::UNORM: | ||
| 367 | return PixelFormat::G8R8U; | ||
| 368 | case Tegra::Texture::ComponentType::SNORM: | ||
| 369 | return PixelFormat::G8R8S; | ||
| 370 | } | ||
| 371 | LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", | ||
| 372 | static_cast<u32>(component_type)); | ||
| 373 | UNREACHABLE(); | ||
| 345 | case Tegra::Texture::TextureFormat::R16_G16_B16_A16: | 374 | case Tegra::Texture::TextureFormat::R16_G16_B16_A16: |
| 346 | return PixelFormat::RGBA16F; | 375 | switch (component_type) { |
| 376 | case Tegra::Texture::ComponentType::UNORM: | ||
| 377 | return PixelFormat::RGBA16U; | ||
| 378 | case Tegra::Texture::ComponentType::FLOAT: | ||
| 379 | return PixelFormat::RGBA16F; | ||
| 380 | } | ||
| 381 | LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", | ||
| 382 | static_cast<u32>(component_type)); | ||
| 383 | UNREACHABLE(); | ||
| 347 | case Tegra::Texture::TextureFormat::BF10GF11RF11: | 384 | case Tegra::Texture::TextureFormat::BF10GF11RF11: |
| 348 | return PixelFormat::R11FG11FB10F; | 385 | switch (component_type) { |
| 386 | case Tegra::Texture::ComponentType::FLOAT: | ||
| 387 | return PixelFormat::R11FG11FB10F; | ||
| 388 | } | ||
| 389 | LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", | ||
| 390 | static_cast<u32>(component_type)); | ||
| 391 | UNREACHABLE(); | ||
| 349 | case Tegra::Texture::TextureFormat::R32_G32_B32_A32: | 392 | case Tegra::Texture::TextureFormat::R32_G32_B32_A32: |
| 350 | switch (component_type) { | 393 | switch (component_type) { |
| 351 | case Tegra::Texture::ComponentType::FLOAT: | 394 | case Tegra::Texture::ComponentType::FLOAT: |
| @@ -367,13 +410,19 @@ struct SurfaceParams { | |||
| 367 | static_cast<u32>(component_type)); | 410 | static_cast<u32>(component_type)); |
| 368 | UNREACHABLE(); | 411 | UNREACHABLE(); |
| 369 | case Tegra::Texture::TextureFormat::R32_G32_B32: | 412 | case Tegra::Texture::TextureFormat::R32_G32_B32: |
| 370 | return PixelFormat::RGB32F; | 413 | switch (component_type) { |
| 414 | case Tegra::Texture::ComponentType::FLOAT: | ||
| 415 | return PixelFormat::RGB32F; | ||
| 416 | } | ||
| 417 | LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", | ||
| 418 | static_cast<u32>(component_type)); | ||
| 419 | UNREACHABLE(); | ||
| 371 | case Tegra::Texture::TextureFormat::R16: | 420 | case Tegra::Texture::TextureFormat::R16: |
| 372 | switch (component_type) { | 421 | switch (component_type) { |
| 373 | case Tegra::Texture::ComponentType::FLOAT: | 422 | case Tegra::Texture::ComponentType::FLOAT: |
| 374 | return PixelFormat::R16F; | 423 | return PixelFormat::R16F; |
| 375 | case Tegra::Texture::ComponentType::UNORM: | 424 | case Tegra::Texture::ComponentType::UNORM: |
| 376 | return PixelFormat::R16UNORM; | 425 | return PixelFormat::R16U; |
| 377 | case Tegra::Texture::ComponentType::SNORM: | 426 | case Tegra::Texture::ComponentType::SNORM: |
| 378 | return PixelFormat::R16S; | 427 | return PixelFormat::R16S; |
| 379 | case Tegra::Texture::ComponentType::UINT: | 428 | case Tegra::Texture::ComponentType::UINT: |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 6834d7085..e0dfdbb9f 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -367,31 +367,32 @@ public: | |||
| 367 | } | 367 | } |
| 368 | 368 | ||
| 369 | /// Generates code representing a uniform (C buffer) register, interpreted as the input type. | 369 | /// Generates code representing a uniform (C buffer) register, interpreted as the input type. |
| 370 | std::string GetUniform(u64 index, u64 offset, GLSLRegister::Type type) { | 370 | std::string GetUniform(u64 index, u64 offset, GLSLRegister::Type type, |
| 371 | Register::Size size = Register::Size::Word) { | ||
| 371 | declr_const_buffers[index].MarkAsUsed(index, offset, stage); | 372 | declr_const_buffers[index].MarkAsUsed(index, offset, stage); |
| 372 | std::string value = 'c' + std::to_string(index) + '[' + std::to_string(offset / 4) + "][" + | 373 | std::string value = 'c' + std::to_string(index) + '[' + std::to_string(offset / 4) + "][" + |
| 373 | std::to_string(offset % 4) + ']'; | 374 | std::to_string(offset % 4) + ']'; |
| 374 | 375 | ||
| 375 | if (type == GLSLRegister::Type::Float) { | 376 | if (type == GLSLRegister::Type::Float) { |
| 376 | return value; | 377 | // Do nothing, default |
| 377 | } else if (type == GLSLRegister::Type::Integer) { | 378 | } else if (type == GLSLRegister::Type::Integer) { |
| 378 | return "floatBitsToInt(" + value + ')'; | 379 | value = "floatBitsToInt(" + value + ')'; |
| 379 | } else if (type == GLSLRegister::Type::UnsignedInteger) { | 380 | } else if (type == GLSLRegister::Type::UnsignedInteger) { |
| 380 | return "floatBitsToUint(" + value + ')'; | 381 | value = "floatBitsToUint(" + value + ')'; |
| 381 | } else { | 382 | } else { |
| 382 | UNREACHABLE(); | 383 | UNREACHABLE(); |
| 383 | } | 384 | } |
| 385 | |||
| 386 | return ConvertIntegerSize(value, size); | ||
| 384 | } | 387 | } |
| 385 | 388 | ||
| 386 | std::string GetUniformIndirect(u64 index, s64 offset, const Register& index_reg, | 389 | std::string GetUniformIndirect(u64 cbuf_index, s64 offset, const std::string& index_str, |
| 387 | GLSLRegister::Type type) { | 390 | GLSLRegister::Type type) { |
| 388 | declr_const_buffers[index].MarkAsUsedIndirect(index, stage); | 391 | declr_const_buffers[cbuf_index].MarkAsUsedIndirect(cbuf_index, stage); |
| 389 | |||
| 390 | std::string final_offset = "((floatBitsToInt(" + GetRegister(index_reg, 0) + ") + " + | ||
| 391 | std::to_string(offset) + ") / 4)"; | ||
| 392 | 392 | ||
| 393 | std::string value = | 393 | std::string final_offset = fmt::format("({} + {})", index_str, offset / 4); |
| 394 | 'c' + std::to_string(index) + '[' + final_offset + " / 4][" + final_offset + " % 4]"; | 394 | std::string value = 'c' + std::to_string(cbuf_index) + '[' + final_offset + " / 4][" + |
| 395 | final_offset + " % 4]"; | ||
| 395 | 396 | ||
| 396 | if (type == GLSLRegister::Type::Float) { | 397 | if (type == GLSLRegister::Type::Float) { |
| 397 | return value; | 398 | return value; |
| @@ -1249,20 +1250,41 @@ private: | |||
| 1249 | op_a = "abs(" + op_a + ')'; | 1250 | op_a = "abs(" + op_a + ')'; |
| 1250 | } | 1251 | } |
| 1251 | 1252 | ||
| 1253 | if (instr.conversion.negate_a) { | ||
| 1254 | op_a = "-(" + op_a + ')'; | ||
| 1255 | } | ||
| 1256 | |||
| 1252 | regs.SetRegisterToInteger(instr.gpr0, instr.conversion.is_output_signed, 0, op_a, 1, | 1257 | regs.SetRegisterToInteger(instr.gpr0, instr.conversion.is_output_signed, 0, op_a, 1, |
| 1253 | 1, instr.alu.saturate_d, 0, instr.conversion.dest_size); | 1258 | 1, instr.alu.saturate_d, 0, instr.conversion.dest_size); |
| 1254 | break; | 1259 | break; |
| 1255 | } | 1260 | } |
| 1256 | case OpCode::Id::I2F_R: { | 1261 | case OpCode::Id::I2F_R: |
| 1262 | case OpCode::Id::I2F_C: { | ||
| 1257 | ASSERT_MSG(instr.conversion.dest_size == Register::Size::Word, "Unimplemented"); | 1263 | ASSERT_MSG(instr.conversion.dest_size == Register::Size::Word, "Unimplemented"); |
| 1258 | ASSERT_MSG(!instr.conversion.selector, "Unimplemented"); | 1264 | ASSERT_MSG(!instr.conversion.selector, "Unimplemented"); |
| 1259 | std::string op_a = regs.GetRegisterAsInteger( | 1265 | |
| 1260 | instr.gpr20, 0, instr.conversion.is_input_signed, instr.conversion.src_size); | 1266 | std::string op_a{}; |
| 1267 | |||
| 1268 | if (instr.is_b_gpr) { | ||
| 1269 | op_a = | ||
| 1270 | regs.GetRegisterAsInteger(instr.gpr20, 0, instr.conversion.is_input_signed, | ||
| 1271 | instr.conversion.src_size); | ||
| 1272 | } else { | ||
| 1273 | op_a = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, | ||
| 1274 | instr.conversion.is_input_signed | ||
| 1275 | ? GLSLRegister::Type::Integer | ||
| 1276 | : GLSLRegister::Type::UnsignedInteger, | ||
| 1277 | instr.conversion.src_size); | ||
| 1278 | } | ||
| 1261 | 1279 | ||
| 1262 | if (instr.conversion.abs_a) { | 1280 | if (instr.conversion.abs_a) { |
| 1263 | op_a = "abs(" + op_a + ')'; | 1281 | op_a = "abs(" + op_a + ')'; |
| 1264 | } | 1282 | } |
| 1265 | 1283 | ||
| 1284 | if (instr.conversion.negate_a) { | ||
| 1285 | op_a = "-(" + op_a + ')'; | ||
| 1286 | } | ||
| 1287 | |||
| 1266 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); | 1288 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); |
| 1267 | break; | 1289 | break; |
| 1268 | } | 1290 | } |
| @@ -1271,6 +1293,14 @@ private: | |||
| 1271 | ASSERT_MSG(instr.conversion.src_size == Register::Size::Word, "Unimplemented"); | 1293 | ASSERT_MSG(instr.conversion.src_size == Register::Size::Word, "Unimplemented"); |
| 1272 | std::string op_a = regs.GetRegisterAsFloat(instr.gpr20); | 1294 | std::string op_a = regs.GetRegisterAsFloat(instr.gpr20); |
| 1273 | 1295 | ||
| 1296 | if (instr.conversion.abs_a) { | ||
| 1297 | op_a = "abs(" + op_a + ')'; | ||
| 1298 | } | ||
| 1299 | |||
| 1300 | if (instr.conversion.negate_a) { | ||
| 1301 | op_a = "-(" + op_a + ')'; | ||
| 1302 | } | ||
| 1303 | |||
| 1274 | switch (instr.conversion.f2f.rounding) { | 1304 | switch (instr.conversion.f2f.rounding) { |
| 1275 | case Tegra::Shader::F2fRoundingOp::None: | 1305 | case Tegra::Shader::F2fRoundingOp::None: |
| 1276 | break; | 1306 | break; |
| @@ -1293,21 +1323,29 @@ private: | |||
| 1293 | break; | 1323 | break; |
| 1294 | } | 1324 | } |
| 1295 | 1325 | ||
| 1296 | if (instr.conversion.abs_a) { | ||
| 1297 | op_a = "abs(" + op_a + ')'; | ||
| 1298 | } | ||
| 1299 | |||
| 1300 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1, instr.alu.saturate_d); | 1326 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1, instr.alu.saturate_d); |
| 1301 | break; | 1327 | break; |
| 1302 | } | 1328 | } |
| 1303 | case OpCode::Id::F2I_R: { | 1329 | case OpCode::Id::F2I_R: |
| 1330 | case OpCode::Id::F2I_C: { | ||
| 1304 | ASSERT_MSG(instr.conversion.src_size == Register::Size::Word, "Unimplemented"); | 1331 | ASSERT_MSG(instr.conversion.src_size == Register::Size::Word, "Unimplemented"); |
| 1305 | std::string op_a = regs.GetRegisterAsFloat(instr.gpr20); | 1332 | std::string op_a{}; |
| 1333 | |||
| 1334 | if (instr.is_b_gpr) { | ||
| 1335 | op_a = regs.GetRegisterAsFloat(instr.gpr20); | ||
| 1336 | } else { | ||
| 1337 | op_a = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset, | ||
| 1338 | GLSLRegister::Type::Float); | ||
| 1339 | } | ||
| 1306 | 1340 | ||
| 1307 | if (instr.conversion.abs_a) { | 1341 | if (instr.conversion.abs_a) { |
| 1308 | op_a = "abs(" + op_a + ')'; | 1342 | op_a = "abs(" + op_a + ')'; |
| 1309 | } | 1343 | } |
| 1310 | 1344 | ||
| 1345 | if (instr.conversion.negate_a) { | ||
| 1346 | op_a = "-(" + op_a + ')'; | ||
| 1347 | } | ||
| 1348 | |||
| 1311 | switch (instr.conversion.f2i.rounding) { | 1349 | switch (instr.conversion.f2i.rounding) { |
| 1312 | case Tegra::Shader::F2iRoundingOp::None: | 1350 | case Tegra::Shader::F2iRoundingOp::None: |
| 1313 | break; | 1351 | break; |
| @@ -1355,11 +1393,16 @@ private: | |||
| 1355 | case OpCode::Id::LD_C: { | 1393 | case OpCode::Id::LD_C: { |
| 1356 | ASSERT_MSG(instr.ld_c.unknown == 0, "Unimplemented"); | 1394 | ASSERT_MSG(instr.ld_c.unknown == 0, "Unimplemented"); |
| 1357 | 1395 | ||
| 1396 | // Add an extra scope and declare the index register inside to prevent | ||
| 1397 | // overwriting it in case it is used as an output of the LD instruction. | ||
| 1398 | shader.AddLine("{"); | ||
| 1399 | ++shader.scope; | ||
| 1400 | |||
| 1401 | shader.AddLine("uint index = (" + regs.GetRegisterAsInteger(instr.gpr8, 0, false) + | ||
| 1402 | " / 4) & (MAX_CONSTBUFFER_ELEMENTS - 1);"); | ||
| 1403 | |||
| 1358 | std::string op_a = | 1404 | std::string op_a = |
| 1359 | regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 0, instr.gpr8, | 1405 | regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 0, "index", |
| 1360 | GLSLRegister::Type::Float); | ||
| 1361 | std::string op_b = | ||
| 1362 | regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 4, instr.gpr8, | ||
| 1363 | GLSLRegister::Type::Float); | 1406 | GLSLRegister::Type::Float); |
| 1364 | 1407 | ||
| 1365 | switch (instr.ld_c.type.Value()) { | 1408 | switch (instr.ld_c.type.Value()) { |
| @@ -1367,16 +1410,22 @@ private: | |||
| 1367 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); | 1410 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); |
| 1368 | break; | 1411 | break; |
| 1369 | 1412 | ||
| 1370 | case Tegra::Shader::UniformType::Double: | 1413 | case Tegra::Shader::UniformType::Double: { |
| 1414 | std::string op_b = | ||
| 1415 | regs.GetUniformIndirect(instr.cbuf36.index, instr.cbuf36.offset + 4, | ||
| 1416 | "index", GLSLRegister::Type::Float); | ||
| 1371 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); | 1417 | regs.SetRegisterToFloat(instr.gpr0, 0, op_a, 1, 1); |
| 1372 | regs.SetRegisterToFloat(instr.gpr0.Value() + 1, 0, op_b, 1, 1); | 1418 | regs.SetRegisterToFloat(instr.gpr0.Value() + 1, 0, op_b, 1, 1); |
| 1373 | break; | 1419 | break; |
| 1374 | 1420 | } | |
| 1375 | default: | 1421 | default: |
| 1376 | LOG_CRITICAL(HW_GPU, "Unhandled type: {}", | 1422 | LOG_CRITICAL(HW_GPU, "Unhandled type: {}", |
| 1377 | static_cast<unsigned>(instr.ld_c.type.Value())); | 1423 | static_cast<unsigned>(instr.ld_c.type.Value())); |
| 1378 | UNREACHABLE(); | 1424 | UNREACHABLE(); |
| 1379 | } | 1425 | } |
| 1426 | |||
| 1427 | --shader.scope; | ||
| 1428 | shader.AddLine("}"); | ||
| 1380 | break; | 1429 | break; |
| 1381 | } | 1430 | } |
| 1382 | case OpCode::Id::ST_A: { | 1431 | case OpCode::Id::ST_A: { |
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h index 83ea0cfc0..8f719fdd8 100644 --- a/src/video_core/renderer_opengl/maxwell_to_gl.h +++ b/src/video_core/renderer_opengl/maxwell_to_gl.h | |||
| @@ -24,16 +24,25 @@ using Maxwell = Tegra::Engines::Maxwell3D::Regs; | |||
| 24 | 24 | ||
| 25 | inline GLenum VertexType(Maxwell::VertexAttribute attrib) { | 25 | inline GLenum VertexType(Maxwell::VertexAttribute attrib) { |
| 26 | switch (attrib.type) { | 26 | switch (attrib.type) { |
| 27 | case Maxwell::VertexAttribute::Type::UnsignedInt: | ||
| 27 | case Maxwell::VertexAttribute::Type::UnsignedNorm: { | 28 | case Maxwell::VertexAttribute::Type::UnsignedNorm: { |
| 28 | 29 | ||
| 29 | switch (attrib.size) { | 30 | switch (attrib.size) { |
| 30 | case Maxwell::VertexAttribute::Size::Size_8: | 31 | case Maxwell::VertexAttribute::Size::Size_8: |
| 31 | case Maxwell::VertexAttribute::Size::Size_8_8: | 32 | case Maxwell::VertexAttribute::Size::Size_8_8: |
| 33 | case Maxwell::VertexAttribute::Size::Size_8_8_8: | ||
| 32 | case Maxwell::VertexAttribute::Size::Size_8_8_8_8: | 34 | case Maxwell::VertexAttribute::Size::Size_8_8_8_8: |
| 33 | return GL_UNSIGNED_BYTE; | 35 | return GL_UNSIGNED_BYTE; |
| 36 | case Maxwell::VertexAttribute::Size::Size_16: | ||
| 34 | case Maxwell::VertexAttribute::Size::Size_16_16: | 37 | case Maxwell::VertexAttribute::Size::Size_16_16: |
| 38 | case Maxwell::VertexAttribute::Size::Size_16_16_16: | ||
| 35 | case Maxwell::VertexAttribute::Size::Size_16_16_16_16: | 39 | case Maxwell::VertexAttribute::Size::Size_16_16_16_16: |
| 36 | return GL_UNSIGNED_SHORT; | 40 | return GL_UNSIGNED_SHORT; |
| 41 | case Maxwell::VertexAttribute::Size::Size_32: | ||
| 42 | case Maxwell::VertexAttribute::Size::Size_32_32: | ||
| 43 | case Maxwell::VertexAttribute::Size::Size_32_32_32: | ||
| 44 | case Maxwell::VertexAttribute::Size::Size_32_32_32_32: | ||
| 45 | return GL_UNSIGNED_INT; | ||
| 37 | case Maxwell::VertexAttribute::Size::Size_10_10_10_2: | 46 | case Maxwell::VertexAttribute::Size::Size_10_10_10_2: |
| 38 | return GL_UNSIGNED_INT_2_10_10_10_REV; | 47 | return GL_UNSIGNED_INT_2_10_10_10_REV; |
| 39 | } | 48 | } |
| @@ -43,16 +52,25 @@ inline GLenum VertexType(Maxwell::VertexAttribute attrib) { | |||
| 43 | return {}; | 52 | return {}; |
| 44 | } | 53 | } |
| 45 | 54 | ||
| 55 | case Maxwell::VertexAttribute::Type::SignedInt: | ||
| 46 | case Maxwell::VertexAttribute::Type::SignedNorm: { | 56 | case Maxwell::VertexAttribute::Type::SignedNorm: { |
| 47 | 57 | ||
| 48 | switch (attrib.size) { | 58 | switch (attrib.size) { |
| 49 | case Maxwell::VertexAttribute::Size::Size_32_32_32: | 59 | case Maxwell::VertexAttribute::Size::Size_8: |
| 50 | return GL_INT; | ||
| 51 | case Maxwell::VertexAttribute::Size::Size_8_8: | 60 | case Maxwell::VertexAttribute::Size::Size_8_8: |
| 61 | case Maxwell::VertexAttribute::Size::Size_8_8_8: | ||
| 52 | case Maxwell::VertexAttribute::Size::Size_8_8_8_8: | 62 | case Maxwell::VertexAttribute::Size::Size_8_8_8_8: |
| 53 | return GL_BYTE; | 63 | return GL_BYTE; |
| 64 | case Maxwell::VertexAttribute::Size::Size_16: | ||
| 54 | case Maxwell::VertexAttribute::Size::Size_16_16: | 65 | case Maxwell::VertexAttribute::Size::Size_16_16: |
| 66 | case Maxwell::VertexAttribute::Size::Size_16_16_16: | ||
| 67 | case Maxwell::VertexAttribute::Size::Size_16_16_16_16: | ||
| 55 | return GL_SHORT; | 68 | return GL_SHORT; |
| 69 | case Maxwell::VertexAttribute::Size::Size_32: | ||
| 70 | case Maxwell::VertexAttribute::Size::Size_32_32: | ||
| 71 | case Maxwell::VertexAttribute::Size::Size_32_32_32: | ||
| 72 | case Maxwell::VertexAttribute::Size::Size_32_32_32_32: | ||
| 73 | return GL_INT; | ||
| 56 | case Maxwell::VertexAttribute::Size::Size_10_10_10_2: | 74 | case Maxwell::VertexAttribute::Size::Size_10_10_10_2: |
| 57 | return GL_INT_2_10_10_10_REV; | 75 | return GL_INT_2_10_10_10_REV; |
| 58 | } | 76 | } |
| @@ -62,9 +80,6 @@ inline GLenum VertexType(Maxwell::VertexAttribute attrib) { | |||
| 62 | return {}; | 80 | return {}; |
| 63 | } | 81 | } |
| 64 | 82 | ||
| 65 | case Maxwell::VertexAttribute::Type::UnsignedInt: | ||
| 66 | return GL_UNSIGNED_INT; | ||
| 67 | |||
| 68 | case Maxwell::VertexAttribute::Type::Float: | 83 | case Maxwell::VertexAttribute::Type::Float: |
| 69 | return GL_FLOAT; | 84 | return GL_FLOAT; |
| 70 | } | 85 | } |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 94fb8ae6a..4bbea3f3c 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -6,7 +6,10 @@ | |||
| 6 | #include <clocale> | 6 | #include <clocale> |
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <thread> | 8 | #include <thread> |
| 9 | |||
| 10 | #include <fmt/ostream.h> | ||
| 9 | #include <glad/glad.h> | 11 | #include <glad/glad.h> |
| 12 | |||
| 10 | #define QT_NO_OPENGL | 13 | #define QT_NO_OPENGL |
| 11 | #include <QDesktopWidget> | 14 | #include <QDesktopWidget> |
| 12 | #include <QFileDialog> | 15 | #include <QFileDialog> |
| @@ -454,7 +457,7 @@ bool GMainWindow::LoadROM(const QString& filename) { | |||
| 454 | "While attempting to load the ROM requested, an error occured. Please " | 457 | "While attempting to load the ROM requested, an error occured. Please " |
| 455 | "refer to the yuzu wiki for more information or the yuzu discord for " | 458 | "refer to the yuzu wiki for more information or the yuzu discord for " |
| 456 | "additional help.\n\nError Code: {:04X}-{:04X}\nError Description: {}", | 459 | "additional help.\n\nError Code: {:04X}-{:04X}\nError Description: {}", |
| 457 | loader_id, error_id, Loader::GetMessageForResultStatus(error_id)))); | 460 | loader_id, error_id, static_cast<Loader::ResultStatus>(error_id)))); |
| 458 | } else { | 461 | } else { |
| 459 | QMessageBox::critical( | 462 | QMessageBox::critical( |
| 460 | this, tr("Error while loading ROM!"), | 463 | this, tr("Error while loading ROM!"), |
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index e44a98311..9095cf27d 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | #include <string> | 7 | #include <string> |
| 8 | #include <thread> | 8 | #include <thread> |
| 9 | 9 | ||
| 10 | #include <fmt/ostream.h> | ||
| 11 | |||
| 10 | #include "common/common_paths.h" | 12 | #include "common/common_paths.h" |
| 11 | #include "common/logging/backend.h" | 13 | #include "common/logging/backend.h" |
| 12 | #include "common/logging/filter.h" | 14 | #include "common/logging/filter.h" |
| @@ -194,7 +196,7 @@ int main(int argc, char** argv) { | |||
| 194 | "While attempting to load the ROM requested, an error occured. Please " | 196 | "While attempting to load the ROM requested, an error occured. Please " |
| 195 | "refer to the yuzu wiki for more information or the yuzu discord for " | 197 | "refer to the yuzu wiki for more information or the yuzu discord for " |
| 196 | "additional help.\n\nError Code: {:04X}-{:04X}\nError Description: {}", | 198 | "additional help.\n\nError Code: {:04X}-{:04X}\nError Description: {}", |
| 197 | loader_id, error_id, Loader::GetMessageForResultStatus(error_id)); | 199 | loader_id, error_id, static_cast<Loader::ResultStatus>(error_id)); |
| 198 | } | 200 | } |
| 199 | } | 201 | } |
| 200 | 202 | ||