diff options
Diffstat (limited to 'src')
34 files changed, 256 insertions, 114 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9d0af02fd..e40e9b0a5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt | |||
| @@ -53,6 +53,7 @@ if (MSVC) | |||
| 53 | else() | 53 | else() |
| 54 | add_compile_options( | 54 | add_compile_options( |
| 55 | -Wall | 55 | -Wall |
| 56 | -Werror=reorder | ||
| 56 | -Wno-attributes | 57 | -Wno-attributes |
| 57 | ) | 58 | ) |
| 58 | 59 | ||
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 66497a386..c15d9f52f 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -591,11 +591,8 @@ target_link_libraries(core PUBLIC common PRIVATE audio_core video_core) | |||
| 591 | target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt json-headers mbedtls opus unicorn) | 591 | target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt json-headers mbedtls opus unicorn) |
| 592 | 592 | ||
| 593 | if (YUZU_ENABLE_BOXCAT) | 593 | if (YUZU_ENABLE_BOXCAT) |
| 594 | get_directory_property(OPENSSL_LIBS | 594 | target_compile_definitions(core PRIVATE -DYUZU_ENABLE_BOXCAT) |
| 595 | DIRECTORY ${PROJECT_SOURCE_DIR}/externals/libressl | 595 | target_link_libraries(core PRIVATE httplib json-headers zip) |
| 596 | DEFINITION OPENSSL_LIBS) | ||
| 597 | target_compile_definitions(core PRIVATE -DCPPHTTPLIB_OPENSSL_SUPPORT -DYUZU_ENABLE_BOXCAT) | ||
| 598 | target_link_libraries(core PRIVATE httplib json-headers ${OPENSSL_LIBS} zip) | ||
| 599 | endif() | 596 | endif() |
| 600 | 597 | ||
| 601 | if (ENABLE_WEB_SERVICE) | 598 | if (ENABLE_WEB_SERVICE) |
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index e226e9711..e77e82b8d 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp | |||
| @@ -348,6 +348,12 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t | |||
| 348 | if (ext_dir != nullptr) | 348 | if (ext_dir != nullptr) |
| 349 | layers_ext.push_back(std::move(ext_dir)); | 349 | layers_ext.push_back(std::move(ext_dir)); |
| 350 | } | 350 | } |
| 351 | |||
| 352 | // When there are no layers to apply, return early as there is no need to rebuild the RomFS | ||
| 353 | if (layers.empty() && layers_ext.empty()) { | ||
| 354 | return; | ||
| 355 | } | ||
| 356 | |||
| 351 | layers.push_back(std::move(extracted)); | 357 | layers.push_back(std::move(extracted)); |
| 352 | 358 | ||
| 353 | auto layered = LayeredVfsDirectory::MakeLayeredDirectory(std::move(layers)); | 359 | auto layered = LayeredVfsDirectory::MakeLayeredDirectory(std::move(layers)); |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index e47f1deed..014d647cf 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -103,7 +103,7 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] s64 cycles_ | |||
| 103 | 103 | ||
| 104 | struct KernelCore::Impl { | 104 | struct KernelCore::Impl { |
| 105 | explicit Impl(Core::System& system, KernelCore& kernel) | 105 | explicit Impl(Core::System& system, KernelCore& kernel) |
| 106 | : system{system}, global_scheduler{kernel}, synchronization{system}, time_manager{system} {} | 106 | : global_scheduler{kernel}, synchronization{system}, time_manager{system}, system{system} {} |
| 107 | 107 | ||
| 108 | void Initialize(KernelCore& kernel) { | 108 | void Initialize(KernelCore& kernel) { |
| 109 | Shutdown(); | 109 | Shutdown(); |
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index 6aadb3ea8..7938b4b80 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp | |||
| @@ -27,7 +27,7 @@ public: | |||
| 27 | {10110, nullptr, "GetFriendProfileImage"}, | 27 | {10110, nullptr, "GetFriendProfileImage"}, |
| 28 | {10200, nullptr, "SendFriendRequestForApplication"}, | 28 | {10200, nullptr, "SendFriendRequestForApplication"}, |
| 29 | {10211, nullptr, "AddFacedFriendRequestForApplication"}, | 29 | {10211, nullptr, "AddFacedFriendRequestForApplication"}, |
| 30 | {10400, nullptr, "GetBlockedUserListIds"}, | 30 | {10400, &IFriendService::GetBlockedUserListIds, "GetBlockedUserListIds"}, |
| 31 | {10500, nullptr, "GetProfileList"}, | 31 | {10500, nullptr, "GetProfileList"}, |
| 32 | {10600, nullptr, "DeclareOpenOnlinePlaySession"}, | 32 | {10600, nullptr, "DeclareOpenOnlinePlaySession"}, |
| 33 | {10601, &IFriendService::DeclareCloseOnlinePlaySession, "DeclareCloseOnlinePlaySession"}, | 33 | {10601, &IFriendService::DeclareCloseOnlinePlaySession, "DeclareCloseOnlinePlaySession"}, |
| @@ -121,6 +121,15 @@ private: | |||
| 121 | }; | 121 | }; |
| 122 | static_assert(sizeof(SizedFriendFilter) == 0x10, "SizedFriendFilter is an invalid size"); | 122 | static_assert(sizeof(SizedFriendFilter) == 0x10, "SizedFriendFilter is an invalid size"); |
| 123 | 123 | ||
| 124 | void GetBlockedUserListIds(Kernel::HLERequestContext& ctx) { | ||
| 125 | // This is safe to stub, as there should be no adverse consequences from reporting no | ||
| 126 | // blocked users. | ||
| 127 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | ||
| 128 | IPC::ResponseBuilder rb{ctx, 3}; | ||
| 129 | rb.Push(RESULT_SUCCESS); | ||
| 130 | rb.Push<u32>(0); // Indicates there are no blocked users | ||
| 131 | } | ||
| 132 | |||
| 124 | void DeclareCloseOnlinePlaySession(Kernel::HLERequestContext& ctx) { | 133 | void DeclareCloseOnlinePlaySession(Kernel::HLERequestContext& ctx) { |
| 125 | // Stub used by Splatoon 2 | 134 | // Stub used by Splatoon 2 |
| 126 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | 135 | LOG_WARNING(Service_ACC, "(STUBBED) called"); |
diff --git a/src/core/hle/service/time/interface.cpp b/src/core/hle/service/time/interface.cpp index f509653a3..ba8fd6152 100644 --- a/src/core/hle/service/time/interface.cpp +++ b/src/core/hle/service/time/interface.cpp | |||
| @@ -29,7 +29,7 @@ Time::Time(std::shared_ptr<Module> module, Core::System& system, const char* nam | |||
| 29 | {300, &Time::CalculateMonotonicSystemClockBaseTimePoint, "CalculateMonotonicSystemClockBaseTimePoint"}, | 29 | {300, &Time::CalculateMonotonicSystemClockBaseTimePoint, "CalculateMonotonicSystemClockBaseTimePoint"}, |
| 30 | {400, &Time::GetClockSnapshot, "GetClockSnapshot"}, | 30 | {400, &Time::GetClockSnapshot, "GetClockSnapshot"}, |
| 31 | {401, &Time::GetClockSnapshotFromSystemClockContext, "GetClockSnapshotFromSystemClockContext"}, | 31 | {401, &Time::GetClockSnapshotFromSystemClockContext, "GetClockSnapshotFromSystemClockContext"}, |
| 32 | {500, nullptr, "CalculateStandardUserSystemClockDifferenceByUser"}, | 32 | {500, &Time::CalculateStandardUserSystemClockDifferenceByUser, "CalculateStandardUserSystemClockDifferenceByUser"}, |
| 33 | {501, &Time::CalculateSpanBetween, "CalculateSpanBetween"}, | 33 | {501, &Time::CalculateSpanBetween, "CalculateSpanBetween"}, |
| 34 | }; | 34 | }; |
| 35 | // clang-format on | 35 | // clang-format on |
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index ce859f18d..e722886de 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp | |||
| @@ -308,6 +308,29 @@ void Module::Interface::GetClockSnapshotFromSystemClockContext(Kernel::HLEReques | |||
| 308 | ctx.WriteBuffer(&clock_snapshot, sizeof(Clock::ClockSnapshot)); | 308 | ctx.WriteBuffer(&clock_snapshot, sizeof(Clock::ClockSnapshot)); |
| 309 | } | 309 | } |
| 310 | 310 | ||
| 311 | void Module::Interface::CalculateStandardUserSystemClockDifferenceByUser( | ||
| 312 | Kernel::HLERequestContext& ctx) { | ||
| 313 | LOG_DEBUG(Service_Time, "called"); | ||
| 314 | |||
| 315 | IPC::RequestParser rp{ctx}; | ||
| 316 | const auto snapshot_a = rp.PopRaw<Clock::ClockSnapshot>(); | ||
| 317 | const auto snapshot_b = rp.PopRaw<Clock::ClockSnapshot>(); | ||
| 318 | |||
| 319 | auto time_span_type{Clock::TimeSpanType::FromSeconds(snapshot_b.user_context.offset - | ||
| 320 | snapshot_a.user_context.offset)}; | ||
| 321 | |||
| 322 | if ((snapshot_b.user_context.steady_time_point.clock_source_id != | ||
| 323 | snapshot_a.user_context.steady_time_point.clock_source_id) || | ||
| 324 | (snapshot_b.is_automatic_correction_enabled && | ||
| 325 | snapshot_a.is_automatic_correction_enabled)) { | ||
| 326 | time_span_type.nanoseconds = 0; | ||
| 327 | } | ||
| 328 | |||
| 329 | IPC::ResponseBuilder rb{ctx, (sizeof(s64) / 4) + 2}; | ||
| 330 | rb.Push(RESULT_SUCCESS); | ||
| 331 | rb.PushRaw(time_span_type.nanoseconds); | ||
| 332 | } | ||
| 333 | |||
| 311 | void Module::Interface::CalculateSpanBetween(Kernel::HLERequestContext& ctx) { | 334 | void Module::Interface::CalculateSpanBetween(Kernel::HLERequestContext& ctx) { |
| 312 | LOG_DEBUG(Service_Time, "called"); | 335 | LOG_DEBUG(Service_Time, "called"); |
| 313 | 336 | ||
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h index 351988468..41f3002e9 100644 --- a/src/core/hle/service/time/time.h +++ b/src/core/hle/service/time/time.h | |||
| @@ -32,6 +32,7 @@ public: | |||
| 32 | void CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERequestContext& ctx); | 32 | void CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERequestContext& ctx); |
| 33 | void GetClockSnapshot(Kernel::HLERequestContext& ctx); | 33 | void GetClockSnapshot(Kernel::HLERequestContext& ctx); |
| 34 | void GetClockSnapshotFromSystemClockContext(Kernel::HLERequestContext& ctx); | 34 | void GetClockSnapshotFromSystemClockContext(Kernel::HLERequestContext& ctx); |
| 35 | void CalculateStandardUserSystemClockDifferenceByUser(Kernel::HLERequestContext& ctx); | ||
| 35 | void CalculateSpanBetween(Kernel::HLERequestContext& ctx); | 36 | void CalculateSpanBetween(Kernel::HLERequestContext& ctx); |
| 36 | void GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx); | 37 | void GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx); |
| 37 | 38 | ||
diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt index 2520ba321..a9c2392b1 100644 --- a/src/input_common/CMakeLists.txt +++ b/src/input_common/CMakeLists.txt | |||
| @@ -27,4 +27,4 @@ if(SDL2_FOUND) | |||
| 27 | endif() | 27 | endif() |
| 28 | 28 | ||
| 29 | create_target_directory_groups(input_common) | 29 | create_target_directory_groups(input_common) |
| 30 | target_link_libraries(input_common PUBLIC core PRIVATE common ${Boost_LIBRARIES}) | 30 | target_link_libraries(input_common PUBLIC core PRIVATE common Boost::boost) |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 2977a7d81..5cf6a4cc3 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -303,6 +303,10 @@ public: | |||
| 303 | return (type == Type::SignedNorm) || (type == Type::UnsignedNorm); | 303 | return (type == Type::SignedNorm) || (type == Type::UnsignedNorm); |
| 304 | } | 304 | } |
| 305 | 305 | ||
| 306 | bool IsConstant() const { | ||
| 307 | return constant; | ||
| 308 | } | ||
| 309 | |||
| 306 | bool IsValid() const { | 310 | bool IsValid() const { |
| 307 | return size != Size::Invalid; | 311 | return size != Size::Invalid; |
| 308 | } | 312 | } |
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h index c66c66f6c..5e9cfba22 100644 --- a/src/video_core/engines/shader_bytecode.h +++ b/src/video_core/engines/shader_bytecode.h | |||
| @@ -1006,6 +1006,12 @@ union Instruction { | |||
| 1006 | } stg; | 1006 | } stg; |
| 1007 | 1007 | ||
| 1008 | union { | 1008 | union { |
| 1009 | BitField<23, 3, AtomicOp> operation; | ||
| 1010 | BitField<48, 1, u64> extended; | ||
| 1011 | BitField<20, 3, GlobalAtomicType> type; | ||
| 1012 | } red; | ||
| 1013 | |||
| 1014 | union { | ||
| 1009 | BitField<52, 4, AtomicOp> operation; | 1015 | BitField<52, 4, AtomicOp> operation; |
| 1010 | BitField<49, 3, GlobalAtomicType> type; | 1016 | BitField<49, 3, GlobalAtomicType> type; |
| 1011 | BitField<28, 20, s64> offset; | 1017 | BitField<28, 20, s64> offset; |
| @@ -1787,6 +1793,7 @@ public: | |||
| 1787 | ST_S, | 1793 | ST_S, |
| 1788 | ST, // Store in generic memory | 1794 | ST, // Store in generic memory |
| 1789 | STG, // Store in global memory | 1795 | STG, // Store in global memory |
| 1796 | RED, // Reduction operation | ||
| 1790 | ATOM, // Atomic operation on global memory | 1797 | ATOM, // Atomic operation on global memory |
| 1791 | ATOMS, // Atomic operation on shared memory | 1798 | ATOMS, // Atomic operation on shared memory |
| 1792 | AL2P, // Transforms attribute memory into physical memory | 1799 | AL2P, // Transforms attribute memory into physical memory |
| @@ -1871,7 +1878,8 @@ public: | |||
| 1871 | ICMP_R, | 1878 | ICMP_R, |
| 1872 | ICMP_CR, | 1879 | ICMP_CR, |
| 1873 | ICMP_IMM, | 1880 | ICMP_IMM, |
| 1874 | FCMP_R, | 1881 | FCMP_RR, |
| 1882 | FCMP_RC, | ||
| 1875 | MUFU, // Multi-Function Operator | 1883 | MUFU, // Multi-Function Operator |
| 1876 | RRO_C, // Range Reduction Operator | 1884 | RRO_C, // Range Reduction Operator |
| 1877 | RRO_R, | 1885 | RRO_R, |
| @@ -2096,6 +2104,7 @@ private: | |||
| 2096 | INST("1110111101010---", Id::ST_L, Type::Memory, "ST_L"), | 2104 | INST("1110111101010---", Id::ST_L, Type::Memory, "ST_L"), |
| 2097 | INST("101-------------", Id::ST, Type::Memory, "ST"), | 2105 | INST("101-------------", Id::ST, Type::Memory, "ST"), |
| 2098 | INST("1110111011011---", Id::STG, Type::Memory, "STG"), | 2106 | INST("1110111011011---", Id::STG, Type::Memory, "STG"), |
| 2107 | INST("1110101111111---", Id::RED, Type::Memory, "RED"), | ||
| 2099 | INST("11101101--------", Id::ATOM, Type::Memory, "ATOM"), | 2108 | INST("11101101--------", Id::ATOM, Type::Memory, "ATOM"), |
| 2100 | INST("11101100--------", Id::ATOMS, Type::Memory, "ATOMS"), | 2109 | INST("11101100--------", Id::ATOMS, Type::Memory, "ATOMS"), |
| 2101 | INST("1110111110100---", Id::AL2P, Type::Memory, "AL2P"), | 2110 | INST("1110111110100---", Id::AL2P, Type::Memory, "AL2P"), |
| @@ -2179,7 +2188,8 @@ private: | |||
| 2179 | INST("0101110100100---", Id::HSETP2_R, Type::HalfSetPredicate, "HSETP2_R"), | 2188 | INST("0101110100100---", Id::HSETP2_R, Type::HalfSetPredicate, "HSETP2_R"), |
| 2180 | INST("0111111-0-------", Id::HSETP2_IMM, Type::HalfSetPredicate, "HSETP2_IMM"), | 2189 | INST("0111111-0-------", Id::HSETP2_IMM, Type::HalfSetPredicate, "HSETP2_IMM"), |
| 2181 | INST("0101110100011---", Id::HSET2_R, Type::HalfSet, "HSET2_R"), | 2190 | INST("0101110100011---", Id::HSET2_R, Type::HalfSet, "HSET2_R"), |
| 2182 | INST("010110111010----", Id::FCMP_R, Type::Arithmetic, "FCMP_R"), | 2191 | INST("010110111010----", Id::FCMP_RR, Type::Arithmetic, "FCMP_RR"), |
| 2192 | INST("010010111010----", Id::FCMP_RC, Type::Arithmetic, "FCMP_RC"), | ||
| 2183 | INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"), | 2193 | INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"), |
| 2184 | INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"), | 2194 | INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"), |
| 2185 | INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"), | 2195 | INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"), |
diff --git a/src/video_core/gpu_asynch.cpp b/src/video_core/gpu_asynch.cpp index cc434faf7..20e73a37e 100644 --- a/src/video_core/gpu_asynch.cpp +++ b/src/video_core/gpu_asynch.cpp | |||
| @@ -12,8 +12,9 @@ namespace VideoCommon { | |||
| 12 | 12 | ||
| 13 | GPUAsynch::GPUAsynch(Core::System& system, std::unique_ptr<VideoCore::RendererBase>&& renderer_, | 13 | GPUAsynch::GPUAsynch(Core::System& system, std::unique_ptr<VideoCore::RendererBase>&& renderer_, |
| 14 | std::unique_ptr<Core::Frontend::GraphicsContext>&& context) | 14 | std::unique_ptr<Core::Frontend::GraphicsContext>&& context) |
| 15 | : GPU(system, std::move(renderer_), true), gpu_thread{system}, gpu_context(std::move(context)), | 15 | : GPU(system, std::move(renderer_), true), gpu_thread{system}, |
| 16 | cpu_context(renderer->GetRenderWindow().CreateSharedContext()) {} | 16 | cpu_context(renderer->GetRenderWindow().CreateSharedContext()), |
| 17 | gpu_context(std::move(context)) {} | ||
| 17 | 18 | ||
| 18 | GPUAsynch::~GPUAsynch() = default; | 19 | GPUAsynch::~GPUAsynch() = default; |
| 19 | 20 | ||
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp index c286502ba..d83dca25a 100644 --- a/src/video_core/renderer_opengl/gl_device.cpp +++ b/src/video_core/renderer_opengl/gl_device.cpp | |||
| @@ -87,7 +87,7 @@ u32 Extract(u32& base, u32& num, u32 amount, std::optional<GLenum> limit = {}) { | |||
| 87 | std::array<Device::BaseBindings, Tegra::Engines::MaxShaderTypes> BuildBaseBindings() noexcept { | 87 | std::array<Device::BaseBindings, Tegra::Engines::MaxShaderTypes> BuildBaseBindings() noexcept { |
| 88 | std::array<Device::BaseBindings, Tegra::Engines::MaxShaderTypes> bindings; | 88 | std::array<Device::BaseBindings, Tegra::Engines::MaxShaderTypes> bindings; |
| 89 | 89 | ||
| 90 | static std::array<std::size_t, 5> stage_swizzle = {0, 1, 2, 3, 4}; | 90 | static constexpr std::array<std::size_t, 5> stage_swizzle{0, 1, 2, 3, 4}; |
| 91 | const u32 total_ubos = GetInteger<u32>(GL_MAX_UNIFORM_BUFFER_BINDINGS); | 91 | const u32 total_ubos = GetInteger<u32>(GL_MAX_UNIFORM_BUFFER_BINDINGS); |
| 92 | const u32 total_ssbos = GetInteger<u32>(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS); | 92 | const u32 total_ssbos = GetInteger<u32>(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS); |
| 93 | const u32 total_samplers = GetInteger<u32>(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS); | 93 | const u32 total_samplers = GetInteger<u32>(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 91abeb9d7..175374f0d 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -140,8 +140,8 @@ void RasterizerOpenGL::SetupVertexFormat() { | |||
| 140 | const auto attrib = gpu.regs.vertex_attrib_format[index]; | 140 | const auto attrib = gpu.regs.vertex_attrib_format[index]; |
| 141 | const auto gl_index = static_cast<GLuint>(index); | 141 | const auto gl_index = static_cast<GLuint>(index); |
| 142 | 142 | ||
| 143 | // Ignore invalid attributes. | 143 | // Disable constant attributes. |
| 144 | if (!attrib.IsValid()) { | 144 | if (attrib.IsConstant()) { |
| 145 | glDisableVertexAttribArray(gl_index); | 145 | glDisableVertexAttribArray(gl_index); |
| 146 | continue; | 146 | continue; |
| 147 | } | 147 | } |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 6d2ff20f9..12c6dcfde 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -34,6 +34,8 @@ | |||
| 34 | namespace OpenGL { | 34 | namespace OpenGL { |
| 35 | 35 | ||
| 36 | using Tegra::Engines::ShaderType; | 36 | using Tegra::Engines::ShaderType; |
| 37 | using VideoCommon::Shader::CompileDepth; | ||
| 38 | using VideoCommon::Shader::CompilerSettings; | ||
| 37 | using VideoCommon::Shader::ProgramCode; | 39 | using VideoCommon::Shader::ProgramCode; |
| 38 | using VideoCommon::Shader::Registry; | 40 | using VideoCommon::Shader::Registry; |
| 39 | using VideoCommon::Shader::ShaderIR; | 41 | using VideoCommon::Shader::ShaderIR; |
| @@ -43,7 +45,7 @@ namespace { | |||
| 43 | constexpr u32 STAGE_MAIN_OFFSET = 10; | 45 | constexpr u32 STAGE_MAIN_OFFSET = 10; |
| 44 | constexpr u32 KERNEL_MAIN_OFFSET = 0; | 46 | constexpr u32 KERNEL_MAIN_OFFSET = 0; |
| 45 | 47 | ||
| 46 | constexpr VideoCommon::Shader::CompilerSettings COMPILER_SETTINGS{}; | 48 | constexpr CompilerSettings COMPILER_SETTINGS{CompileDepth::FullDecompile}; |
| 47 | 49 | ||
| 48 | /// Gets the address for the specified shader stage program | 50 | /// Gets the address for the specified shader stage program |
| 49 | GPUVAddr GetShaderAddress(Core::System& system, Maxwell::ShaderProgram program) { | 51 | GPUVAddr GetShaderAddress(Core::System& system, Maxwell::ShaderProgram program) { |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 1f1f01313..b1804e9ea 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -1821,13 +1821,15 @@ private: | |||
| 1821 | Expression HMergeH0(Operation operation) { | 1821 | Expression HMergeH0(Operation operation) { |
| 1822 | const std::string dest = VisitOperand(operation, 0).AsUint(); | 1822 | const std::string dest = VisitOperand(operation, 0).AsUint(); |
| 1823 | const std::string src = VisitOperand(operation, 1).AsUint(); | 1823 | const std::string src = VisitOperand(operation, 1).AsUint(); |
| 1824 | return {fmt::format("bitfieldInsert({}, {}, 0, 16)", dest, src), Type::Uint}; | 1824 | return {fmt::format("vec2(unpackHalf2x16({}).x, unpackHalf2x16({}).y)", src, dest), |
| 1825 | Type::HalfFloat}; | ||
| 1825 | } | 1826 | } |
| 1826 | 1827 | ||
| 1827 | Expression HMergeH1(Operation operation) { | 1828 | Expression HMergeH1(Operation operation) { |
| 1828 | const std::string dest = VisitOperand(operation, 0).AsUint(); | 1829 | const std::string dest = VisitOperand(operation, 0).AsUint(); |
| 1829 | const std::string src = VisitOperand(operation, 1).AsUint(); | 1830 | const std::string src = VisitOperand(operation, 1).AsUint(); |
| 1830 | return {fmt::format("bitfieldInsert({}, {}, 16, 16)", dest, src), Type::Uint}; | 1831 | return {fmt::format("vec2(unpackHalf2x16({}).x, unpackHalf2x16({}).y)", dest, src), |
| 1832 | Type::HalfFloat}; | ||
| 1831 | } | 1833 | } |
| 1832 | 1834 | ||
| 1833 | Expression HPack2(Operation operation) { | 1835 | Expression HPack2(Operation operation) { |
| @@ -2117,8 +2119,14 @@ private: | |||
| 2117 | return {}; | 2119 | return {}; |
| 2118 | } | 2120 | } |
| 2119 | return {fmt::format("atomic{}({}, {})", opname, Visit(operation[0]).GetCode(), | 2121 | return {fmt::format("atomic{}({}, {})", opname, Visit(operation[0]).GetCode(), |
| 2120 | Visit(operation[1]).As(type)), | 2122 | Visit(operation[1]).AsUint()), |
| 2121 | type}; | 2123 | Type::Uint}; |
| 2124 | } | ||
| 2125 | |||
| 2126 | template <const std::string_view& opname, Type type> | ||
| 2127 | Expression Reduce(Operation operation) { | ||
| 2128 | code.AddLine("{};", Atomic<opname, type>(operation).GetCode()); | ||
| 2129 | return {}; | ||
| 2122 | } | 2130 | } |
| 2123 | 2131 | ||
| 2124 | Expression Branch(Operation operation) { | 2132 | Expression Branch(Operation operation) { |
| @@ -2477,6 +2485,20 @@ private: | |||
| 2477 | &GLSLDecompiler::Atomic<Func::Or, Type::Int>, | 2485 | &GLSLDecompiler::Atomic<Func::Or, Type::Int>, |
| 2478 | &GLSLDecompiler::Atomic<Func::Xor, Type::Int>, | 2486 | &GLSLDecompiler::Atomic<Func::Xor, Type::Int>, |
| 2479 | 2487 | ||
| 2488 | &GLSLDecompiler::Reduce<Func::Add, Type::Uint>, | ||
| 2489 | &GLSLDecompiler::Reduce<Func::Min, Type::Uint>, | ||
| 2490 | &GLSLDecompiler::Reduce<Func::Max, Type::Uint>, | ||
| 2491 | &GLSLDecompiler::Reduce<Func::And, Type::Uint>, | ||
| 2492 | &GLSLDecompiler::Reduce<Func::Or, Type::Uint>, | ||
| 2493 | &GLSLDecompiler::Reduce<Func::Xor, Type::Uint>, | ||
| 2494 | |||
| 2495 | &GLSLDecompiler::Reduce<Func::Add, Type::Int>, | ||
| 2496 | &GLSLDecompiler::Reduce<Func::Min, Type::Int>, | ||
| 2497 | &GLSLDecompiler::Reduce<Func::Max, Type::Int>, | ||
| 2498 | &GLSLDecompiler::Reduce<Func::And, Type::Int>, | ||
| 2499 | &GLSLDecompiler::Reduce<Func::Or, Type::Int>, | ||
| 2500 | &GLSLDecompiler::Reduce<Func::Xor, Type::Int>, | ||
| 2501 | |||
| 2480 | &GLSLDecompiler::Branch, | 2502 | &GLSLDecompiler::Branch, |
| 2481 | &GLSLDecompiler::BranchIndirect, | 2503 | &GLSLDecompiler::BranchIndirect, |
| 2482 | &GLSLDecompiler::PushFlowStack, | 2504 | &GLSLDecompiler::PushFlowStack, |
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 0b4d999d7..2729d1265 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp | |||
| @@ -417,7 +417,7 @@ void CachedSurfaceView::Attach(GLenum attachment, GLenum target) const { | |||
| 417 | 417 | ||
| 418 | switch (params.target) { | 418 | switch (params.target) { |
| 419 | case SurfaceTarget::Texture2DArray: | 419 | case SurfaceTarget::Texture2DArray: |
| 420 | glFramebufferTexture(target, attachment, GetTexture(), params.base_level); | 420 | glFramebufferTexture(target, attachment, GetTexture(), 0); |
| 421 | break; | 421 | break; |
| 422 | default: | 422 | default: |
| 423 | UNIMPLEMENTED(); | 423 | UNIMPLEMENTED(); |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index f1a28cc21..b2a179746 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -315,8 +315,8 @@ public: | |||
| 315 | 315 | ||
| 316 | RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system, | 316 | RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system, |
| 317 | Core::Frontend::GraphicsContext& context) | 317 | Core::Frontend::GraphicsContext& context) |
| 318 | : VideoCore::RendererBase{emu_window}, emu_window{emu_window}, system{system}, | 318 | : RendererBase{emu_window}, emu_window{emu_window}, system{system}, context{context}, |
| 319 | frame_mailbox{}, context{context}, has_debug_tool{HasDebugTool()} {} | 319 | has_debug_tool{HasDebugTool()} {} |
| 320 | 320 | ||
| 321 | RendererOpenGL::~RendererOpenGL() = default; | 321 | RendererOpenGL::~RendererOpenGL() = default; |
| 322 | 322 | ||
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index 143478863..8681b821f 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp | |||
| @@ -360,6 +360,7 @@ VkFormat VertexFormat(Maxwell::VertexAttribute::Type type, Maxwell::VertexAttrib | |||
| 360 | default: | 360 | default: |
| 361 | break; | 361 | break; |
| 362 | } | 362 | } |
| 363 | break; | ||
| 363 | case Maxwell::VertexAttribute::Type::UnsignedInt: | 364 | case Maxwell::VertexAttribute::Type::UnsignedInt: |
| 364 | switch (size) { | 365 | switch (size) { |
| 365 | case Maxwell::VertexAttribute::Size::Size_8: | 366 | case Maxwell::VertexAttribute::Size::Size_8: |
| @@ -370,6 +371,14 @@ VkFormat VertexFormat(Maxwell::VertexAttribute::Type type, Maxwell::VertexAttrib | |||
| 370 | return VK_FORMAT_R8G8B8_UINT; | 371 | return VK_FORMAT_R8G8B8_UINT; |
| 371 | case Maxwell::VertexAttribute::Size::Size_8_8_8_8: | 372 | case Maxwell::VertexAttribute::Size::Size_8_8_8_8: |
| 372 | return VK_FORMAT_R8G8B8A8_UINT; | 373 | return VK_FORMAT_R8G8B8A8_UINT; |
| 374 | case Maxwell::VertexAttribute::Size::Size_16: | ||
| 375 | return VK_FORMAT_R16_UINT; | ||
| 376 | case Maxwell::VertexAttribute::Size::Size_16_16: | ||
| 377 | return VK_FORMAT_R16G16_UINT; | ||
| 378 | case Maxwell::VertexAttribute::Size::Size_16_16_16: | ||
| 379 | return VK_FORMAT_R16G16B16_UINT; | ||
| 380 | case Maxwell::VertexAttribute::Size::Size_16_16_16_16: | ||
| 381 | return VK_FORMAT_R16G16B16A16_UINT; | ||
| 373 | case Maxwell::VertexAttribute::Size::Size_32: | 382 | case Maxwell::VertexAttribute::Size::Size_32: |
| 374 | return VK_FORMAT_R32_UINT; | 383 | return VK_FORMAT_R32_UINT; |
| 375 | case Maxwell::VertexAttribute::Size::Size_32_32: | 384 | case Maxwell::VertexAttribute::Size::Size_32_32: |
| @@ -381,6 +390,7 @@ VkFormat VertexFormat(Maxwell::VertexAttribute::Type type, Maxwell::VertexAttrib | |||
| 381 | default: | 390 | default: |
| 382 | break; | 391 | break; |
| 383 | } | 392 | } |
| 393 | break; | ||
| 384 | case Maxwell::VertexAttribute::Type::UnsignedScaled: | 394 | case Maxwell::VertexAttribute::Type::UnsignedScaled: |
| 385 | switch (size) { | 395 | switch (size) { |
| 386 | case Maxwell::VertexAttribute::Size::Size_8: | 396 | case Maxwell::VertexAttribute::Size::Size_8: |
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp index 21644a7e7..fbd406f2b 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp | |||
| @@ -535,7 +535,9 @@ void VKBlitScreen::CreateGraphicsPipeline() { | |||
| 535 | viewport_state_ci.pNext = nullptr; | 535 | viewport_state_ci.pNext = nullptr; |
| 536 | viewport_state_ci.flags = 0; | 536 | viewport_state_ci.flags = 0; |
| 537 | viewport_state_ci.viewportCount = 1; | 537 | viewport_state_ci.viewportCount = 1; |
| 538 | viewport_state_ci.pViewports = nullptr; | ||
| 538 | viewport_state_ci.scissorCount = 1; | 539 | viewport_state_ci.scissorCount = 1; |
| 540 | viewport_state_ci.pScissors = nullptr; | ||
| 539 | 541 | ||
| 540 | VkPipelineRasterizationStateCreateInfo rasterization_ci; | 542 | VkPipelineRasterizationStateCreateInfo rasterization_ci; |
| 541 | rasterization_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; | 543 | rasterization_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; |
diff --git a/src/video_core/renderer_vulkan/vk_memory_manager.h b/src/video_core/renderer_vulkan/vk_memory_manager.h index 35ee54d30..5b6858e9b 100644 --- a/src/video_core/renderer_vulkan/vk_memory_manager.h +++ b/src/video_core/renderer_vulkan/vk_memory_manager.h | |||
| @@ -32,7 +32,7 @@ public: | |||
| 32 | * memory. When passing false, it will try to allocate device local memory. | 32 | * memory. When passing false, it will try to allocate device local memory. |
| 33 | * @returns A memory commit. | 33 | * @returns A memory commit. |
| 34 | */ | 34 | */ |
| 35 | VKMemoryCommit Commit(const VkMemoryRequirements& reqs, bool host_visible); | 35 | VKMemoryCommit Commit(const VkMemoryRequirements& requirements, bool host_visible); |
| 36 | 36 | ||
| 37 | /// Commits memory required by the buffer and binds it. | 37 | /// Commits memory required by the buffer and binds it. |
| 38 | VKMemoryCommit Commit(const vk::Buffer& buffer, bool host_visible); | 38 | VKMemoryCommit Commit(const vk::Buffer& buffer, bool host_visible); |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index ab281c9e2..4ca0febb8 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -62,13 +62,16 @@ constexpr auto ComputeShaderIndex = static_cast<std::size_t>(Tegra::Engines::Sha | |||
| 62 | 62 | ||
| 63 | VkViewport GetViewportState(const VKDevice& device, const Maxwell& regs, std::size_t index) { | 63 | VkViewport GetViewportState(const VKDevice& device, const Maxwell& regs, std::size_t index) { |
| 64 | const auto& src = regs.viewport_transform[index]; | 64 | const auto& src = regs.viewport_transform[index]; |
| 65 | const float width = src.scale_x * 2.0f; | ||
| 66 | const float height = src.scale_y * 2.0f; | ||
| 67 | |||
| 65 | VkViewport viewport; | 68 | VkViewport viewport; |
| 66 | viewport.x = src.translate_x - src.scale_x; | 69 | viewport.x = src.translate_x - src.scale_x; |
| 67 | viewport.y = src.translate_y - src.scale_y; | 70 | viewport.y = src.translate_y - src.scale_y; |
| 68 | viewport.width = src.scale_x * 2.0f; | 71 | viewport.width = width != 0.0f ? width : 1.0f; |
| 69 | viewport.height = src.scale_y * 2.0f; | 72 | viewport.height = height != 0.0f ? height : 1.0f; |
| 70 | 73 | ||
| 71 | const float reduce_z = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne; | 74 | const float reduce_z = regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1.0f : 0.0f; |
| 72 | viewport.minDepth = src.translate_z - src.scale_z * reduce_z; | 75 | viewport.minDepth = src.translate_z - src.scale_z * reduce_z; |
| 73 | viewport.maxDepth = src.translate_z + src.scale_z; | 76 | viewport.maxDepth = src.translate_z + src.scale_z; |
| 74 | if (!device.IsExtDepthRangeUnrestrictedSupported()) { | 77 | if (!device.IsExtDepthRangeUnrestrictedSupported()) { |
diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 62e4ca488..aaa138f52 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp | |||
| @@ -1938,11 +1938,8 @@ private: | |||
| 1938 | return {}; | 1938 | return {}; |
| 1939 | } | 1939 | } |
| 1940 | 1940 | ||
| 1941 | template <Id (Module::*func)(Id, Id, Id, Id, Id), Type result_type, | 1941 | template <Id (Module::*func)(Id, Id, Id, Id, Id)> |
| 1942 | Type value_type = result_type> | ||
| 1943 | Expression Atomic(Operation operation) { | 1942 | Expression Atomic(Operation operation) { |
| 1944 | const Id type_def = GetTypeDefinition(result_type); | ||
| 1945 | |||
| 1946 | Id pointer; | 1943 | Id pointer; |
| 1947 | if (const auto smem = std::get_if<SmemNode>(&*operation[0])) { | 1944 | if (const auto smem = std::get_if<SmemNode>(&*operation[0])) { |
| 1948 | pointer = GetSharedMemoryPointer(*smem); | 1945 | pointer = GetSharedMemoryPointer(*smem); |
| @@ -1950,15 +1947,19 @@ private: | |||
| 1950 | pointer = GetGlobalMemoryPointer(*gmem); | 1947 | pointer = GetGlobalMemoryPointer(*gmem); |
| 1951 | } else { | 1948 | } else { |
| 1952 | UNREACHABLE(); | 1949 | UNREACHABLE(); |
| 1953 | return {Constant(type_def, 0), result_type}; | 1950 | return {v_float_zero, Type::Float}; |
| 1954 | } | 1951 | } |
| 1955 | |||
| 1956 | const Id value = As(Visit(operation[1]), value_type); | ||
| 1957 | |||
| 1958 | const Id scope = Constant(t_uint, static_cast<u32>(spv::Scope::Device)); | 1952 | const Id scope = Constant(t_uint, static_cast<u32>(spv::Scope::Device)); |
| 1959 | const Id semantics = Constant(type_def, 0); | 1953 | const Id semantics = Constant(t_uint, 0); |
| 1954 | const Id value = AsUint(Visit(operation[1])); | ||
| 1955 | |||
| 1956 | return {(this->*func)(t_uint, pointer, scope, semantics, value), Type::Uint}; | ||
| 1957 | } | ||
| 1960 | 1958 | ||
| 1961 | return {(this->*func)(type_def, pointer, scope, semantics, value), result_type}; | 1959 | template <Id (Module::*func)(Id, Id, Id, Id, Id)> |
| 1960 | Expression Reduce(Operation operation) { | ||
| 1961 | Atomic<func>(operation); | ||
| 1962 | return {}; | ||
| 1962 | } | 1963 | } |
| 1963 | 1964 | ||
| 1964 | Expression Branch(Operation operation) { | 1965 | Expression Branch(Operation operation) { |
| @@ -2547,21 +2548,35 @@ private: | |||
| 2547 | &SPIRVDecompiler::AtomicImageXor, | 2548 | &SPIRVDecompiler::AtomicImageXor, |
| 2548 | &SPIRVDecompiler::AtomicImageExchange, | 2549 | &SPIRVDecompiler::AtomicImageExchange, |
| 2549 | 2550 | ||
| 2550 | &SPIRVDecompiler::Atomic<&Module::OpAtomicExchange, Type::Uint>, | 2551 | &SPIRVDecompiler::Atomic<&Module::OpAtomicExchange>, |
| 2551 | &SPIRVDecompiler::Atomic<&Module::OpAtomicIAdd, Type::Uint>, | 2552 | &SPIRVDecompiler::Atomic<&Module::OpAtomicIAdd>, |
| 2552 | &SPIRVDecompiler::Atomic<&Module::OpAtomicUMin, Type::Uint>, | 2553 | &SPIRVDecompiler::Atomic<&Module::OpAtomicUMin>, |
| 2553 | &SPIRVDecompiler::Atomic<&Module::OpAtomicUMax, Type::Uint>, | 2554 | &SPIRVDecompiler::Atomic<&Module::OpAtomicUMax>, |
| 2554 | &SPIRVDecompiler::Atomic<&Module::OpAtomicAnd, Type::Uint>, | 2555 | &SPIRVDecompiler::Atomic<&Module::OpAtomicAnd>, |
| 2555 | &SPIRVDecompiler::Atomic<&Module::OpAtomicOr, Type::Uint>, | 2556 | &SPIRVDecompiler::Atomic<&Module::OpAtomicOr>, |
| 2556 | &SPIRVDecompiler::Atomic<&Module::OpAtomicXor, Type::Uint>, | 2557 | &SPIRVDecompiler::Atomic<&Module::OpAtomicXor>, |
| 2557 | 2558 | ||
| 2558 | &SPIRVDecompiler::Atomic<&Module::OpAtomicExchange, Type::Int>, | 2559 | &SPIRVDecompiler::Atomic<&Module::OpAtomicExchange>, |
| 2559 | &SPIRVDecompiler::Atomic<&Module::OpAtomicIAdd, Type::Int>, | 2560 | &SPIRVDecompiler::Atomic<&Module::OpAtomicIAdd>, |
| 2560 | &SPIRVDecompiler::Atomic<&Module::OpAtomicSMin, Type::Int>, | 2561 | &SPIRVDecompiler::Atomic<&Module::OpAtomicSMin>, |
| 2561 | &SPIRVDecompiler::Atomic<&Module::OpAtomicSMax, Type::Int>, | 2562 | &SPIRVDecompiler::Atomic<&Module::OpAtomicSMax>, |
| 2562 | &SPIRVDecompiler::Atomic<&Module::OpAtomicAnd, Type::Int>, | 2563 | &SPIRVDecompiler::Atomic<&Module::OpAtomicAnd>, |
| 2563 | &SPIRVDecompiler::Atomic<&Module::OpAtomicOr, Type::Int>, | 2564 | &SPIRVDecompiler::Atomic<&Module::OpAtomicOr>, |
| 2564 | &SPIRVDecompiler::Atomic<&Module::OpAtomicXor, Type::Int>, | 2565 | &SPIRVDecompiler::Atomic<&Module::OpAtomicXor>, |
| 2566 | |||
| 2567 | &SPIRVDecompiler::Reduce<&Module::OpAtomicIAdd>, | ||
| 2568 | &SPIRVDecompiler::Reduce<&Module::OpAtomicUMin>, | ||
| 2569 | &SPIRVDecompiler::Reduce<&Module::OpAtomicUMax>, | ||
| 2570 | &SPIRVDecompiler::Reduce<&Module::OpAtomicAnd>, | ||
| 2571 | &SPIRVDecompiler::Reduce<&Module::OpAtomicOr>, | ||
| 2572 | &SPIRVDecompiler::Reduce<&Module::OpAtomicXor>, | ||
| 2573 | |||
| 2574 | &SPIRVDecompiler::Reduce<&Module::OpAtomicIAdd>, | ||
| 2575 | &SPIRVDecompiler::Reduce<&Module::OpAtomicSMin>, | ||
| 2576 | &SPIRVDecompiler::Reduce<&Module::OpAtomicSMax>, | ||
| 2577 | &SPIRVDecompiler::Reduce<&Module::OpAtomicAnd>, | ||
| 2578 | &SPIRVDecompiler::Reduce<&Module::OpAtomicOr>, | ||
| 2579 | &SPIRVDecompiler::Reduce<&Module::OpAtomicXor>, | ||
| 2565 | 2580 | ||
| 2566 | &SPIRVDecompiler::Branch, | 2581 | &SPIRVDecompiler::Branch, |
| 2567 | &SPIRVDecompiler::BranchIndirect, | 2582 | &SPIRVDecompiler::BranchIndirect, |
diff --git a/src/video_core/shader/control_flow.cpp b/src/video_core/shader/control_flow.cpp index 2e2711350..6d313963a 100644 --- a/src/video_core/shader/control_flow.cpp +++ b/src/video_core/shader/control_flow.cpp | |||
| @@ -484,17 +484,17 @@ bool TryInspectAddress(CFGRebuildState& state) { | |||
| 484 | } | 484 | } |
| 485 | case BlockCollision::Inside: { | 485 | case BlockCollision::Inside: { |
| 486 | // This case is the tricky one: | 486 | // This case is the tricky one: |
| 487 | // We need to Split the block in 2 sepparate blocks | 487 | // We need to split the block into 2 separate blocks |
| 488 | const u32 end = state.block_info[block_index].end; | 488 | const u32 end = state.block_info[block_index].end; |
| 489 | BlockInfo& new_block = CreateBlockInfo(state, address, end); | 489 | BlockInfo& new_block = CreateBlockInfo(state, address, end); |
| 490 | BlockInfo& current_block = state.block_info[block_index]; | 490 | BlockInfo& current_block = state.block_info[block_index]; |
| 491 | current_block.end = address - 1; | 491 | current_block.end = address - 1; |
| 492 | new_block.branch = current_block.branch; | 492 | new_block.branch = std::move(current_block.branch); |
| 493 | BlockBranchInfo forward_branch = MakeBranchInfo<SingleBranch>(); | 493 | BlockBranchInfo forward_branch = MakeBranchInfo<SingleBranch>(); |
| 494 | const auto branch = std::get_if<SingleBranch>(forward_branch.get()); | 494 | const auto branch = std::get_if<SingleBranch>(forward_branch.get()); |
| 495 | branch->address = address; | 495 | branch->address = address; |
| 496 | branch->ignore = true; | 496 | branch->ignore = true; |
| 497 | current_block.branch = forward_branch; | 497 | current_block.branch = std::move(forward_branch); |
| 498 | return true; | 498 | return true; |
| 499 | } | 499 | } |
| 500 | default: | 500 | default: |
diff --git a/src/video_core/shader/decode/arithmetic.cpp b/src/video_core/shader/decode/arithmetic.cpp index 478394682..4db329fa5 100644 --- a/src/video_core/shader/decode/arithmetic.cpp +++ b/src/video_core/shader/decode/arithmetic.cpp | |||
| @@ -136,7 +136,8 @@ u32 ShaderIR::DecodeArithmetic(NodeBlock& bb, u32 pc) { | |||
| 136 | SetRegister(bb, instr.gpr0, value); | 136 | SetRegister(bb, instr.gpr0, value); |
| 137 | break; | 137 | break; |
| 138 | } | 138 | } |
| 139 | case OpCode::Id::FCMP_R: { | 139 | case OpCode::Id::FCMP_RR: |
| 140 | case OpCode::Id::FCMP_RC: { | ||
| 140 | UNIMPLEMENTED_IF(instr.fcmp.ftz == 0); | 141 | UNIMPLEMENTED_IF(instr.fcmp.ftz == 0); |
| 141 | Node op_c = GetRegister(instr.gpr39); | 142 | Node op_c = GetRegister(instr.gpr39); |
| 142 | Node comp = GetPredicateComparisonFloat(instr.fcmp.cond, std::move(op_c), Immediate(0.0f)); | 143 | Node comp = GetPredicateComparisonFloat(instr.fcmp.cond, std::move(op_c), Immediate(0.0f)); |
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index b8f63922f..8112ead3e 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp | |||
| @@ -3,7 +3,9 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <utility> | ||
| 6 | #include <vector> | 7 | #include <vector> |
| 8 | |||
| 7 | #include <fmt/format.h> | 9 | #include <fmt/format.h> |
| 8 | 10 | ||
| 9 | #include "common/alignment.h" | 11 | #include "common/alignment.h" |
| @@ -16,6 +18,7 @@ | |||
| 16 | 18 | ||
| 17 | namespace VideoCommon::Shader { | 19 | namespace VideoCommon::Shader { |
| 18 | 20 | ||
| 21 | using std::move; | ||
| 19 | using Tegra::Shader::AtomicOp; | 22 | using Tegra::Shader::AtomicOp; |
| 20 | using Tegra::Shader::AtomicType; | 23 | using Tegra::Shader::AtomicType; |
| 21 | using Tegra::Shader::Attribute; | 24 | using Tegra::Shader::Attribute; |
| @@ -27,29 +30,26 @@ using Tegra::Shader::StoreType; | |||
| 27 | 30 | ||
| 28 | namespace { | 31 | namespace { |
| 29 | 32 | ||
| 30 | Node GetAtomOperation(AtomicOp op, bool is_signed, Node memory, Node data) { | 33 | OperationCode GetAtomOperation(AtomicOp op) { |
| 31 | const OperationCode operation_code = [op] { | 34 | switch (op) { |
| 32 | switch (op) { | 35 | case AtomicOp::Add: |
| 33 | case AtomicOp::Add: | 36 | return OperationCode::AtomicIAdd; |
| 34 | return OperationCode::AtomicIAdd; | 37 | case AtomicOp::Min: |
| 35 | case AtomicOp::Min: | 38 | return OperationCode::AtomicIMin; |
| 36 | return OperationCode::AtomicIMin; | 39 | case AtomicOp::Max: |
| 37 | case AtomicOp::Max: | 40 | return OperationCode::AtomicIMax; |
| 38 | return OperationCode::AtomicIMax; | 41 | case AtomicOp::And: |
| 39 | case AtomicOp::And: | 42 | return OperationCode::AtomicIAnd; |
| 40 | return OperationCode::AtomicIAnd; | 43 | case AtomicOp::Or: |
| 41 | case AtomicOp::Or: | 44 | return OperationCode::AtomicIOr; |
| 42 | return OperationCode::AtomicIOr; | 45 | case AtomicOp::Xor: |
| 43 | case AtomicOp::Xor: | 46 | return OperationCode::AtomicIXor; |
| 44 | return OperationCode::AtomicIXor; | 47 | case AtomicOp::Exch: |
| 45 | case AtomicOp::Exch: | 48 | return OperationCode::AtomicIExchange; |
| 46 | return OperationCode::AtomicIExchange; | 49 | default: |
| 47 | default: | 50 | UNIMPLEMENTED_MSG("op={}", static_cast<int>(op)); |
| 48 | UNIMPLEMENTED_MSG("op={}", static_cast<int>(op)); | 51 | return OperationCode::AtomicIAdd; |
| 49 | return OperationCode::AtomicIAdd; | 52 | } |
| 50 | } | ||
| 51 | }(); | ||
| 52 | return SignedOperation(operation_code, is_signed, std::move(memory), std::move(data)); | ||
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | bool IsUnaligned(Tegra::Shader::UniformType uniform_type) { | 55 | bool IsUnaligned(Tegra::Shader::UniformType uniform_type) { |
| @@ -90,23 +90,22 @@ u32 GetMemorySize(Tegra::Shader::UniformType uniform_type) { | |||
| 90 | 90 | ||
| 91 | Node ExtractUnaligned(Node value, Node address, u32 mask, u32 size) { | 91 | Node ExtractUnaligned(Node value, Node address, u32 mask, u32 size) { |
| 92 | Node offset = Operation(OperationCode::UBitwiseAnd, address, Immediate(mask)); | 92 | Node offset = Operation(OperationCode::UBitwiseAnd, address, Immediate(mask)); |
| 93 | offset = Operation(OperationCode::ULogicalShiftLeft, std::move(offset), Immediate(3)); | 93 | offset = Operation(OperationCode::ULogicalShiftLeft, move(offset), Immediate(3)); |
| 94 | return Operation(OperationCode::UBitfieldExtract, std::move(value), std::move(offset), | 94 | return Operation(OperationCode::UBitfieldExtract, move(value), move(offset), Immediate(size)); |
| 95 | Immediate(size)); | ||
| 96 | } | 95 | } |
| 97 | 96 | ||
| 98 | Node InsertUnaligned(Node dest, Node value, Node address, u32 mask, u32 size) { | 97 | Node InsertUnaligned(Node dest, Node value, Node address, u32 mask, u32 size) { |
| 99 | Node offset = Operation(OperationCode::UBitwiseAnd, std::move(address), Immediate(mask)); | 98 | Node offset = Operation(OperationCode::UBitwiseAnd, move(address), Immediate(mask)); |
| 100 | offset = Operation(OperationCode::ULogicalShiftLeft, std::move(offset), Immediate(3)); | 99 | offset = Operation(OperationCode::ULogicalShiftLeft, move(offset), Immediate(3)); |
| 101 | return Operation(OperationCode::UBitfieldInsert, std::move(dest), std::move(value), | 100 | return Operation(OperationCode::UBitfieldInsert, move(dest), move(value), move(offset), |
| 102 | std::move(offset), Immediate(size)); | 101 | Immediate(size)); |
| 103 | } | 102 | } |
| 104 | 103 | ||
| 105 | Node Sign16Extend(Node value) { | 104 | Node Sign16Extend(Node value) { |
| 106 | Node sign = Operation(OperationCode::UBitwiseAnd, value, Immediate(1U << 15)); | 105 | Node sign = Operation(OperationCode::UBitwiseAnd, value, Immediate(1U << 15)); |
| 107 | Node is_sign = Operation(OperationCode::LogicalUEqual, std::move(sign), Immediate(1U << 15)); | 106 | Node is_sign = Operation(OperationCode::LogicalUEqual, move(sign), Immediate(1U << 15)); |
| 108 | Node extend = Operation(OperationCode::Select, is_sign, Immediate(0xFFFF0000), Immediate(0)); | 107 | Node extend = Operation(OperationCode::Select, is_sign, Immediate(0xFFFF0000), Immediate(0)); |
| 109 | return Operation(OperationCode::UBitwiseOr, std::move(value), std::move(extend)); | 108 | return Operation(OperationCode::UBitwiseOr, move(value), move(extend)); |
| 110 | } | 109 | } |
| 111 | 110 | ||
| 112 | } // Anonymous namespace | 111 | } // Anonymous namespace |
| @@ -379,20 +378,36 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { | |||
| 379 | 378 | ||
| 380 | if (IsUnaligned(type)) { | 379 | if (IsUnaligned(type)) { |
| 381 | const u32 mask = GetUnalignedMask(type); | 380 | const u32 mask = GetUnalignedMask(type); |
| 382 | value = InsertUnaligned(gmem, std::move(value), real_address, mask, size); | 381 | value = InsertUnaligned(gmem, move(value), real_address, mask, size); |
| 383 | } | 382 | } |
| 384 | 383 | ||
| 385 | bb.push_back(Operation(OperationCode::Assign, gmem, value)); | 384 | bb.push_back(Operation(OperationCode::Assign, gmem, value)); |
| 386 | } | 385 | } |
| 387 | break; | 386 | break; |
| 388 | } | 387 | } |
| 388 | case OpCode::Id::RED: { | ||
| 389 | UNIMPLEMENTED_IF_MSG(instr.red.type != GlobalAtomicType::U32); | ||
| 390 | UNIMPLEMENTED_IF_MSG(instr.red.operation != AtomicOp::Add); | ||
| 391 | const auto [real_address, base_address, descriptor] = | ||
| 392 | TrackGlobalMemory(bb, instr, true, true); | ||
| 393 | if (!real_address || !base_address) { | ||
| 394 | // Tracking failed, skip atomic. | ||
| 395 | break; | ||
| 396 | } | ||
| 397 | Node gmem = MakeNode<GmemNode>(real_address, base_address, descriptor); | ||
| 398 | Node value = GetRegister(instr.gpr0); | ||
| 399 | bb.push_back(Operation(OperationCode::ReduceIAdd, move(gmem), move(value))); | ||
| 400 | break; | ||
| 401 | } | ||
| 389 | case OpCode::Id::ATOM: { | 402 | case OpCode::Id::ATOM: { |
| 390 | UNIMPLEMENTED_IF_MSG(instr.atom.operation == AtomicOp::Inc || | 403 | UNIMPLEMENTED_IF_MSG(instr.atom.operation == AtomicOp::Inc || |
| 391 | instr.atom.operation == AtomicOp::Dec || | 404 | instr.atom.operation == AtomicOp::Dec || |
| 392 | instr.atom.operation == AtomicOp::SafeAdd, | 405 | instr.atom.operation == AtomicOp::SafeAdd, |
| 393 | "operation={}", static_cast<int>(instr.atom.operation.Value())); | 406 | "operation={}", static_cast<int>(instr.atom.operation.Value())); |
| 394 | UNIMPLEMENTED_IF_MSG(instr.atom.type == GlobalAtomicType::S64 || | 407 | UNIMPLEMENTED_IF_MSG(instr.atom.type == GlobalAtomicType::S64 || |
| 395 | instr.atom.type == GlobalAtomicType::U64, | 408 | instr.atom.type == GlobalAtomicType::U64 || |
| 409 | instr.atom.type == GlobalAtomicType::F16x2_FTZ_RN || | ||
| 410 | instr.atom.type == GlobalAtomicType::F32_FTZ_RN, | ||
| 396 | "type={}", static_cast<int>(instr.atom.type.Value())); | 411 | "type={}", static_cast<int>(instr.atom.type.Value())); |
| 397 | 412 | ||
| 398 | const auto [real_address, base_address, descriptor] = | 413 | const auto [real_address, base_address, descriptor] = |
| @@ -403,11 +418,11 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { | |||
| 403 | } | 418 | } |
| 404 | 419 | ||
| 405 | const bool is_signed = | 420 | const bool is_signed = |
| 406 | instr.atoms.type == AtomicType::S32 || instr.atoms.type == AtomicType::S64; | 421 | instr.atom.type == GlobalAtomicType::S32 || instr.atom.type == GlobalAtomicType::S64; |
| 407 | Node gmem = MakeNode<GmemNode>(real_address, base_address, descriptor); | 422 | Node gmem = MakeNode<GmemNode>(real_address, base_address, descriptor); |
| 408 | Node value = GetAtomOperation(static_cast<AtomicOp>(instr.atom.operation), is_signed, gmem, | 423 | SetRegister(bb, instr.gpr0, |
| 409 | GetRegister(instr.gpr20)); | 424 | SignedOperation(GetAtomOperation(instr.atom.operation), is_signed, gmem, |
| 410 | SetRegister(bb, instr.gpr0, std::move(value)); | 425 | GetRegister(instr.gpr20))); |
| 411 | break; | 426 | break; |
| 412 | } | 427 | } |
| 413 | case OpCode::Id::ATOMS: { | 428 | case OpCode::Id::ATOMS: { |
| @@ -421,11 +436,10 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) { | |||
| 421 | instr.atoms.type == AtomicType::S32 || instr.atoms.type == AtomicType::S64; | 436 | instr.atoms.type == AtomicType::S32 || instr.atoms.type == AtomicType::S64; |
| 422 | const s32 offset = instr.atoms.GetImmediateOffset(); | 437 | const s32 offset = instr.atoms.GetImmediateOffset(); |
| 423 | Node address = GetRegister(instr.gpr8); | 438 | Node address = GetRegister(instr.gpr8); |
| 424 | address = Operation(OperationCode::IAdd, std::move(address), Immediate(offset)); | 439 | address = Operation(OperationCode::IAdd, move(address), Immediate(offset)); |
| 425 | Node value = | 440 | SetRegister(bb, instr.gpr0, |
| 426 | GetAtomOperation(static_cast<AtomicOp>(instr.atoms.operation), is_signed, | 441 | SignedOperation(GetAtomOperation(instr.atoms.operation), is_signed, |
| 427 | GetSharedMemory(std::move(address)), GetRegister(instr.gpr20)); | 442 | GetSharedMemory(move(address)), GetRegister(instr.gpr20))); |
| 428 | SetRegister(bb, instr.gpr0, std::move(value)); | ||
| 429 | break; | 443 | break; |
| 430 | } | 444 | } |
| 431 | case OpCode::Id::AL2P: { | 445 | case OpCode::Id::AL2P: { |
diff --git a/src/video_core/shader/decode/shift.cpp b/src/video_core/shader/decode/shift.cpp index 3b391d3e6..d4ffa8014 100644 --- a/src/video_core/shader/decode/shift.cpp +++ b/src/video_core/shader/decode/shift.cpp | |||
| @@ -23,7 +23,6 @@ Node IsFull(Node shift) { | |||
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | Node Shift(OperationCode opcode, Node value, Node shift) { | 25 | Node Shift(OperationCode opcode, Node value, Node shift) { |
| 26 | Node is_full = Operation(OperationCode::LogicalIEqual, shift, Immediate(32)); | ||
| 27 | Node shifted = Operation(opcode, move(value), shift); | 26 | Node shifted = Operation(opcode, move(value), shift); |
| 28 | return Operation(OperationCode::Select, IsFull(move(shift)), Immediate(0), move(shifted)); | 27 | return Operation(OperationCode::Select, IsFull(move(shift)), Immediate(0), move(shifted)); |
| 29 | } | 28 | } |
diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h index 5fcc9da60..3eee961f5 100644 --- a/src/video_core/shader/node.h +++ b/src/video_core/shader/node.h | |||
| @@ -178,6 +178,20 @@ enum class OperationCode { | |||
| 178 | AtomicIOr, /// (memory, int) -> int | 178 | AtomicIOr, /// (memory, int) -> int |
| 179 | AtomicIXor, /// (memory, int) -> int | 179 | AtomicIXor, /// (memory, int) -> int |
| 180 | 180 | ||
| 181 | ReduceUAdd, /// (memory, uint) -> void | ||
| 182 | ReduceUMin, /// (memory, uint) -> void | ||
| 183 | ReduceUMax, /// (memory, uint) -> void | ||
| 184 | ReduceUAnd, /// (memory, uint) -> void | ||
| 185 | ReduceUOr, /// (memory, uint) -> void | ||
| 186 | ReduceUXor, /// (memory, uint) -> void | ||
| 187 | |||
| 188 | ReduceIAdd, /// (memory, int) -> void | ||
| 189 | ReduceIMin, /// (memory, int) -> void | ||
| 190 | ReduceIMax, /// (memory, int) -> void | ||
| 191 | ReduceIAnd, /// (memory, int) -> void | ||
| 192 | ReduceIOr, /// (memory, int) -> void | ||
| 193 | ReduceIXor, /// (memory, int) -> void | ||
| 194 | |||
| 181 | Branch, /// (uint branch_target) -> void | 195 | Branch, /// (uint branch_target) -> void |
| 182 | BranchIndirect, /// (uint branch_target) -> void | 196 | BranchIndirect, /// (uint branch_target) -> void |
| 183 | PushFlowStack, /// (uint branch_target) -> void | 197 | PushFlowStack, /// (uint branch_target) -> void |
diff --git a/src/video_core/texture_cache/surface_base.cpp b/src/video_core/texture_cache/surface_base.cpp index 7af0e792c..715f39d0d 100644 --- a/src/video_core/texture_cache/surface_base.cpp +++ b/src/video_core/texture_cache/surface_base.cpp | |||
| @@ -248,8 +248,14 @@ void SurfaceBaseImpl::FlushBuffer(Tegra::MemoryManager& memory_manager, | |||
| 248 | 248 | ||
| 249 | // Use an extra temporal buffer | 249 | // Use an extra temporal buffer |
| 250 | auto& tmp_buffer = staging_cache.GetBuffer(1); | 250 | auto& tmp_buffer = staging_cache.GetBuffer(1); |
| 251 | // Special case for 3D Texture Segments | ||
| 252 | const bool must_read_current_data = | ||
| 253 | params.block_depth > 0 && params.target == VideoCore::Surface::SurfaceTarget::Texture2D; | ||
| 251 | tmp_buffer.resize(guest_memory_size); | 254 | tmp_buffer.resize(guest_memory_size); |
| 252 | host_ptr = tmp_buffer.data(); | 255 | host_ptr = tmp_buffer.data(); |
| 256 | if (must_read_current_data) { | ||
| 257 | memory_manager.ReadBlockUnsafe(gpu_addr, host_ptr, guest_memory_size); | ||
| 258 | } | ||
| 253 | 259 | ||
| 254 | if (params.is_tiled) { | 260 | if (params.is_tiled) { |
| 255 | ASSERT_MSG(params.block_width == 0, "Block width is defined as {}", params.block_width); | 261 | ASSERT_MSG(params.block_width == 0, "Block width is defined as {}", params.block_width); |
diff --git a/src/video_core/texture_cache/surface_base.h b/src/video_core/texture_cache/surface_base.h index a39a8661b..c5ab21f56 100644 --- a/src/video_core/texture_cache/surface_base.h +++ b/src/video_core/texture_cache/surface_base.h | |||
| @@ -72,9 +72,9 @@ public: | |||
| 72 | return (cpu_addr < end) && (cpu_addr_end > start); | 72 | return (cpu_addr < end) && (cpu_addr_end > start); |
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | bool IsInside(const GPUVAddr other_start, const GPUVAddr other_end) { | 75 | bool IsInside(const GPUVAddr other_start, const GPUVAddr other_end) const { |
| 76 | const GPUVAddr gpu_addr_end = gpu_addr + guest_memory_size; | 76 | const GPUVAddr gpu_addr_end = gpu_addr + guest_memory_size; |
| 77 | return (gpu_addr <= other_start && other_end <= gpu_addr_end); | 77 | return gpu_addr <= other_start && other_end <= gpu_addr_end; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | // Use only when recycling a surface | 80 | // Use only when recycling a surface |
diff --git a/src/video_core/texture_cache/surface_view.cpp b/src/video_core/texture_cache/surface_view.cpp index 57a1f5803..6b5f5984b 100644 --- a/src/video_core/texture_cache/surface_view.cpp +++ b/src/video_core/texture_cache/surface_view.cpp | |||
| @@ -20,4 +20,8 @@ bool ViewParams::operator==(const ViewParams& rhs) const { | |||
| 20 | std::tie(rhs.base_layer, rhs.num_layers, rhs.base_level, rhs.num_levels, rhs.target); | 20 | std::tie(rhs.base_layer, rhs.num_layers, rhs.base_level, rhs.num_levels, rhs.target); |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | bool ViewParams::operator!=(const ViewParams& rhs) const { | ||
| 24 | return !operator==(rhs); | ||
| 25 | } | ||
| 26 | |||
| 23 | } // namespace VideoCommon | 27 | } // namespace VideoCommon |
diff --git a/src/video_core/texture_cache/surface_view.h b/src/video_core/texture_cache/surface_view.h index b17fd11a9..90a8bb0ae 100644 --- a/src/video_core/texture_cache/surface_view.h +++ b/src/video_core/texture_cache/surface_view.h | |||
| @@ -21,6 +21,7 @@ struct ViewParams { | |||
| 21 | std::size_t Hash() const; | 21 | std::size_t Hash() const; |
| 22 | 22 | ||
| 23 | bool operator==(const ViewParams& rhs) const; | 23 | bool operator==(const ViewParams& rhs) const; |
| 24 | bool operator!=(const ViewParams& rhs) const; | ||
| 24 | 25 | ||
| 25 | bool IsLayered() const { | 26 | bool IsLayered() const { |
| 26 | switch (target) { | 27 | switch (target) { |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index cfc7fe6e9..3e8663adf 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -509,7 +509,9 @@ private: | |||
| 509 | } | 509 | } |
| 510 | const auto& final_params = new_surface->GetSurfaceParams(); | 510 | const auto& final_params = new_surface->GetSurfaceParams(); |
| 511 | if (cr_params.type != final_params.type) { | 511 | if (cr_params.type != final_params.type) { |
| 512 | BufferCopy(current_surface, new_surface); | 512 | if (Settings::values.use_accurate_gpu_emulation) { |
| 513 | BufferCopy(current_surface, new_surface); | ||
| 514 | } | ||
| 513 | } else { | 515 | } else { |
| 514 | std::vector<CopyParams> bricks = current_surface->BreakDown(final_params); | 516 | std::vector<CopyParams> bricks = current_surface->BreakDown(final_params); |
| 515 | for (auto& brick : bricks) { | 517 | for (auto& brick : bricks) { |
| @@ -612,10 +614,10 @@ private: | |||
| 612 | * textures within the GPU if possible. Falls back to LLE when it isn't possible to use any of | 614 | * textures within the GPU if possible. Falls back to LLE when it isn't possible to use any of |
| 613 | * the HLE methods. | 615 | * the HLE methods. |
| 614 | * | 616 | * |
| 615 | * @param overlaps The overlapping surfaces registered in the cache. | 617 | * @param overlaps The overlapping surfaces registered in the cache. |
| 616 | * @param params The parameters on the new surface. | 618 | * @param params The parameters on the new surface. |
| 617 | * @param gpu_addr The starting address of the new surface. | 619 | * @param gpu_addr The starting address of the new surface. |
| 618 | * @param cache_addr The starting address of the new surface on physical memory. | 620 | * @param cpu_addr The starting address of the new surface on physical memory. |
| 619 | */ | 621 | */ |
| 620 | std::optional<std::pair<TSurface, TView>> Manage3DSurfaces(std::vector<TSurface>& overlaps, | 622 | std::optional<std::pair<TSurface, TView>> Manage3DSurfaces(std::vector<TSurface>& overlaps, |
| 621 | const SurfaceParams& params, | 623 | const SurfaceParams& params, |
diff --git a/src/web_service/CMakeLists.txt b/src/web_service/CMakeLists.txt index 01f2d129d..0c9bb0d55 100644 --- a/src/web_service/CMakeLists.txt +++ b/src/web_service/CMakeLists.txt | |||
| @@ -8,9 +8,4 @@ add_library(web_service STATIC | |||
| 8 | ) | 8 | ) |
| 9 | 9 | ||
| 10 | create_target_directory_groups(web_service) | 10 | create_target_directory_groups(web_service) |
| 11 | 11 | target_link_libraries(web_service PRIVATE common json-headers httplib lurlparser) | |
| 12 | get_directory_property(OPENSSL_LIBS | ||
| 13 | DIRECTORY ${PROJECT_SOURCE_DIR}/externals/libressl | ||
| 14 | DEFINITION OPENSSL_LIBS) | ||
| 15 | target_compile_definitions(web_service PRIVATE -DCPPHTTPLIB_OPENSSL_SUPPORT) | ||
| 16 | target_link_libraries(web_service PRIVATE common json-headers ${OPENSSL_LIBS} httplib lurlparser) | ||