From ca0b9fc44b490c1c0e9e1ee3e71a76ef2ed062b3 Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Tue, 8 Nov 2022 03:37:36 +0100 Subject: [PATCH] early-access version 3098 --- README.md | 2 +- src/core/hle/kernel/hle_ipc.cpp | 14 +++---- src/core/hle/kernel/hle_ipc.h | 6 +-- src/core/hle/kernel/kernel.cpp | 42 +++++++++---------- src/core/hle/kernel/kernel.h | 10 ++--- .../glasm/emit_glasm_context_get_set.cpp | 2 +- .../backend/spirv/spirv_emit_context.h | 2 +- src/video_core/engines/maxwell_dma.cpp | 37 ++++++++-------- .../renderer_opengl/gl_shader_cache.cpp | 2 +- src/yuzu/compatdb.cpp | 2 +- src/yuzu/compatdb.ui | 4 +- 11 files changed, 60 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 50e816c9c..848c21d03 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 3097. +This is the source code for early-access 3098. ## Legal Notice diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 68f7053ab..a3bfae208 100755 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -27,16 +27,12 @@ namespace Kernel { SessionRequestHandler::SessionRequestHandler(KernelCore& kernel_, const char* service_name_, ServiceThreadType thread_type) - : kernel{kernel_} { - if (thread_type == ServiceThreadType::CreateNew) { - service_thread = kernel.CreateServiceThread(service_name_); - } else { - service_thread = kernel.GetDefaultServiceThread(); - } -} + : kernel{kernel_}, service_thread{thread_type == ServiceThreadType::CreateNew + ? kernel.CreateServiceThread(service_name_) + : kernel.GetDefaultServiceThread()} {} SessionRequestHandler::~SessionRequestHandler() { - kernel.ReleaseServiceThread(service_thread.lock()); + kernel.ReleaseServiceThread(service_thread); } void SessionRequestHandler::AcceptSession(KServerPort* server_port) { @@ -49,7 +45,7 @@ void SessionRequestHandler::AcceptSession(KServerPort* server_port) { void SessionRequestHandler::RegisterSession(KServerSession* server_session, std::shared_ptr manager) { manager->SetSessionHandler(shared_from_this()); - service_thread.lock()->RegisterServerSession(server_session, manager); + service_thread.RegisterServerSession(server_session, manager); server_session->Close(); } diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index a43242020..5ecb5e5d3 100755 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -82,13 +82,13 @@ public: void RegisterSession(KServerSession* server_session, std::shared_ptr manager); - std::weak_ptr GetServiceThread() const { + ServiceThread& GetServiceThread() const { return service_thread; } protected: KernelCore& kernel; - std::weak_ptr service_thread; + ServiceThread& service_thread; }; using SessionRequestHandlerWeakPtr = std::weak_ptr; @@ -154,7 +154,7 @@ public: session_handler = std::move(handler); } - std::weak_ptr GetServiceThread() const { + ServiceThread& GetServiceThread() const { return session_handler->GetServiceThread(); } diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 8be7fc377..d648e55ed 100755 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -93,7 +93,7 @@ struct KernelCore::Impl { RegisterHostThread(nullptr); - default_service_thread = CreateServiceThread(kernel, "DefaultServiceThread"); + default_service_thread = &CreateServiceThread(kernel, "DefaultServiceThread"); } void InitializeCores() { @@ -782,33 +782,31 @@ struct KernelCore::Impl { search->second(system.ServiceManager(), server_port); } - std::weak_ptr CreateServiceThread(KernelCore& kernel, - const std::string& name) { - auto service_thread = std::make_shared(kernel, name); + Kernel::ServiceThread& CreateServiceThread(KernelCore& kernel, const std::string& name) { + auto* ptr = new ServiceThread(kernel, name); service_threads_manager.QueueWork( - [this, service_thread]() { service_threads.emplace(service_thread); }); + [this, ptr]() { service_threads.emplace(ptr, std::unique_ptr(ptr)); }); - return service_thread; + return *ptr; } - void ReleaseServiceThread(std::weak_ptr service_thread) { - if (auto strong_ptr = service_thread.lock()) { - if (strong_ptr == default_service_thread.lock()) { - // Nothing to do here, the service is using default_service_thread, which will be - // released on shutdown. - return; - } + void ReleaseServiceThread(Kernel::ServiceThread& service_thread) { + auto* ptr = &service_thread; - service_threads_manager.QueueWork( - [this, strong_ptr{std::move(strong_ptr)}]() { service_threads.erase(strong_ptr); }); + if (ptr == default_service_thread) { + // Nothing to do here, the service is using default_service_thread, which will be + // released on shutdown. + return; } + + service_threads_manager.QueueWork([this, ptr]() { service_threads.erase(ptr); }); } void ClearServiceThreads() { service_threads_manager.QueueWork([this] { service_threads.clear(); - default_service_thread.reset(); + default_service_thread = nullptr; service_thread_barrier.Sync(); }); service_thread_barrier.Sync(); @@ -884,8 +882,8 @@ struct KernelCore::Impl { std::unique_ptr memory_layout; // Threads used for services - std::unordered_set> service_threads; - std::weak_ptr default_service_thread; + std::unordered_map> service_threads; + ServiceThread* default_service_thread{}; Common::ThreadWorker service_threads_manager; Common::Barrier service_thread_barrier; @@ -1258,15 +1256,15 @@ void KernelCore::ExitSVCProfile() { MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[CurrentPhysicalCoreIndex()]); } -std::weak_ptr KernelCore::CreateServiceThread(const std::string& name) { +Kernel::ServiceThread& KernelCore::CreateServiceThread(const std::string& name) { return impl->CreateServiceThread(*this, name); } -std::weak_ptr KernelCore::GetDefaultServiceThread() const { - return impl->default_service_thread; +Kernel::ServiceThread& KernelCore::GetDefaultServiceThread() const { + return *impl->default_service_thread; } -void KernelCore::ReleaseServiceThread(std::weak_ptr service_thread) { +void KernelCore::ReleaseServiceThread(Kernel::ServiceThread& service_thread) { impl->ReleaseServiceThread(service_thread); } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index b87714c4a..6d1868aa4 100755 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -309,24 +309,24 @@ public: * See GetDefaultServiceThread. * @param name String name for the ServerSession creating this thread, used for debug * purposes. - * @returns The a weak pointer newly created service thread. + * @returns A reference to the newly created service thread. */ - std::weak_ptr CreateServiceThread(const std::string& name); + Kernel::ServiceThread& CreateServiceThread(const std::string& name); /** * Gets the default host service thread, which executes HLE service requests. Unless service * requests need to block on the host, the default service thread should be used in favor of * creating a new service thread. - * @returns The a weak pointer for the default service thread. + * @returns A reference to the default service thread. */ - std::weak_ptr GetDefaultServiceThread() const; + Kernel::ServiceThread& GetDefaultServiceThread() const; /** * Releases a HLE service thread, instructing KernelCore to free it. This should be called when * the ServerSession associated with the thread is destroyed. * @param service_thread Service thread to release. */ - void ReleaseServiceThread(std::weak_ptr service_thread); + void ReleaseServiceThread(Kernel::ServiceThread& service_thread); /// Workaround for single-core mode when preempting threads while idle. bool IsPhantomModeForSingleCore() const; diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp index 804d5a467..62cf57077 100755 --- a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp @@ -383,7 +383,7 @@ void EmitInvocationInfo(EmitContext& ctx, IR::Inst& inst) { switch (ctx.stage) { case Stage::TessellationControl: case Stage::TessellationEval: - ctx.Add("SHL.U {}.x, primitive.vertexcount, 16;", inst); + ctx.Add("SHL.U {}.x,primitive.vertexcount,16;", inst); break; default: LOG_WARNING(Shader, "(STUBBED) called"); diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.h b/src/shader_recompiler/backend/spirv/spirv_emit_context.h index efcc5210b..915d57b4f 100755 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.h +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.h @@ -204,7 +204,7 @@ public: Id workgroup_id{}; Id local_invocation_id{}; Id invocation_id{}; - Id patch_vertices_in; + Id patch_vertices_in{}; Id sample_id{}; Id is_helper_invocation{}; Id subgroup_local_invocation_id{}; diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index 05e302e35..7804f6b88 100755 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp @@ -103,26 +103,29 @@ void MaxwellDMA::Launch() { const bool is_src_pitch = IsPitchKind(static_cast(src_kind)); const bool is_dst_pitch = IsPitchKind(static_cast(dst_kind)); if (!is_src_pitch && is_dst_pitch) { - std::vector tmp_buffer(regs.line_length_in); - std::vector dst_buffer(regs.line_length_in); - memory_manager.ReadBlockUnsafe(regs.offset_in, tmp_buffer.data(), - regs.line_length_in); - for (u32 offset = 0; offset < regs.line_length_in; ++offset) { - dst_buffer[offset] = - tmp_buffer[convert_linear_2_blocklinear_addr(regs.offset_in + offset) - - regs.offset_in]; + UNIMPLEMENTED_IF(regs.line_length_in % 16 != 0); + UNIMPLEMENTED_IF(regs.offset_in % 16 != 0); + UNIMPLEMENTED_IF(regs.offset_out % 16 != 0); + std::vector tmp_buffer(16); + for (u32 offset = 0; offset < regs.line_length_in; offset += 16) { + memory_manager.ReadBlockUnsafe( + convert_linear_2_blocklinear_addr(regs.offset_in + offset), + tmp_buffer.data(), tmp_buffer.size()); + memory_manager.WriteBlock(regs.offset_out + offset, tmp_buffer.data(), + tmp_buffer.size()); } - memory_manager.WriteBlock(regs.offset_out, dst_buffer.data(), regs.line_length_in); } else if (is_src_pitch && !is_dst_pitch) { - std::vector tmp_buffer(regs.line_length_in); - std::vector dst_buffer(regs.line_length_in); - memory_manager.ReadBlockUnsafe(regs.offset_in, tmp_buffer.data(), - regs.line_length_in); - for (u32 offset = 0; offset < regs.line_length_in; ++offset) { - dst_buffer[convert_linear_2_blocklinear_addr(regs.offset_out + offset) - - regs.offset_out] = tmp_buffer[offset]; + UNIMPLEMENTED_IF(regs.line_length_in % 16 != 0); + UNIMPLEMENTED_IF(regs.offset_in % 16 != 0); + UNIMPLEMENTED_IF(regs.offset_out % 16 != 0); + std::vector tmp_buffer(16); + for (u32 offset = 0; offset < regs.line_length_in; offset += 16) { + memory_manager.ReadBlockUnsafe(regs.offset_in + offset, tmp_buffer.data(), + tmp_buffer.size()); + memory_manager.WriteBlock( + convert_linear_2_blocklinear_addr(regs.offset_out + offset), + tmp_buffer.data(), tmp_buffer.size()); } - memory_manager.WriteBlock(regs.offset_out, dst_buffer.data(), regs.line_length_in); } else { if (!accelerate.BufferCopy(regs.offset_in, regs.offset_out, regs.line_length_in)) { std::vector tmp_buffer(regs.line_length_in); diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index f53f52beb..3268ff08d 100755 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -76,7 +76,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key, } break; case Shader::Stage::TessellationEval: - // Flip the face, as opengl's drawing is also flipped + // Flip the face, as OpenGL's drawing is flipped. info.tess_clockwise = key.tessellation_clockwise == 0; info.tess_primitive = [&key] { switch (key.tessellation_primitive) { diff --git a/src/yuzu/compatdb.cpp b/src/yuzu/compatdb.cpp index 91f1269be..37f512531 100755 --- a/src/yuzu/compatdb.cpp +++ b/src/yuzu/compatdb.cpp @@ -158,7 +158,7 @@ int CompatDB::nextId() const { case CompatDBPage::Audio: return static_cast(CompatDBPage::Final); case CompatDBPage::Final: - return static_cast(CompatDBPage::Final); + return -1; default: LOG_ERROR(Frontend, "Unexpected page: {}", currentId()); return static_cast(CompatDBPage::Intro); diff --git a/src/yuzu/compatdb.ui b/src/yuzu/compatdb.ui index c74006782..05d14c197 100755 --- a/src/yuzu/compatdb.ui +++ b/src/yuzu/compatdb.ui @@ -291,7 +291,7 @@ - None Everything is rendered as it looks on the Nintendo Switch + None Everything is rendered as it looks on the Nintendo Switch @@ -350,7 +350,7 @@ - None Audio is played perfectly + None Audio is played perfectly