summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/CMakeLists.txt16
-rw-r--r--src/common/fiber.cpp8
-rw-r--r--src/common/fiber.h2
-rw-r--r--src/common/file_util.cpp31
-rw-r--r--src/common/logging/backend.cpp2
-rw-r--r--src/common/string_util.cpp5
-rw-r--r--src/common/timer.cpp12
-rw-r--r--src/common/wall_clock.cpp2
-rw-r--r--src/common/x64/native_clock.h2
-rw-r--r--src/core/hle/service/ldr/ldr.cpp16
-rw-r--r--src/video_core/command_classes/codecs/codec.h6
-rw-r--r--src/video_core/command_classes/codecs/h264.cpp3
-rw-r--r--src/video_core/command_classes/codecs/h264.h10
-rw-r--r--src/video_core/command_classes/codecs/vp9.cpp2
-rw-r--r--src/video_core/command_classes/codecs/vp9.h2
-rw-r--r--src/video_core/command_classes/codecs/vp9_types.h5
-rw-r--r--src/video_core/command_classes/nvdec.h4
-rw-r--r--src/video_core/shader/async_shaders.cpp17
18 files changed, 89 insertions, 56 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index e50ab2922..207c7a0a6 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -190,6 +190,22 @@ if(ARCHITECTURE_x86_64)
190 ) 190 )
191endif() 191endif()
192 192
193if (MSVC)
194 target_compile_definitions(common PRIVATE
195 # The standard library doesn't provide any replacement for codecvt yet
196 # so we can disable this deprecation warning for the time being.
197 _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
198 )
199 target_compile_options(common PRIVATE
200 /W4
201 /WX
202 )
203else()
204 target_compile_options(common PRIVATE
205 -Werror
206 )
207endif()
208
193create_target_directory_groups(common) 209create_target_directory_groups(common)
194find_package(Boost 1.71 COMPONENTS context headers REQUIRED) 210find_package(Boost 1.71 COMPONENTS context headers REQUIRED)
195 211
diff --git a/src/common/fiber.cpp b/src/common/fiber.cpp
index e186ed880..b209f52fc 100644
--- a/src/common/fiber.cpp
+++ b/src/common/fiber.cpp
@@ -79,9 +79,9 @@ void Fiber::Exit() {
79 released = true; 79 released = true;
80} 80}
81 81
82void Fiber::SetRewindPoint(std::function<void(void*)>&& rewind_func, void* start_parameter) { 82void Fiber::SetRewindPoint(std::function<void(void*)>&& rewind_func, void* rewind_param) {
83 rewind_point = std::move(rewind_func); 83 rewind_point = std::move(rewind_func);
84 rewind_parameter = start_parameter; 84 rewind_parameter = rewind_param;
85} 85}
86 86
87void Fiber::Rewind() { 87void Fiber::Rewind() {
@@ -161,9 +161,9 @@ Fiber::Fiber(std::function<void(void*)>&& entry_point_func, void* start_paramete
161 boost::context::detail::make_fcontext(stack_base, impl->stack.size(), FiberStartFunc); 161 boost::context::detail::make_fcontext(stack_base, impl->stack.size(), FiberStartFunc);
162} 162}
163 163
164void Fiber::SetRewindPoint(std::function<void(void*)>&& rewind_func, void* start_parameter) { 164void Fiber::SetRewindPoint(std::function<void(void*)>&& rewind_func, void* rewind_param) {
165 rewind_point = std::move(rewind_func); 165 rewind_point = std::move(rewind_func);
166 rewind_parameter = start_parameter; 166 rewind_parameter = rewind_param;
167} 167}
168 168
169Fiber::Fiber() : impl{std::make_unique<FiberImpl>()} {} 169Fiber::Fiber() : impl{std::make_unique<FiberImpl>()} {}
diff --git a/src/common/fiber.h b/src/common/fiber.h
index cefd61df9..699286ee2 100644
--- a/src/common/fiber.h
+++ b/src/common/fiber.h
@@ -49,7 +49,7 @@ public:
49 static void YieldTo(std::shared_ptr<Fiber> from, std::shared_ptr<Fiber> to); 49 static void YieldTo(std::shared_ptr<Fiber> from, std::shared_ptr<Fiber> to);
50 [[nodiscard]] static std::shared_ptr<Fiber> ThreadToFiber(); 50 [[nodiscard]] static std::shared_ptr<Fiber> ThreadToFiber();
51 51
52 void SetRewindPoint(std::function<void(void*)>&& rewind_func, void* start_parameter); 52 void SetRewindPoint(std::function<void(void*)>&& rewind_func, void* rewind_param);
53 53
54 void Rewind(); 54 void Rewind();
55 55
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp
index 16c3713e0..18fbfa25b 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -472,13 +472,14 @@ u64 ScanDirectoryTree(const std::string& directory, FSTEntry& parent_entry,
472} 472}
473 473
474bool DeleteDirRecursively(const std::string& directory, unsigned int recursion) { 474bool DeleteDirRecursively(const std::string& directory, unsigned int recursion) {
475 const auto callback = [recursion](u64* num_entries_out, const std::string& directory, 475 const auto callback = [recursion](u64*, const std::string& directory,
476 const std::string& virtual_name) -> bool { 476 const std::string& virtual_name) {
477 std::string new_path = directory + DIR_SEP_CHR + virtual_name; 477 const std::string new_path = directory + DIR_SEP_CHR + virtual_name;
478 478
479 if (IsDirectory(new_path)) { 479 if (IsDirectory(new_path)) {
480 if (recursion == 0) 480 if (recursion == 0) {
481 return false; 481 return false;
482 }
482 return DeleteDirRecursively(new_path, recursion - 1); 483 return DeleteDirRecursively(new_path, recursion - 1);
483 } 484 }
484 return Delete(new_path); 485 return Delete(new_path);
@@ -492,7 +493,8 @@ bool DeleteDirRecursively(const std::string& directory, unsigned int recursion)
492 return true; 493 return true;
493} 494}
494 495
495void CopyDir(const std::string& source_path, const std::string& dest_path) { 496void CopyDir([[maybe_unused]] const std::string& source_path,
497 [[maybe_unused]] const std::string& dest_path) {
496#ifndef _WIN32 498#ifndef _WIN32
497 if (source_path == dest_path) { 499 if (source_path == dest_path) {
498 return; 500 return;
@@ -553,7 +555,7 @@ std::optional<std::string> GetCurrentDir() {
553 std::string strDir = dir; 555 std::string strDir = dir;
554#endif 556#endif
555 free(dir); 557 free(dir);
556 return std::move(strDir); 558 return strDir;
557} 559}
558 560
559bool SetCurrentDir(const std::string& directory) { 561bool SetCurrentDir(const std::string& directory) {
@@ -772,21 +774,23 @@ std::size_t ReadFileToString(bool text_file, const std::string& filename, std::s
772 774
773void SplitFilename83(const std::string& filename, std::array<char, 9>& short_name, 775void SplitFilename83(const std::string& filename, std::array<char, 9>& short_name,
774 std::array<char, 4>& extension) { 776 std::array<char, 4>& extension) {
775 const std::string forbidden_characters = ".\"/\\[]:;=, "; 777 static constexpr std::string_view forbidden_characters = ".\"/\\[]:;=, ";
776 778
777 // On a FAT32 partition, 8.3 names are stored as a 11 bytes array, filled with spaces. 779 // On a FAT32 partition, 8.3 names are stored as a 11 bytes array, filled with spaces.
778 short_name = {{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '\0'}}; 780 short_name = {{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '\0'}};
779 extension = {{' ', ' ', ' ', '\0'}}; 781 extension = {{' ', ' ', ' ', '\0'}};
780 782
781 std::string::size_type point = filename.rfind('.'); 783 auto point = filename.rfind('.');
782 if (point == filename.size() - 1) 784 if (point == filename.size() - 1) {
783 point = filename.rfind('.', point); 785 point = filename.rfind('.', point);
786 }
784 787
785 // Get short name. 788 // Get short name.
786 int j = 0; 789 int j = 0;
787 for (char letter : filename.substr(0, point)) { 790 for (char letter : filename.substr(0, point)) {
788 if (forbidden_characters.find(letter, 0) != std::string::npos) 791 if (forbidden_characters.find(letter, 0) != std::string::npos) {
789 continue; 792 continue;
793 }
790 if (j == 8) { 794 if (j == 8) {
791 // TODO(Link Mauve): also do that for filenames containing a space. 795 // TODO(Link Mauve): also do that for filenames containing a space.
792 // TODO(Link Mauve): handle multiple files having the same short name. 796 // TODO(Link Mauve): handle multiple files having the same short name.
@@ -794,14 +798,15 @@ void SplitFilename83(const std::string& filename, std::array<char, 9>& short_nam
794 short_name[7] = '1'; 798 short_name[7] = '1';
795 break; 799 break;
796 } 800 }
797 short_name[j++] = toupper(letter); 801 short_name[j++] = static_cast<char>(std::toupper(letter));
798 } 802 }
799 803
800 // Get extension. 804 // Get extension.
801 if (point != std::string::npos) { 805 if (point != std::string::npos) {
802 j = 0; 806 j = 0;
803 for (char letter : filename.substr(point + 1, 3)) 807 for (char letter : filename.substr(point + 1, 3)) {
804 extension[j++] = toupper(letter); 808 extension[j++] = static_cast<char>(std::toupper(letter));
809 }
805 } 810 }
806} 811}
807 812
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 62cfde397..90dfa22ca 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -274,7 +274,6 @@ const char* GetLogClassName(Class log_class) {
274 case Class::Count: 274 case Class::Count:
275 break; 275 break;
276 } 276 }
277 UNREACHABLE();
278 return "Invalid"; 277 return "Invalid";
279} 278}
280 279
@@ -293,7 +292,6 @@ const char* GetLevelName(Level log_level) {
293 break; 292 break;
294 } 293 }
295#undef LVL 294#undef LVL
296 UNREACHABLE();
297 return "Invalid"; 295 return "Invalid";
298} 296}
299 297
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp
index 84883a1d3..4cba2aaa4 100644
--- a/src/common/string_util.cpp
+++ b/src/common/string_util.cpp
@@ -8,6 +8,7 @@
8#include <cstdlib> 8#include <cstdlib>
9#include <locale> 9#include <locale>
10#include <sstream> 10#include <sstream>
11
11#include "common/common_paths.h" 12#include "common/common_paths.h"
12#include "common/logging/log.h" 13#include "common/logging/log.h"
13#include "common/string_util.h" 14#include "common/string_util.h"
@@ -21,14 +22,14 @@ namespace Common {
21/// Make a string lowercase 22/// Make a string lowercase
22std::string ToLower(std::string str) { 23std::string ToLower(std::string str) {
23 std::transform(str.begin(), str.end(), str.begin(), 24 std::transform(str.begin(), str.end(), str.begin(),
24 [](unsigned char c) { return std::tolower(c); }); 25 [](unsigned char c) { return static_cast<char>(std::tolower(c)); });
25 return str; 26 return str;
26} 27}
27 28
28/// Make a string uppercase 29/// Make a string uppercase
29std::string ToUpper(std::string str) { 30std::string ToUpper(std::string str) {
30 std::transform(str.begin(), str.end(), str.begin(), 31 std::transform(str.begin(), str.end(), str.begin(),
31 [](unsigned char c) { return std::toupper(c); }); 32 [](unsigned char c) { return static_cast<char>(std::toupper(c)); });
32 return str; 33 return str;
33} 34}
34 35
diff --git a/src/common/timer.cpp b/src/common/timer.cpp
index 2dc15e434..d17dc2a50 100644
--- a/src/common/timer.cpp
+++ b/src/common/timer.cpp
@@ -142,20 +142,18 @@ std::string Timer::GetTimeFormatted() {
142// ---------------- 142// ----------------
143double Timer::GetDoubleTime() { 143double Timer::GetDoubleTime() {
144 // Get continuous timestamp 144 // Get continuous timestamp
145 u64 TmpSeconds = static_cast<u64>(Common::Timer::GetTimeSinceJan1970().count()); 145 auto tmp_seconds = static_cast<u64>(GetTimeSinceJan1970().count());
146 double ms = static_cast<u64>(GetTimeMs().count()) % 1000; 146 const auto ms = static_cast<double>(static_cast<u64>(GetTimeMs().count()) % 1000);
147 147
148 // Remove a few years. We only really want enough seconds to make 148 // Remove a few years. We only really want enough seconds to make
149 // sure that we are detecting actual actions, perhaps 60 seconds is 149 // sure that we are detecting actual actions, perhaps 60 seconds is
150 // enough really, but I leave a year of seconds anyway, in case the 150 // enough really, but I leave a year of seconds anyway, in case the
151 // user's clock is incorrect or something like that. 151 // user's clock is incorrect or something like that.
152 TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60); 152 tmp_seconds = tmp_seconds - (38 * 365 * 24 * 60 * 60);
153 153
154 // Make a smaller integer that fits in the double 154 // Make a smaller integer that fits in the double
155 u32 Seconds = static_cast<u32>(TmpSeconds); 155 const auto seconds = static_cast<u32>(tmp_seconds);
156 double TmpTime = Seconds + ms; 156 return seconds + ms;
157
158 return TmpTime;
159} 157}
160 158
161} // Namespace Common 159} // Namespace Common
diff --git a/src/common/wall_clock.cpp b/src/common/wall_clock.cpp
index 7a20e95b7..452a2837e 100644
--- a/src/common/wall_clock.cpp
+++ b/src/common/wall_clock.cpp
@@ -53,7 +53,7 @@ public:
53 return Common::Divide128On32(temporary, 1000000000).first; 53 return Common::Divide128On32(temporary, 1000000000).first;
54 } 54 }
55 55
56 void Pause(bool is_paused) override { 56 void Pause([[maybe_unused]] bool is_paused) override {
57 // Do nothing in this clock type. 57 // Do nothing in this clock type.
58 } 58 }
59 59
diff --git a/src/common/x64/native_clock.h b/src/common/x64/native_clock.h
index 7c503df26..97aab6ac9 100644
--- a/src/common/x64/native_clock.h
+++ b/src/common/x64/native_clock.h
@@ -34,7 +34,7 @@ private:
34 /// value used to reduce the native clocks accuracy as some apss rely on 34 /// value used to reduce the native clocks accuracy as some apss rely on
35 /// undefined behavior where the level of accuracy in the clock shouldn't 35 /// undefined behavior where the level of accuracy in the clock shouldn't
36 /// be higher. 36 /// be higher.
37 static constexpr u64 inaccuracy_mask = ~(0x400 - 1); 37 static constexpr u64 inaccuracy_mask = ~(UINT64_C(0x400) - 1);
38 38
39 SpinLock rtsc_serialize{}; 39 SpinLock rtsc_serialize{};
40 u64 last_measure{}; 40 u64 last_measure{};
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index 9ad5bbf0d..eeaca44b6 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -166,7 +166,7 @@ public:
166 {0, &RelocatableObject::LoadNro, "LoadNro"}, 166 {0, &RelocatableObject::LoadNro, "LoadNro"},
167 {1, &RelocatableObject::UnloadNro, "UnloadNro"}, 167 {1, &RelocatableObject::UnloadNro, "UnloadNro"},
168 {2, &RelocatableObject::LoadNrr, "LoadNrr"}, 168 {2, &RelocatableObject::LoadNrr, "LoadNrr"},
169 {3, nullptr, "UnloadNrr"}, 169 {3, &RelocatableObject::UnloadNrr, "UnloadNrr"},
170 {4, &RelocatableObject::Initialize, "Initialize"}, 170 {4, &RelocatableObject::Initialize, "Initialize"},
171 {10, nullptr, "LoadNrrEx"}, 171 {10, nullptr, "LoadNrrEx"},
172 }; 172 };
@@ -272,6 +272,20 @@ public:
272 rb.Push(RESULT_SUCCESS); 272 rb.Push(RESULT_SUCCESS);
273 } 273 }
274 274
275 void UnloadNrr(Kernel::HLERequestContext& ctx) {
276 IPC::RequestParser rp{ctx};
277 const auto pid = rp.Pop<u64>();
278 const auto nrr_address = rp.Pop<VAddr>();
279
280 LOG_DEBUG(Service_LDR, "called with pid={}, nrr_address={:016X}", pid, nrr_address);
281
282 nrr.erase(nrr_address);
283
284 IPC::ResponseBuilder rb{ctx, 2};
285
286 rb.Push(RESULT_SUCCESS);
287 }
288
275 bool ValidateRegionForMap(Kernel::Memory::PageTable& page_table, VAddr start, 289 bool ValidateRegionForMap(Kernel::Memory::PageTable& page_table, VAddr start,
276 std::size_t size) const { 290 std::size_t size) const {
277 constexpr std::size_t padding_size{4 * Kernel::Memory::PageSize}; 291 constexpr std::size_t padding_size{4 * Kernel::Memory::PageSize};
diff --git a/src/video_core/command_classes/codecs/codec.h b/src/video_core/command_classes/codecs/codec.h
index cb67094f6..5bbe6a332 100644
--- a/src/video_core/command_classes/codecs/codec.h
+++ b/src/video_core/command_classes/codecs/codec.h
@@ -42,11 +42,11 @@ public:
42 void Decode(); 42 void Decode();
43 43
44 /// Returns most recently decoded frame 44 /// Returns most recently decoded frame
45 AVFrame* GetCurrentFrame(); 45 [[nodiscard]] AVFrame* GetCurrentFrame();
46 const AVFrame* GetCurrentFrame() const; 46 [[nodiscard]] const AVFrame* GetCurrentFrame() const;
47 47
48 /// Returns the value of current_codec 48 /// Returns the value of current_codec
49 NvdecCommon::VideoCodec GetCurrentCodec() const; 49 [[nodiscard]] NvdecCommon::VideoCodec GetCurrentCodec() const;
50 50
51private: 51private:
52 bool initialized{}; 52 bool initialized{};
diff --git a/src/video_core/command_classes/codecs/h264.cpp b/src/video_core/command_classes/codecs/h264.cpp
index 549a40f52..33e063e20 100644
--- a/src/video_core/command_classes/codecs/h264.cpp
+++ b/src/video_core/command_classes/codecs/h264.cpp
@@ -43,7 +43,8 @@ H264::H264(GPU& gpu_) : gpu(gpu_) {}
43 43
44H264::~H264() = default; 44H264::~H264() = default;
45 45
46std::vector<u8>& H264::ComposeFrameHeader(NvdecCommon::NvdecRegisters& state, bool is_first_frame) { 46const std::vector<u8>& H264::ComposeFrameHeader(NvdecCommon::NvdecRegisters& state,
47 bool is_first_frame) {
47 H264DecoderContext context{}; 48 H264DecoderContext context{};
48 gpu.MemoryManager().ReadBlock(state.picture_info_offset, &context, sizeof(H264DecoderContext)); 49 gpu.MemoryManager().ReadBlock(state.picture_info_offset, &context, sizeof(H264DecoderContext));
49 50
diff --git a/src/video_core/command_classes/codecs/h264.h b/src/video_core/command_classes/codecs/h264.h
index f2292fd2f..273449495 100644
--- a/src/video_core/command_classes/codecs/h264.h
+++ b/src/video_core/command_classes/codecs/h264.h
@@ -51,14 +51,14 @@ public:
51 void WriteScalingList(const std::vector<u8>& list, s32 start, s32 count); 51 void WriteScalingList(const std::vector<u8>& list, s32 start, s32 count);
52 52
53 /// Return the bitstream as a vector. 53 /// Return the bitstream as a vector.
54 std::vector<u8>& GetByteArray(); 54 [[nodiscard]] std::vector<u8>& GetByteArray();
55 const std::vector<u8>& GetByteArray() const; 55 [[nodiscard]] const std::vector<u8>& GetByteArray() const;
56 56
57private: 57private:
58 void WriteBits(s32 value, s32 bit_count); 58 void WriteBits(s32 value, s32 bit_count);
59 void WriteExpGolombCodedInt(s32 value); 59 void WriteExpGolombCodedInt(s32 value);
60 void WriteExpGolombCodedUInt(u32 value); 60 void WriteExpGolombCodedUInt(u32 value);
61 s32 GetFreeBufferBits(); 61 [[nodiscard]] s32 GetFreeBufferBits();
62 void Flush(); 62 void Flush();
63 63
64 s32 buffer_size{8}; 64 s32 buffer_size{8};
@@ -74,8 +74,8 @@ public:
74 ~H264(); 74 ~H264();
75 75
76 /// Compose the H264 header of the frame for FFmpeg decoding 76 /// Compose the H264 header of the frame for FFmpeg decoding
77 std::vector<u8>& ComposeFrameHeader(NvdecCommon::NvdecRegisters& state, 77 [[nodiscard]] const std::vector<u8>& ComposeFrameHeader(NvdecCommon::NvdecRegisters& state,
78 bool is_first_frame = false); 78 bool is_first_frame = false);
79 79
80private: 80private:
81 struct H264ParameterSet { 81 struct H264ParameterSet {
diff --git a/src/video_core/command_classes/codecs/vp9.cpp b/src/video_core/command_classes/codecs/vp9.cpp
index 42520f856..ab44fdc9e 100644
--- a/src/video_core/command_classes/codecs/vp9.cpp
+++ b/src/video_core/command_classes/codecs/vp9.cpp
@@ -854,7 +854,7 @@ VpxBitStreamWriter VP9::ComposeUncompressedHeader() {
854 return uncomp_writer; 854 return uncomp_writer;
855} 855}
856 856
857std::vector<u8>& VP9::ComposeFrameHeader(NvdecCommon::NvdecRegisters& state) { 857const std::vector<u8>& VP9::ComposeFrameHeader(NvdecCommon::NvdecRegisters& state) {
858 std::vector<u8> bitstream; 858 std::vector<u8> bitstream;
859 { 859 {
860 Vp9FrameContainer curr_frame = GetCurrentFrame(state); 860 Vp9FrameContainer curr_frame = GetCurrentFrame(state);
diff --git a/src/video_core/command_classes/codecs/vp9.h b/src/video_core/command_classes/codecs/vp9.h
index 05c9682fa..e2504512c 100644
--- a/src/video_core/command_classes/codecs/vp9.h
+++ b/src/video_core/command_classes/codecs/vp9.h
@@ -119,7 +119,7 @@ public:
119 119
120 /// Composes the VP9 frame from the GPU state information. Based on the official VP9 spec 120 /// Composes the VP9 frame from the GPU state information. Based on the official VP9 spec
121 /// documentation 121 /// documentation
122 std::vector<u8>& ComposeFrameHeader(NvdecCommon::NvdecRegisters& state); 122 [[nodiscard]] const std::vector<u8>& ComposeFrameHeader(NvdecCommon::NvdecRegisters& state);
123 123
124 /// Returns true if the most recent frame was a hidden frame. 124 /// Returns true if the most recent frame was a hidden frame.
125 [[nodiscard]] bool WasFrameHidden() const { 125 [[nodiscard]] bool WasFrameHidden() const {
diff --git a/src/video_core/command_classes/codecs/vp9_types.h b/src/video_core/command_classes/codecs/vp9_types.h
index a50acf6e8..4f0b05d22 100644
--- a/src/video_core/command_classes/codecs/vp9_types.h
+++ b/src/video_core/command_classes/codecs/vp9_types.h
@@ -231,9 +231,8 @@ struct PictureInfo {
231 u32 surface_params{}; 231 u32 surface_params{};
232 INSERT_PADDING_WORDS(3); 232 INSERT_PADDING_WORDS(3);
233 233
234 Vp9PictureInfo Convert() const { 234 [[nodiscard]] Vp9PictureInfo Convert() const {
235 235 return {
236 return Vp9PictureInfo{
237 .is_key_frame = (vp9_flags & FrameFlags::IsKeyFrame) != 0, 236 .is_key_frame = (vp9_flags & FrameFlags::IsKeyFrame) != 0,
238 .intra_only = (vp9_flags & FrameFlags::IntraOnly) != 0, 237 .intra_only = (vp9_flags & FrameFlags::IntraOnly) != 0,
239 .last_frame_was_key = (vp9_flags & FrameFlags::LastFrameIsKeyFrame) != 0, 238 .last_frame_was_key = (vp9_flags & FrameFlags::LastFrameIsKeyFrame) != 0,
diff --git a/src/video_core/command_classes/nvdec.h b/src/video_core/command_classes/nvdec.h
index af14f9857..eec4443f9 100644
--- a/src/video_core/command_classes/nvdec.h
+++ b/src/video_core/command_classes/nvdec.h
@@ -26,8 +26,8 @@ public:
26 void ProcessMethod(Method method, const std::vector<u32>& arguments); 26 void ProcessMethod(Method method, const std::vector<u32>& arguments);
27 27
28 /// Return most recently decoded frame 28 /// Return most recently decoded frame
29 AVFrame* GetFrame(); 29 [[nodiscard]] AVFrame* GetFrame();
30 const AVFrame* GetFrame() const; 30 [[nodiscard]] const AVFrame* GetFrame() const;
31 31
32private: 32private:
33 /// Invoke codec to decode a frame 33 /// Invoke codec to decode a frame
diff --git a/src/video_core/shader/async_shaders.cpp b/src/video_core/shader/async_shaders.cpp
index aabd62c5c..39cc3b869 100644
--- a/src/video_core/shader/async_shaders.cpp
+++ b/src/video_core/shader/async_shaders.cpp
@@ -20,14 +20,15 @@ AsyncShaders::~AsyncShaders() {
20} 20}
21 21
22void AsyncShaders::AllocateWorkers() { 22void AsyncShaders::AllocateWorkers() {
23 // Max worker threads we should allow 23 // Use at least one thread
24 constexpr u32 MAX_THREADS = 4; 24 u32 num_workers = 1;
25 // Deduce how many threads we can use 25
26 const u32 threads_used = std::thread::hardware_concurrency() / 4; 26 // Deduce how many more threads we can use
27 // Always allow at least 1 thread regardless of our settings 27 const u32 thread_count = std::thread::hardware_concurrency();
28 const auto max_worker_count = std::max(1U, threads_used); 28 if (thread_count >= 8) {
29 // Don't use more than MAX_THREADS 29 // Increase async workers by 1 for every 2 threads >= 8
30 const auto num_workers = std::min(max_worker_count, MAX_THREADS); 30 num_workers += 1 + (thread_count - 8) / 2;
31 }
31 32
32 // If we already have workers queued, ignore 33 // If we already have workers queued, ignore
33 if (num_workers == worker_threads.size()) { 34 if (num_workers == worker_threads.size()) {