summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/core_timing.cpp10
-rw-r--r--src/core/core_timing.h1
-rw-r--r--src/core/file_sys/card_image.cpp7
-rw-r--r--src/core/hle/kernel/server_session.cpp2
-rw-r--r--src/core/hle/kernel/server_session.h7
-rw-r--r--src/core/hle/kernel/thread.cpp2
-rw-r--r--src/core/hle/service/sm/controller.cpp4
-rw-r--r--src/core/loader/loader.cpp12
-rw-r--r--src/core/loader/loader.h4
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp6
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp44
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h159
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp101
-rw-r--r--src/video_core/renderer_opengl/maxwell_to_gl.h25
-rw-r--r--src/yuzu/main.cpp5
-rw-r--r--src/yuzu_cmd/yuzu.cpp4
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
57static Common::MPSCQueue<Event, false> ts_queue; 57static Common::MPSCQueue<Event, false> ts_queue;
58 58
59// the queue for unscheduling the events from other threads threadsafe
60static Common::MPSCQueue<std::pair<const EventType*, u64>, false> unschedule_queue;
61
59constexpr int MAX_SLICE_LENGTH = 20000; 62constexpr int MAX_SLICE_LENGTH = 20000;
60 63
61static s64 idled_cycles; 64static s64 idled_cycles;
@@ -158,6 +161,10 @@ void UnscheduleEvent(const EventType* event_type, u64 userdata) {
158 } 161 }
159} 162}
160 163
164void UnscheduleEventThreadsafe(const EventType* event_type, u64 userdata) {
165 unschedule_queue.Push(std::make_pair(event_type, userdata));
166}
167
161void RemoveEvent(const EventType* event_type) { 168void 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
195void Advance() { 202void 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
65void ScheduleEventThreadsafe(s64 cycles_into_future, const EventType* event_type, u64 userdata); 65void ScheduleEventThreadsafe(s64 cycles_into_future, const EventType* event_type, u64 userdata);
66 66
67void UnscheduleEvent(const EventType* event_type, u64 userdata); 67void UnscheduleEvent(const EventType* event_type, u64 userdata);
68void 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.
70void RemoveEvent(const EventType* event_type); 71void 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
13namespace FileSys { 16namespace 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
169void Thread::CancelWakeupTimer() { 169void Thread::CancelWakeupTimer() {
170 CoreTiming::UnscheduleEvent(ThreadWakeupEventType, callback_handle); 170 CoreTiming::UnscheduleEventThreadsafe(ThreadWakeupEventType, callback_handle);
171} 171}
172 172
173static boost::optional<s32> GetNextProcessorId(u64 mask) { 173static 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 @@
10namespace Service::SM { 10namespace Service::SM {
11 11
12void Controller::ConvertSessionToDomain(Kernel::HLERequestContext& ctx) { 12void 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) {
41void Controller::QueryPointerBufferSize(Kernel::HLERequestContext& ctx) { 41void 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
122std::string GetMessageForResultStatus(ResultStatus status) { 123std::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
126std::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
97std::string GetMessageForResultStatus(ResultStatus status); 98std::ostream& operator<<(std::ostream& os, ResultStatus status);
98std::string GetMessageForResultStatus(u16 status);
99 99
100/// Interface for loading an application 100/// Interface for loading an application
101class AppLoader : NonCopyable { 101class 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 {
94static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ 94static 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
463static void ConvertG8R8ToR8G8(std::vector<u8>& data, u32 width, u32 height) { 466static 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
25inline GLenum VertexType(Maxwell::VertexAttribute attrib) { 25inline 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