summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_core/CMakeLists.txt8
-rw-r--r--src/audio_core/algorithm/filter.cpp79
-rw-r--r--src/audio_core/algorithm/filter.h62
-rw-r--r--src/audio_core/algorithm/interpolate.cpp71
-rw-r--r--src/audio_core/algorithm/interpolate.h43
-rw-r--r--src/audio_core/audio_renderer.cpp5
-rw-r--r--src/audio_core/audio_renderer.h2
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.cpp4
-rw-r--r--src/core/file_sys/card_image.cpp8
-rw-r--r--src/core/file_sys/card_image.h6
-rw-r--r--src/core/file_sys/vfs.cpp20
-rw-r--r--src/core/hle/kernel/kernel.cpp2
-rw-r--r--src/core/hle/kernel/object.h15
-rw-r--r--src/video_core/gpu.cpp4
-rw-r--r--src/video_core/gpu.h4
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp76
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h110
-rw-r--r--src/video_core/renderer_opengl/maxwell_to_gl.h1
18 files changed, 434 insertions, 86 deletions
diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt
index ec71524a3..82e4850f7 100644
--- a/src/audio_core/CMakeLists.txt
+++ b/src/audio_core/CMakeLists.txt
@@ -1,4 +1,8 @@
1add_library(audio_core STATIC 1add_library(audio_core STATIC
2 algorithm/filter.cpp
3 algorithm/filter.h
4 algorithm/interpolate.cpp
5 algorithm/interpolate.h
2 audio_out.cpp 6 audio_out.cpp
3 audio_out.h 7 audio_out.h
4 audio_renderer.cpp 8 audio_renderer.cpp
@@ -7,12 +11,12 @@ add_library(audio_core STATIC
7 codec.cpp 11 codec.cpp
8 codec.h 12 codec.h
9 null_sink.h 13 null_sink.h
10 stream.cpp
11 stream.h
12 sink.h 14 sink.h
13 sink_details.cpp 15 sink_details.cpp
14 sink_details.h 16 sink_details.h
15 sink_stream.h 17 sink_stream.h
18 stream.cpp
19 stream.h
16 20
17 $<$<BOOL:${ENABLE_CUBEB}>:cubeb_sink.cpp cubeb_sink.h> 21 $<$<BOOL:${ENABLE_CUBEB}>:cubeb_sink.cpp cubeb_sink.h>
18) 22)
diff --git a/src/audio_core/algorithm/filter.cpp b/src/audio_core/algorithm/filter.cpp
new file mode 100644
index 000000000..403b8503f
--- /dev/null
+++ b/src/audio_core/algorithm/filter.cpp
@@ -0,0 +1,79 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#define _USE_MATH_DEFINES
6
7#include <algorithm>
8#include <array>
9#include <cmath>
10#include <vector>
11#include "audio_core/algorithm/filter.h"
12#include "common/common_types.h"
13
14namespace AudioCore {
15
16Filter Filter::LowPass(double cutoff, double Q) {
17 const double w0 = 2.0 * M_PI * cutoff;
18 const double sin_w0 = std::sin(w0);
19 const double cos_w0 = std::cos(w0);
20 const double alpha = sin_w0 / (2 * Q);
21
22 const double a0 = 1 + alpha;
23 const double a1 = -2.0 * cos_w0;
24 const double a2 = 1 - alpha;
25 const double b0 = 0.5 * (1 - cos_w0);
26 const double b1 = 1.0 * (1 - cos_w0);
27 const double b2 = 0.5 * (1 - cos_w0);
28
29 return {a0, a1, a2, b0, b1, b2};
30}
31
32Filter::Filter() : Filter(1.0, 0.0, 0.0, 1.0, 0.0, 0.0) {}
33
34Filter::Filter(double a0, double a1, double a2, double b0, double b1, double b2)
35 : a1(a1 / a0), a2(a2 / a0), b0(b0 / a0), b1(b1 / a0), b2(b2 / a0) {}
36
37void Filter::Process(std::vector<s16>& signal) {
38 const size_t num_frames = signal.size() / 2;
39 for (size_t i = 0; i < num_frames; i++) {
40 std::rotate(in.begin(), in.end() - 1, in.end());
41 std::rotate(out.begin(), out.end() - 1, out.end());
42
43 for (size_t ch = 0; ch < channel_count; ch++) {
44 in[0][ch] = signal[i * channel_count + ch];
45
46 out[0][ch] = b0 * in[0][ch] + b1 * in[1][ch] + b2 * in[2][ch] - a1 * out[1][ch] -
47 a2 * out[2][ch];
48
49 signal[i * 2 + ch] = std::clamp(out[0][ch], -32768.0, 32767.0);
50 }
51 }
52}
53
54/// Calculates the appropriate Q for each biquad in a cascading filter.
55/// @param total_count The total number of biquads to be cascaded.
56/// @param index 0-index of the biquad to calculate the Q value for.
57static double CascadingBiquadQ(size_t total_count, size_t index) {
58 const double pole = M_PI * (2 * index + 1) / (4.0 * total_count);
59 return 1.0 / (2.0 * std::cos(pole));
60}
61
62CascadingFilter CascadingFilter::LowPass(double cutoff, size_t cascade_size) {
63 std::vector<Filter> cascade(cascade_size);
64 for (size_t i = 0; i < cascade_size; i++) {
65 cascade[i] = Filter::LowPass(cutoff, CascadingBiquadQ(cascade_size, i));
66 }
67 return CascadingFilter{std::move(cascade)};
68}
69
70CascadingFilter::CascadingFilter() = default;
71CascadingFilter::CascadingFilter(std::vector<Filter> filters) : filters(std::move(filters)) {}
72
73void CascadingFilter::Process(std::vector<s16>& signal) {
74 for (auto& filter : filters) {
75 filter.Process(signal);
76 }
77}
78
79} // namespace AudioCore
diff --git a/src/audio_core/algorithm/filter.h b/src/audio_core/algorithm/filter.h
new file mode 100644
index 000000000..a41beef98
--- /dev/null
+++ b/src/audio_core/algorithm/filter.h
@@ -0,0 +1,62 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include <vector>
9#include "common/common_types.h"
10
11namespace AudioCore {
12
13/// Digital biquad filter:
14///
15/// b0 + b1 z^-1 + b2 z^-2
16/// H(z) = ------------------------
17/// a0 + a1 z^-1 + b2 z^-2
18class Filter {
19public:
20 /// Creates a low-pass filter.
21 /// @param cutoff Determines the cutoff frequency. A value from 0.0 to 1.0.
22 /// @param Q Determines the quality factor of this filter.
23 static Filter LowPass(double cutoff, double Q = 0.7071);
24
25 /// Passthrough filter.
26 Filter();
27
28 Filter(double a0, double a1, double a2, double b0, double b1, double b2);
29
30 void Process(std::vector<s16>& signal);
31
32private:
33 static constexpr size_t channel_count = 2;
34
35 /// Coefficients are in normalized form (a0 = 1.0).
36 double a1, a2, b0, b1, b2;
37 /// Input History
38 std::array<std::array<double, channel_count>, 3> in;
39 /// Output History
40 std::array<std::array<double, channel_count>, 3> out;
41};
42
43/// Cascade filters to build up higher-order filters from lower-order ones.
44class CascadingFilter {
45public:
46 /// Creates a cascading low-pass filter.
47 /// @param cutoff Determines the cutoff frequency. A value from 0.0 to 1.0.
48 /// @param cascade_size Number of biquads in cascade.
49 static CascadingFilter LowPass(double cutoff, size_t cascade_size);
50
51 /// Passthrough.
52 CascadingFilter();
53
54 explicit CascadingFilter(std::vector<Filter> filters);
55
56 void Process(std::vector<s16>& signal);
57
58private:
59 std::vector<Filter> filters;
60};
61
62} // namespace AudioCore
diff --git a/src/audio_core/algorithm/interpolate.cpp b/src/audio_core/algorithm/interpolate.cpp
new file mode 100644
index 000000000..11459821f
--- /dev/null
+++ b/src/audio_core/algorithm/interpolate.cpp
@@ -0,0 +1,71 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#define _USE_MATH_DEFINES
6
7#include <algorithm>
8#include <cmath>
9#include <vector>
10#include "audio_core/algorithm/interpolate.h"
11#include "common/common_types.h"
12#include "common/logging/log.h"
13
14namespace AudioCore {
15
16/// The Lanczos kernel
17static double Lanczos(size_t a, double x) {
18 if (x == 0.0)
19 return 1.0;
20 const double px = M_PI * x;
21 return a * std::sin(px) * std::sin(px / a) / (px * px);
22}
23
24std::vector<s16> Interpolate(InterpolationState& state, std::vector<s16> input, double ratio) {
25 if (input.size() < 2)
26 return {};
27
28 if (ratio <= 0) {
29 LOG_CRITICAL(Audio, "Nonsensical interpolation ratio {}", ratio);
30 ratio = 1.0;
31 }
32
33 if (ratio != state.current_ratio) {
34 const double cutoff_frequency = std::min(0.5 / ratio, 0.5 * ratio);
35 state.nyquist = CascadingFilter::LowPass(std::clamp(cutoff_frequency, 0.0, 0.4), 3);
36 state.current_ratio = ratio;
37 }
38 state.nyquist.Process(input);
39
40 constexpr size_t taps = InterpolationState::lanczos_taps;
41 const size_t num_frames = input.size() / 2;
42
43 std::vector<s16> output;
44 output.reserve(static_cast<size_t>(input.size() / ratio + 4));
45
46 double& pos = state.position;
47 auto& h = state.history;
48 for (size_t i = 0; i < num_frames; ++i) {
49 std::rotate(h.begin(), h.end() - 1, h.end());
50 h[0][0] = input[i * 2 + 0];
51 h[0][1] = input[i * 2 + 1];
52
53 while (pos <= 1.0) {
54 double l = 0.0;
55 double r = 0.0;
56 for (size_t j = 0; j < h.size(); j++) {
57 l += Lanczos(taps, pos + j - taps + 1) * h[j][0];
58 r += Lanczos(taps, pos + j - taps + 1) * h[j][1];
59 }
60 output.emplace_back(static_cast<s16>(std::clamp(l, -32768.0, 32767.0)));
61 output.emplace_back(static_cast<s16>(std::clamp(r, -32768.0, 32767.0)));
62
63 pos += ratio;
64 }
65 pos -= 1.0;
66 }
67
68 return output;
69}
70
71} // namespace AudioCore
diff --git a/src/audio_core/algorithm/interpolate.h b/src/audio_core/algorithm/interpolate.h
new file mode 100644
index 000000000..c79c2eef4
--- /dev/null
+++ b/src/audio_core/algorithm/interpolate.h
@@ -0,0 +1,43 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include <vector>
9#include "audio_core/algorithm/filter.h"
10#include "common/common_types.h"
11
12namespace AudioCore {
13
14struct InterpolationState {
15 static constexpr size_t lanczos_taps = 4;
16 static constexpr size_t history_size = lanczos_taps * 2 - 1;
17
18 double current_ratio = 0.0;
19 CascadingFilter nyquist;
20 std::array<std::array<s16, 2>, history_size> history = {};
21 double position = 0;
22};
23
24/// Interpolates input signal to produce output signal.
25/// @param input The signal to interpolate.
26/// @param ratio Interpolation ratio.
27/// ratio > 1.0 results in fewer output samples.
28/// ratio < 1.0 results in more output samples.
29/// @returns Output signal.
30std::vector<s16> Interpolate(InterpolationState& state, std::vector<s16> input, double ratio);
31
32/// Interpolates input signal to produce output signal.
33/// @param input The signal to interpolate.
34/// @param input_rate The sample rate of input.
35/// @param output_rate The desired sample rate of the output.
36/// @returns Output signal.
37inline std::vector<s16> Interpolate(InterpolationState& state, std::vector<s16> input,
38 u32 input_rate, u32 output_rate) {
39 const double ratio = static_cast<double>(input_rate) / static_cast<double>(output_rate);
40 return Interpolate(state, std::move(input), ratio);
41}
42
43} // namespace AudioCore
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp
index 6ebed3fb0..397b107f5 100644
--- a/src/audio_core/audio_renderer.cpp
+++ b/src/audio_core/audio_renderer.cpp
@@ -2,6 +2,7 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "audio_core/algorithm/interpolate.h"
5#include "audio_core/audio_renderer.h" 6#include "audio_core/audio_renderer.h"
6#include "common/assert.h" 7#include "common/assert.h"
7#include "common/logging/log.h" 8#include "common/logging/log.h"
@@ -199,6 +200,8 @@ void AudioRenderer::VoiceState::RefreshBuffer() {
199 break; 200 break;
200 } 201 }
201 202
203 samples = Interpolate(interp_state, std::move(samples), Info().sample_rate, STREAM_SAMPLE_RATE);
204
202 is_refresh_pending = false; 205 is_refresh_pending = false;
203} 206}
204 207
@@ -224,7 +227,7 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
224 break; 227 break;
225 } 228 }
226 229
227 samples_remaining -= samples.size(); 230 samples_remaining -= samples.size() / stream->GetNumChannels();
228 231
229 for (const auto& sample : samples) { 232 for (const auto& sample : samples) {
230 const s32 buffer_sample{buffer[offset]}; 233 const s32 buffer_sample{buffer[offset]};
diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h
index 13c5d0adc..eba67f28e 100644
--- a/src/audio_core/audio_renderer.h
+++ b/src/audio_core/audio_renderer.h
@@ -8,6 +8,7 @@
8#include <memory> 8#include <memory>
9#include <vector> 9#include <vector>
10 10
11#include "audio_core/algorithm/interpolate.h"
11#include "audio_core/audio_out.h" 12#include "audio_core/audio_out.h"
12#include "audio_core/codec.h" 13#include "audio_core/codec.h"
13#include "audio_core/stream.h" 14#include "audio_core/stream.h"
@@ -194,6 +195,7 @@ private:
194 size_t wave_index{}; 195 size_t wave_index{};
195 size_t offset{}; 196 size_t offset{};
196 Codec::ADPCMState adpcm_state{}; 197 Codec::ADPCMState adpcm_state{};
198 InterpolationState interp_state{};
197 std::vector<s16> samples; 199 std::vector<s16> samples;
198 VoiceOutStatus out_status{}; 200 VoiceOutStatus out_status{};
199 VoiceInfo info{}; 201 VoiceInfo info{};
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
index 0996f129c..20e5200a8 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -243,9 +243,7 @@ void ARM_Dynarmic::LoadContext(const ThreadContext& ctx) {
243} 243}
244 244
245void ARM_Dynarmic::PrepareReschedule() { 245void ARM_Dynarmic::PrepareReschedule() {
246 if (jit->IsExecuting()) { 246 jit->HaltExecution();
247 jit->HaltExecution();
248 }
249} 247}
250 248
251void ARM_Dynarmic::ClearInstructionCache() { 249void ARM_Dynarmic::ClearInstructionCache() {
diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp
index a4823353e..8e05b9d0e 100644
--- a/src/core/file_sys/card_image.cpp
+++ b/src/core/file_sys/card_image.cpp
@@ -107,19 +107,19 @@ VirtualFile XCI::GetNCAFileByType(NCAContentType type) const {
107 return nullptr; 107 return nullptr;
108} 108}
109 109
110std::vector<std::shared_ptr<VfsFile>> XCI::GetFiles() const { 110std::vector<VirtualFile> XCI::GetFiles() const {
111 return {}; 111 return {};
112} 112}
113 113
114std::vector<std::shared_ptr<VfsDirectory>> XCI::GetSubdirectories() const { 114std::vector<VirtualDir> XCI::GetSubdirectories() const {
115 return std::vector<std::shared_ptr<VfsDirectory>>(); 115 return {};
116} 116}
117 117
118std::string XCI::GetName() const { 118std::string XCI::GetName() const {
119 return file->GetName(); 119 return file->GetName();
120} 120}
121 121
122std::shared_ptr<VfsDirectory> XCI::GetParentDirectory() const { 122VirtualDir XCI::GetParentDirectory() const {
123 return file->GetContainingDirectory(); 123 return file->GetContainingDirectory();
124} 124}
125 125
diff --git a/src/core/file_sys/card_image.h b/src/core/file_sys/card_image.h
index e089d737c..4618d9c00 100644
--- a/src/core/file_sys/card_image.h
+++ b/src/core/file_sys/card_image.h
@@ -71,13 +71,13 @@ public:
71 std::shared_ptr<NCA> GetNCAByType(NCAContentType type) const; 71 std::shared_ptr<NCA> GetNCAByType(NCAContentType type) const;
72 VirtualFile GetNCAFileByType(NCAContentType type) const; 72 VirtualFile GetNCAFileByType(NCAContentType type) const;
73 73
74 std::vector<std::shared_ptr<VfsFile>> GetFiles() const override; 74 std::vector<VirtualFile> GetFiles() const override;
75 75
76 std::vector<std::shared_ptr<VfsDirectory>> GetSubdirectories() const override; 76 std::vector<VirtualDir> GetSubdirectories() const override;
77 77
78 std::string GetName() const override; 78 std::string GetName() const override;
79 79
80 std::shared_ptr<VfsDirectory> GetParentDirectory() const override; 80 VirtualDir GetParentDirectory() const override;
81 81
82protected: 82protected:
83 bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override; 83 bool ReplaceFileWithSubdirectory(VirtualFile file, VirtualDir dir) override;
diff --git a/src/core/file_sys/vfs.cpp b/src/core/file_sys/vfs.cpp
index 24e158962..a5ec50b1a 100644
--- a/src/core/file_sys/vfs.cpp
+++ b/src/core/file_sys/vfs.cpp
@@ -74,15 +74,15 @@ VirtualFile VfsFilesystem::CopyFile(std::string_view old_path_, std::string_view
74 return new_file; 74 return new_file;
75} 75}
76 76
77VirtualFile VfsFilesystem::MoveFile(std::string_view old_path_, std::string_view new_path_) { 77VirtualFile VfsFilesystem::MoveFile(std::string_view old_path, std::string_view new_path) {
78 const auto old_path = FileUtil::SanitizePath(old_path_); 78 const auto sanitized_old_path = FileUtil::SanitizePath(old_path);
79 const auto new_path = FileUtil::SanitizePath(new_path_); 79 const auto sanitized_new_path = FileUtil::SanitizePath(new_path);
80 80
81 // Again, non-default impls are highly encouraged to provide a more optimized version of this. 81 // Again, non-default impls are highly encouraged to provide a more optimized version of this.
82 auto out = CopyFile(old_path_, new_path_); 82 auto out = CopyFile(sanitized_old_path, sanitized_new_path);
83 if (out == nullptr) 83 if (out == nullptr)
84 return nullptr; 84 return nullptr;
85 if (DeleteFile(old_path)) 85 if (DeleteFile(sanitized_old_path))
86 return out; 86 return out;
87 return nullptr; 87 return nullptr;
88} 88}
@@ -137,15 +137,15 @@ VirtualDir VfsFilesystem::CopyDirectory(std::string_view old_path_, std::string_
137 return new_dir; 137 return new_dir;
138} 138}
139 139
140VirtualDir VfsFilesystem::MoveDirectory(std::string_view old_path_, std::string_view new_path_) { 140VirtualDir VfsFilesystem::MoveDirectory(std::string_view old_path, std::string_view new_path) {
141 const auto old_path = FileUtil::SanitizePath(old_path_); 141 const auto sanitized_old_path = FileUtil::SanitizePath(old_path);
142 const auto new_path = FileUtil::SanitizePath(new_path_); 142 const auto sanitized_new_path = FileUtil::SanitizePath(new_path);
143 143
144 // Non-default impls are highly encouraged to provide a more optimized version of this. 144 // Non-default impls are highly encouraged to provide a more optimized version of this.
145 auto out = CopyDirectory(old_path_, new_path_); 145 auto out = CopyDirectory(sanitized_old_path, sanitized_new_path);
146 if (out == nullptr) 146 if (out == nullptr)
147 return nullptr; 147 return nullptr;
148 if (DeleteDirectory(old_path)) 148 if (DeleteDirectory(sanitized_old_path))
149 return out; 149 return out;
150 return nullptr; 150 return nullptr;
151} 151}
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 1b0cd0abf..8c19e86d3 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -11,7 +11,7 @@
11 11
12namespace Kernel { 12namespace Kernel {
13 13
14unsigned int Object::next_object_id; 14std::atomic<u32> Object::next_object_id{0};
15 15
16/// Initialize the kernel 16/// Initialize the kernel
17void Init() { 17void Init() {
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h
index 83df68dfd..526ac9cc3 100644
--- a/src/core/hle/kernel/object.h
+++ b/src/core/hle/kernel/object.h
@@ -4,6 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <atomic>
7#include <string> 8#include <string>
8#include <utility> 9#include <utility>
9 10
@@ -42,8 +43,8 @@ public:
42 virtual ~Object(); 43 virtual ~Object();
43 44
44 /// Returns a unique identifier for the object. For debugging purposes only. 45 /// Returns a unique identifier for the object. For debugging purposes only.
45 unsigned int GetObjectId() const { 46 u32 GetObjectId() const {
46 return object_id; 47 return object_id.load(std::memory_order_relaxed);
47 } 48 }
48 49
49 virtual std::string GetTypeName() const { 50 virtual std::string GetTypeName() const {
@@ -61,23 +62,23 @@ public:
61 bool IsWaitable() const; 62 bool IsWaitable() const;
62 63
63public: 64public:
64 static unsigned int next_object_id; 65 static std::atomic<u32> next_object_id;
65 66
66private: 67private:
67 friend void intrusive_ptr_add_ref(Object*); 68 friend void intrusive_ptr_add_ref(Object*);
68 friend void intrusive_ptr_release(Object*); 69 friend void intrusive_ptr_release(Object*);
69 70
70 unsigned int ref_count = 0; 71 std::atomic<u32> ref_count{0};
71 unsigned int object_id = next_object_id++; 72 std::atomic<u32> object_id{next_object_id++};
72}; 73};
73 74
74// Special functions used by boost::instrusive_ptr to do automatic ref-counting 75// Special functions used by boost::instrusive_ptr to do automatic ref-counting
75inline void intrusive_ptr_add_ref(Object* object) { 76inline void intrusive_ptr_add_ref(Object* object) {
76 ++object->ref_count; 77 object->ref_count.fetch_add(1, std::memory_order_relaxed);
77} 78}
78 79
79inline void intrusive_ptr_release(Object* object) { 80inline void intrusive_ptr_release(Object* object) {
80 if (--object->ref_count == 0) { 81 if (object->ref_count.fetch_sub(1, std::memory_order_acq_rel) == 1) {
81 delete object; 82 delete object;
82 } 83 }
83} 84}
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 19e7f1161..c9f6b82b7 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -46,8 +46,10 @@ u32 RenderTargetBytesPerPixel(RenderTargetFormat format) {
46 case RenderTargetFormat::RGBA32_FLOAT: 46 case RenderTargetFormat::RGBA32_FLOAT:
47 case RenderTargetFormat::RGBA32_UINT: 47 case RenderTargetFormat::RGBA32_UINT:
48 return 16; 48 return 16;
49 case RenderTargetFormat::RGBA16_UINT:
49 case RenderTargetFormat::RGBA16_FLOAT: 50 case RenderTargetFormat::RGBA16_FLOAT:
50 case RenderTargetFormat::RG32_FLOAT: 51 case RenderTargetFormat::RG32_FLOAT:
52 case RenderTargetFormat::RG32_UINT:
51 return 8; 53 return 8;
52 case RenderTargetFormat::RGBA8_UNORM: 54 case RenderTargetFormat::RGBA8_UNORM:
53 case RenderTargetFormat::RGBA8_SNORM: 55 case RenderTargetFormat::RGBA8_SNORM:
@@ -61,12 +63,14 @@ u32 RenderTargetBytesPerPixel(RenderTargetFormat format) {
61 case RenderTargetFormat::RG16_FLOAT: 63 case RenderTargetFormat::RG16_FLOAT:
62 case RenderTargetFormat::R32_FLOAT: 64 case RenderTargetFormat::R32_FLOAT:
63 case RenderTargetFormat::R11G11B10_FLOAT: 65 case RenderTargetFormat::R11G11B10_FLOAT:
66 case RenderTargetFormat::R32_UINT:
64 return 4; 67 return 4;
65 case RenderTargetFormat::R16_UNORM: 68 case RenderTargetFormat::R16_UNORM:
66 case RenderTargetFormat::R16_SNORM: 69 case RenderTargetFormat::R16_SNORM:
67 case RenderTargetFormat::R16_UINT: 70 case RenderTargetFormat::R16_UINT:
68 case RenderTargetFormat::R16_SINT: 71 case RenderTargetFormat::R16_SINT:
69 case RenderTargetFormat::R16_FLOAT: 72 case RenderTargetFormat::R16_FLOAT:
73 case RenderTargetFormat::RG8_UNORM:
70 case RenderTargetFormat::RG8_SNORM: 74 case RenderTargetFormat::RG8_SNORM:
71 return 2; 75 return 2;
72 case RenderTargetFormat::R8_UNORM: 76 case RenderTargetFormat::R8_UNORM:
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index e008d8f26..8a90a3a66 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -20,8 +20,10 @@ enum class RenderTargetFormat : u32 {
20 NONE = 0x0, 20 NONE = 0x0,
21 RGBA32_FLOAT = 0xC0, 21 RGBA32_FLOAT = 0xC0,
22 RGBA32_UINT = 0xC2, 22 RGBA32_UINT = 0xC2,
23 RGBA16_UINT = 0xC9,
23 RGBA16_FLOAT = 0xCA, 24 RGBA16_FLOAT = 0xCA,
24 RG32_FLOAT = 0xCB, 25 RG32_FLOAT = 0xCB,
26 RG32_UINT = 0xCD,
25 BGRA8_UNORM = 0xCF, 27 BGRA8_UNORM = 0xCF,
26 RGB10_A2_UNORM = 0xD1, 28 RGB10_A2_UNORM = 0xD1,
27 RGBA8_UNORM = 0xD5, 29 RGBA8_UNORM = 0xD5,
@@ -33,8 +35,10 @@ enum class RenderTargetFormat : u32 {
33 RG16_UINT = 0xDD, 35 RG16_UINT = 0xDD,
34 RG16_FLOAT = 0xDE, 36 RG16_FLOAT = 0xDE,
35 R11G11B10_FLOAT = 0xE0, 37 R11G11B10_FLOAT = 0xE0,
38 R32_UINT = 0xE4,
36 R32_FLOAT = 0xE5, 39 R32_FLOAT = 0xE5,
37 B5G6R5_UNORM = 0xE8, 40 B5G6R5_UNORM = 0xE8,
41 RG8_UNORM = 0xEA,
38 RG8_SNORM = 0xEB, 42 RG8_SNORM = 0xEB,
39 R16_UNORM = 0xEE, 43 R16_UNORM = 0xEE,
40 R16_SNORM = 0xEF, 44 R16_SNORM = 0xEF,
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 84c250c63..4b48ab8e2 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -101,6 +101,7 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form
101 {GL_R8, GL_RED, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // R8 101 {GL_R8, GL_RED, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // R8
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_RGBA16UI, GL_RGBA, GL_UNSIGNED_SHORT, ComponentType::UInt, false}, // RGBA16UI
104 {GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, ComponentType::Float, 105 {GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, ComponentType::Float,
105 false}, // R11FG11FB10F 106 false}, // R11FG11FB10F
106 {GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // RGBA32UI 107 {GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // RGBA32UI
@@ -134,7 +135,10 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form
134 {GL_RG16_SNORM, GL_RG, GL_SHORT, ComponentType::SNorm, false}, // RG16S 135 {GL_RG16_SNORM, GL_RG, GL_SHORT, ComponentType::SNorm, false}, // RG16S
135 {GL_RGB32F, GL_RGB, GL_FLOAT, ComponentType::Float, false}, // RGB32F 136 {GL_RGB32F, GL_RGB, GL_FLOAT, ComponentType::Float, false}, // RGB32F
136 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // SRGBA8 137 {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // SRGBA8
138 {GL_RG8, GL_RG, GL_UNSIGNED_BYTE, ComponentType::UNorm, false}, // RG8U
137 {GL_RG8, GL_RG, GL_BYTE, ComponentType::SNorm, false}, // RG8S 139 {GL_RG8, GL_RG, GL_BYTE, ComponentType::SNorm, false}, // RG8S
140 {GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // RG32UI
141 {GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // R32UI
138 142
139 // DepthStencil formats 143 // DepthStencil formats
140 {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, ComponentType::UNorm, 144 {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, ComponentType::UNorm,
@@ -234,32 +238,59 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, std::vector<u8>& gl_bu
234static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPUVAddr), 238static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPUVAddr),
235 SurfaceParams::MaxPixelFormat> 239 SurfaceParams::MaxPixelFormat>
236 morton_to_gl_fns = { 240 morton_to_gl_fns = {
237 MortonCopy<true, PixelFormat::ABGR8U>, MortonCopy<true, PixelFormat::ABGR8S>, 241 // clang-format off
238 MortonCopy<true, PixelFormat::B5G6R5>, MortonCopy<true, PixelFormat::A2B10G10R10>, 242 MortonCopy<true, PixelFormat::ABGR8U>,
239 MortonCopy<true, PixelFormat::A1B5G5R5>, MortonCopy<true, PixelFormat::R8>, 243 MortonCopy<true, PixelFormat::ABGR8S>,
240 MortonCopy<true, PixelFormat::R8UI>, MortonCopy<true, PixelFormat::RGBA16F>, 244 MortonCopy<true, PixelFormat::B5G6R5>,
241 MortonCopy<true, PixelFormat::R11FG11FB10F>, MortonCopy<true, PixelFormat::RGBA32UI>, 245 MortonCopy<true, PixelFormat::A2B10G10R10>,
242 MortonCopy<true, PixelFormat::DXT1>, MortonCopy<true, PixelFormat::DXT23>, 246 MortonCopy<true, PixelFormat::A1B5G5R5>,
243 MortonCopy<true, PixelFormat::DXT45>, MortonCopy<true, PixelFormat::DXN1>, 247 MortonCopy<true, PixelFormat::R8>,
244 MortonCopy<true, PixelFormat::DXN2UNORM>, MortonCopy<true, PixelFormat::DXN2SNORM>, 248 MortonCopy<true, PixelFormat::R8UI>,
245 MortonCopy<true, PixelFormat::BC7U>, MortonCopy<true, PixelFormat::ASTC_2D_4X4>, 249 MortonCopy<true, PixelFormat::RGBA16F>,
246 MortonCopy<true, PixelFormat::G8R8>, MortonCopy<true, PixelFormat::BGRA8>, 250 MortonCopy<true, PixelFormat::RGBA16UI>,
247 MortonCopy<true, PixelFormat::RGBA32F>, MortonCopy<true, PixelFormat::RG32F>, 251 MortonCopy<true, PixelFormat::R11FG11FB10F>,
248 MortonCopy<true, PixelFormat::R32F>, MortonCopy<true, PixelFormat::R16F>, 252 MortonCopy<true, PixelFormat::RGBA32UI>,
249 MortonCopy<true, PixelFormat::R16UNORM>, MortonCopy<true, PixelFormat::R16S>, 253 MortonCopy<true, PixelFormat::DXT1>,
250 MortonCopy<true, PixelFormat::R16UI>, MortonCopy<true, PixelFormat::R16I>, 254 MortonCopy<true, PixelFormat::DXT23>,
251 MortonCopy<true, PixelFormat::RG16>, MortonCopy<true, PixelFormat::RG16F>, 255 MortonCopy<true, PixelFormat::DXT45>,
252 MortonCopy<true, PixelFormat::RG16UI>, MortonCopy<true, PixelFormat::RG16I>, 256 MortonCopy<true, PixelFormat::DXN1>,
253 MortonCopy<true, PixelFormat::RG16S>, MortonCopy<true, PixelFormat::RGB32F>, 257 MortonCopy<true, PixelFormat::DXN2UNORM>,
254 MortonCopy<true, PixelFormat::SRGBA8>, MortonCopy<true, PixelFormat::RG8S>, 258 MortonCopy<true, PixelFormat::DXN2SNORM>,
255 MortonCopy<true, PixelFormat::Z24S8>, MortonCopy<true, PixelFormat::S8Z24>, 259 MortonCopy<true, PixelFormat::BC7U>,
256 MortonCopy<true, PixelFormat::Z32F>, MortonCopy<true, PixelFormat::Z16>, 260 MortonCopy<true, PixelFormat::ASTC_2D_4X4>,
261 MortonCopy<true, PixelFormat::G8R8>,
262 MortonCopy<true, PixelFormat::BGRA8>,
263 MortonCopy<true, PixelFormat::RGBA32F>,
264 MortonCopy<true, PixelFormat::RG32F>,
265 MortonCopy<true, PixelFormat::R32F>,
266 MortonCopy<true, PixelFormat::R16F>,
267 MortonCopy<true, PixelFormat::R16UNORM>,
268 MortonCopy<true, PixelFormat::R16S>,
269 MortonCopy<true, PixelFormat::R16UI>,
270 MortonCopy<true, PixelFormat::R16I>,
271 MortonCopy<true, PixelFormat::RG16>,
272 MortonCopy<true, PixelFormat::RG16F>,
273 MortonCopy<true, PixelFormat::RG16UI>,
274 MortonCopy<true, PixelFormat::RG16I>,
275 MortonCopy<true, PixelFormat::RG16S>,
276 MortonCopy<true, PixelFormat::RGB32F>,
277 MortonCopy<true, PixelFormat::SRGBA8>,
278 MortonCopy<true, PixelFormat::RG8U>,
279 MortonCopy<true, PixelFormat::RG8S>,
280 MortonCopy<true, PixelFormat::RG32UI>,
281 MortonCopy<true, PixelFormat::R32UI>,
282 MortonCopy<true, PixelFormat::Z24S8>,
283 MortonCopy<true, PixelFormat::S8Z24>,
284 MortonCopy<true, PixelFormat::Z32F>,
285 MortonCopy<true, PixelFormat::Z16>,
257 MortonCopy<true, PixelFormat::Z32FS8>, 286 MortonCopy<true, PixelFormat::Z32FS8>,
287 // clang-format on
258}; 288};
259 289
260static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPUVAddr), 290static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPUVAddr),
261 SurfaceParams::MaxPixelFormat> 291 SurfaceParams::MaxPixelFormat>
262 gl_to_morton_fns = { 292 gl_to_morton_fns = {
293 // clang-format off
263 MortonCopy<false, PixelFormat::ABGR8U>, 294 MortonCopy<false, PixelFormat::ABGR8U>,
264 MortonCopy<false, PixelFormat::ABGR8S>, 295 MortonCopy<false, PixelFormat::ABGR8S>,
265 MortonCopy<false, PixelFormat::B5G6R5>, 296 MortonCopy<false, PixelFormat::B5G6R5>,
@@ -268,6 +299,7 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU
268 MortonCopy<false, PixelFormat::R8>, 299 MortonCopy<false, PixelFormat::R8>,
269 MortonCopy<false, PixelFormat::R8UI>, 300 MortonCopy<false, PixelFormat::R8UI>,
270 MortonCopy<false, PixelFormat::RGBA16F>, 301 MortonCopy<false, PixelFormat::RGBA16F>,
302 MortonCopy<false, PixelFormat::RGBA16UI>,
271 MortonCopy<false, PixelFormat::R11FG11FB10F>, 303 MortonCopy<false, PixelFormat::R11FG11FB10F>,
272 MortonCopy<false, PixelFormat::RGBA32UI>, 304 MortonCopy<false, PixelFormat::RGBA32UI>,
273 // TODO(Subv): Swizzling DXT1/DXT23/DXT45/DXN1/DXN2/BC7U/ASTC_2D_4X4 formats is not 305 // TODO(Subv): Swizzling DXT1/DXT23/DXT45/DXN1/DXN2/BC7U/ASTC_2D_4X4 formats is not
@@ -297,12 +329,16 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU
297 MortonCopy<false, PixelFormat::RG16S>, 329 MortonCopy<false, PixelFormat::RG16S>,
298 MortonCopy<false, PixelFormat::RGB32F>, 330 MortonCopy<false, PixelFormat::RGB32F>,
299 MortonCopy<false, PixelFormat::SRGBA8>, 331 MortonCopy<false, PixelFormat::SRGBA8>,
332 MortonCopy<false, PixelFormat::RG8U>,
300 MortonCopy<false, PixelFormat::RG8S>, 333 MortonCopy<false, PixelFormat::RG8S>,
334 MortonCopy<false, PixelFormat::RG32UI>,
335 MortonCopy<false, PixelFormat::R32UI>,
301 MortonCopy<false, PixelFormat::Z24S8>, 336 MortonCopy<false, PixelFormat::Z24S8>,
302 MortonCopy<false, PixelFormat::S8Z24>, 337 MortonCopy<false, PixelFormat::S8Z24>,
303 MortonCopy<false, PixelFormat::Z32F>, 338 MortonCopy<false, PixelFormat::Z32F>,
304 MortonCopy<false, PixelFormat::Z16>, 339 MortonCopy<false, PixelFormat::Z16>,
305 MortonCopy<false, PixelFormat::Z32FS8>, 340 MortonCopy<false, PixelFormat::Z32FS8>,
341 // clang-format on
306}; 342};
307 343
308// Allocate an uninitialized texture of appropriate size and format for the surface 344// Allocate an uninitialized texture of appropriate size and format for the surface
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index 202257b58..630b40e77 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -31,43 +31,47 @@ struct SurfaceParams {
31 R8 = 5, 31 R8 = 5,
32 R8UI = 6, 32 R8UI = 6,
33 RGBA16F = 7, 33 RGBA16F = 7,
34 R11FG11FB10F = 8, 34 RGBA16UI = 8,
35 RGBA32UI = 9, 35 R11FG11FB10F = 9,
36 DXT1 = 10, 36 RGBA32UI = 10,
37 DXT23 = 11, 37 DXT1 = 11,
38 DXT45 = 12, 38 DXT23 = 12,
39 DXN1 = 13, // This is also known as BC4 39 DXT45 = 13,
40 DXN2UNORM = 14, 40 DXN1 = 14, // This is also known as BC4
41 DXN2SNORM = 15, 41 DXN2UNORM = 15,
42 BC7U = 16, 42 DXN2SNORM = 16,
43 ASTC_2D_4X4 = 17, 43 BC7U = 17,
44 G8R8 = 18, 44 ASTC_2D_4X4 = 18,
45 BGRA8 = 19, 45 G8R8 = 19,
46 RGBA32F = 20, 46 BGRA8 = 20,
47 RG32F = 21, 47 RGBA32F = 21,
48 R32F = 22, 48 RG32F = 22,
49 R16F = 23, 49 R32F = 23,
50 R16UNORM = 24, 50 R16F = 24,
51 R16S = 25, 51 R16UNORM = 25,
52 R16UI = 26, 52 R16S = 26,
53 R16I = 27, 53 R16UI = 27,
54 RG16 = 28, 54 R16I = 28,
55 RG16F = 29, 55 RG16 = 29,
56 RG16UI = 30, 56 RG16F = 30,
57 RG16I = 31, 57 RG16UI = 31,
58 RG16S = 32, 58 RG16I = 32,
59 RGB32F = 33, 59 RG16S = 33,
60 SRGBA8 = 34, 60 RGB32F = 34,
61 RG8S = 35, 61 SRGBA8 = 35,
62 RG8U = 36,
63 RG8S = 37,
64 RG32UI = 38,
65 R32UI = 39,
62 66
63 MaxColorFormat, 67 MaxColorFormat,
64 68
65 // DepthStencil formats 69 // DepthStencil formats
66 Z24S8 = 36, 70 Z24S8 = 40,
67 S8Z24 = 37, 71 S8Z24 = 41,
68 Z32F = 38, 72 Z32F = 42,
69 Z16 = 39, 73 Z16 = 43,
70 Z32FS8 = 40, 74 Z32FS8 = 44,
71 75
72 MaxDepthStencilFormat, 76 MaxDepthStencilFormat,
73 77
@@ -113,6 +117,7 @@ struct SurfaceParams {
113 1, // R8 117 1, // R8
114 1, // R8UI 118 1, // R8UI
115 1, // RGBA16F 119 1, // RGBA16F
120 1, // RGBA16UI
116 1, // R11FG11FB10F 121 1, // R11FG11FB10F
117 1, // RGBA32UI 122 1, // RGBA32UI
118 4, // DXT1 123 4, // DXT1
@@ -140,7 +145,10 @@ struct SurfaceParams {
140 1, // RG16S 145 1, // RG16S
141 1, // RGB32F 146 1, // RGB32F
142 1, // SRGBA8 147 1, // SRGBA8
148 1, // RG8U
143 1, // RG8S 149 1, // RG8S
150 1, // RG32UI
151 1, // R32UI
144 1, // Z24S8 152 1, // Z24S8
145 1, // S8Z24 153 1, // S8Z24
146 1, // Z32F 154 1, // Z32F
@@ -165,6 +173,7 @@ struct SurfaceParams {
165 8, // R8 173 8, // R8
166 8, // R8UI 174 8, // R8UI
167 64, // RGBA16F 175 64, // RGBA16F
176 64, // RGBA16UI
168 32, // R11FG11FB10F 177 32, // R11FG11FB10F
169 128, // RGBA32UI 178 128, // RGBA32UI
170 64, // DXT1 179 64, // DXT1
@@ -192,7 +201,10 @@ struct SurfaceParams {
192 32, // RG16S 201 32, // RG16S
193 96, // RGB32F 202 96, // RGB32F
194 32, // SRGBA8 203 32, // SRGBA8
204 16, // RG8U
195 16, // RG8S 205 16, // RG8S
206 64, // RG32UI
207 32, // R32UI
196 32, // Z24S8 208 32, // Z24S8
197 32, // S8Z24 209 32, // S8Z24
198 32, // Z32F 210 32, // Z32F
@@ -241,6 +253,8 @@ struct SurfaceParams {
241 return PixelFormat::A2B10G10R10; 253 return PixelFormat::A2B10G10R10;
242 case Tegra::RenderTargetFormat::RGBA16_FLOAT: 254 case Tegra::RenderTargetFormat::RGBA16_FLOAT:
243 return PixelFormat::RGBA16F; 255 return PixelFormat::RGBA16F;
256 case Tegra::RenderTargetFormat::RGBA16_UINT:
257 return PixelFormat::RGBA16UI;
244 case Tegra::RenderTargetFormat::RGBA32_FLOAT: 258 case Tegra::RenderTargetFormat::RGBA32_FLOAT:
245 return PixelFormat::RGBA32F; 259 return PixelFormat::RGBA32F;
246 case Tegra::RenderTargetFormat::RG32_FLOAT: 260 case Tegra::RenderTargetFormat::RG32_FLOAT:
@@ -265,6 +279,8 @@ struct SurfaceParams {
265 return PixelFormat::RG16; 279 return PixelFormat::RG16;
266 case Tegra::RenderTargetFormat::RG16_SNORM: 280 case Tegra::RenderTargetFormat::RG16_SNORM:
267 return PixelFormat::RG16S; 281 return PixelFormat::RG16S;
282 case Tegra::RenderTargetFormat::RG8_UNORM:
283 return PixelFormat::RG8U;
268 case Tegra::RenderTargetFormat::RG8_SNORM: 284 case Tegra::RenderTargetFormat::RG8_SNORM:
269 return PixelFormat::RG8S; 285 return PixelFormat::RG8S;
270 case Tegra::RenderTargetFormat::R16_FLOAT: 286 case Tegra::RenderTargetFormat::R16_FLOAT:
@@ -279,6 +295,10 @@ struct SurfaceParams {
279 return PixelFormat::R16I; 295 return PixelFormat::R16I;
280 case Tegra::RenderTargetFormat::R32_FLOAT: 296 case Tegra::RenderTargetFormat::R32_FLOAT:
281 return PixelFormat::R32F; 297 return PixelFormat::R32F;
298 case Tegra::RenderTargetFormat::R32_UINT:
299 return PixelFormat::R32UI;
300 case Tegra::RenderTargetFormat::RG32_UINT:
301 return PixelFormat::RG32UI;
282 default: 302 default:
283 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); 303 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
284 UNREACHABLE(); 304 UNREACHABLE();
@@ -332,7 +352,15 @@ struct SurfaceParams {
332 static_cast<u32>(component_type)); 352 static_cast<u32>(component_type));
333 UNREACHABLE(); 353 UNREACHABLE();
334 case Tegra::Texture::TextureFormat::R32_G32: 354 case Tegra::Texture::TextureFormat::R32_G32:
335 return PixelFormat::RG32F; 355 switch (component_type) {
356 case Tegra::Texture::ComponentType::FLOAT:
357 return PixelFormat::RG32F;
358 case Tegra::Texture::ComponentType::UINT:
359 return PixelFormat::RG32UI;
360 }
361 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
362 static_cast<u32>(component_type));
363 UNREACHABLE();
336 case Tegra::Texture::TextureFormat::R32_G32_B32: 364 case Tegra::Texture::TextureFormat::R32_G32_B32:
337 return PixelFormat::RGB32F; 365 return PixelFormat::RGB32F;
338 case Tegra::Texture::TextureFormat::R16: 366 case Tegra::Texture::TextureFormat::R16:
@@ -352,7 +380,15 @@ struct SurfaceParams {
352 static_cast<u32>(component_type)); 380 static_cast<u32>(component_type));
353 UNREACHABLE(); 381 UNREACHABLE();
354 case Tegra::Texture::TextureFormat::R32: 382 case Tegra::Texture::TextureFormat::R32:
355 return PixelFormat::R32F; 383 switch (component_type) {
384 case Tegra::Texture::ComponentType::FLOAT:
385 return PixelFormat::R32F;
386 case Tegra::Texture::ComponentType::UINT:
387 return PixelFormat::R32UI;
388 }
389 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
390 static_cast<u32>(component_type));
391 UNREACHABLE();
356 case Tegra::Texture::TextureFormat::ZF32: 392 case Tegra::Texture::TextureFormat::ZF32:
357 return PixelFormat::Z32F; 393 return PixelFormat::Z32F;
358 case Tegra::Texture::TextureFormat::Z24S8: 394 case Tegra::Texture::TextureFormat::Z24S8:
@@ -432,6 +468,7 @@ struct SurfaceParams {
432 case Tegra::RenderTargetFormat::RG16_UNORM: 468 case Tegra::RenderTargetFormat::RG16_UNORM:
433 case Tegra::RenderTargetFormat::R16_UNORM: 469 case Tegra::RenderTargetFormat::R16_UNORM:
434 case Tegra::RenderTargetFormat::B5G6R5_UNORM: 470 case Tegra::RenderTargetFormat::B5G6R5_UNORM:
471 case Tegra::RenderTargetFormat::RG8_UNORM:
435 return ComponentType::UNorm; 472 return ComponentType::UNorm;
436 case Tegra::RenderTargetFormat::RGBA8_SNORM: 473 case Tegra::RenderTargetFormat::RGBA8_SNORM:
437 case Tegra::RenderTargetFormat::RG16_SNORM: 474 case Tegra::RenderTargetFormat::RG16_SNORM:
@@ -447,9 +484,12 @@ struct SurfaceParams {
447 case Tegra::RenderTargetFormat::R32_FLOAT: 484 case Tegra::RenderTargetFormat::R32_FLOAT:
448 return ComponentType::Float; 485 return ComponentType::Float;
449 case Tegra::RenderTargetFormat::RGBA32_UINT: 486 case Tegra::RenderTargetFormat::RGBA32_UINT:
487 case Tegra::RenderTargetFormat::RGBA16_UINT:
450 case Tegra::RenderTargetFormat::RG16_UINT: 488 case Tegra::RenderTargetFormat::RG16_UINT:
451 case Tegra::RenderTargetFormat::R8_UINT: 489 case Tegra::RenderTargetFormat::R8_UINT:
452 case Tegra::RenderTargetFormat::R16_UINT: 490 case Tegra::RenderTargetFormat::R16_UINT:
491 case Tegra::RenderTargetFormat::RG32_UINT:
492 case Tegra::RenderTargetFormat::R32_UINT:
453 return ComponentType::UInt; 493 return ComponentType::UInt;
454 case Tegra::RenderTargetFormat::RG16_SINT: 494 case Tegra::RenderTargetFormat::RG16_SINT:
455 case Tegra::RenderTargetFormat::R16_SINT: 495 case Tegra::RenderTargetFormat::R16_SINT:
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h
index 679e5ceb2..83ea0cfc0 100644
--- a/src/video_core/renderer_opengl/maxwell_to_gl.h
+++ b/src/video_core/renderer_opengl/maxwell_to_gl.h
@@ -27,6 +27,7 @@ inline GLenum VertexType(Maxwell::VertexAttribute attrib) {
27 case Maxwell::VertexAttribute::Type::UnsignedNorm: { 27 case Maxwell::VertexAttribute::Type::UnsignedNorm: {
28 28
29 switch (attrib.size) { 29 switch (attrib.size) {
30 case Maxwell::VertexAttribute::Size::Size_8:
30 case Maxwell::VertexAttribute::Size::Size_8_8: 31 case Maxwell::VertexAttribute::Size::Size_8_8:
31 case Maxwell::VertexAttribute::Size::Size_8_8_8_8: 32 case Maxwell::VertexAttribute::Size::Size_8_8_8_8:
32 return GL_UNSIGNED_BYTE; 33 return GL_UNSIGNED_BYTE;