From 1f43e53a8296af7698bbb3a99f3911f2b1676675 Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Wed, 23 Nov 2022 01:24:32 +0100 Subject: [PATCH] early-access version 3144 --- README.md | 2 +- src/core/hle/kernel/k_handle_table.cpp | 17 ++++ src/core/hle/kernel/k_handle_table.h | 16 +--- src/video_core/engines/maxwell_3d.cpp | 116 ++++++++++++------------- src/video_core/engines/maxwell_3d.h | 8 +- 5 files changed, 82 insertions(+), 77 deletions(-) diff --git a/README.md b/README.md index 70517d174..6c023e629 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 3143. +This is the source code for early-access 3144. ## Legal Notice diff --git a/src/core/hle/kernel/k_handle_table.cpp b/src/core/hle/kernel/k_handle_table.cpp index 16cbdc001..4a6933408 100755 --- a/src/core/hle/kernel/k_handle_table.cpp +++ b/src/core/hle/kernel/k_handle_table.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/kernel/k_handle_table.h" +#include "core/hle/kernel/k_process.h" namespace Kernel { @@ -82,6 +83,22 @@ Result KHandleTable::Add(Handle* out_handle, KAutoObject* obj) { R_SUCCEED(); } +KScopedAutoObject KHandleTable::GetObjectForIpc(Handle handle, + KThread* cur_thread) const { + // Handle pseudo-handles. + ASSERT(cur_thread != nullptr); + if (handle == Svc::PseudoHandle::CurrentProcess) { + auto* const cur_process = cur_thread->GetOwnerProcess(); + ASSERT(cur_process != nullptr); + return cur_process; + } + if (handle == Svc::PseudoHandle::CurrentThread) { + return cur_thread; + } + + return GetObjectForIpcWithoutPseudoHandle(handle); +} + Result KHandleTable::Reserve(Handle* out_handle) { KScopedDisableDispatch dd{m_kernel}; KScopedSpinLock lk(m_lock); diff --git a/src/core/hle/kernel/k_handle_table.h b/src/core/hle/kernel/k_handle_table.h index a9403a139..583d3a485 100755 --- a/src/core/hle/kernel/k_handle_table.h +++ b/src/core/hle/kernel/k_handle_table.h @@ -113,21 +113,7 @@ public: return this->GetObjectImpl(handle); } - KScopedAutoObject GetObjectForIpc(Handle handle, KThread* cur_thread) const { - // Handle pseudo-handles. - ASSERT(cur_thread != nullptr); - if (handle == Svc::PseudoHandle::CurrentProcess) { - auto* const cur_process = - static_cast(static_cast(cur_thread->GetOwnerProcess())); - ASSERT(cur_process != nullptr); - return cur_process; - } - if (handle == Svc::PseudoHandle::CurrentThread) { - return static_cast(cur_thread); - } - - return GetObjectForIpcWithoutPseudoHandle(handle); - } + KScopedAutoObject GetObjectForIpc(Handle handle, KThread* cur_thread) const; KScopedAutoObject GetObjectByIndex(Handle* out_handle, size_t index) const { KScopedDisableDispatch dd{m_kernel}; diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 3a60abb08..e882f0514 100755 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -126,6 +126,7 @@ void Maxwell3D::InitializeRegisterDefaults() { draw_command[MAXWELL3D_REG_INDEX(draw_inline_index)] = true; draw_command[MAXWELL3D_REG_INDEX(inline_index_2x16.even)] = true; draw_command[MAXWELL3D_REG_INDEX(inline_index_4x8.index0)] = true; + draw_command[MAXWELL3D_REG_INDEX(draw.instance_id)] = true; } void Maxwell3D::ProcessMacro(u32 method, const u32* base_start, u32 amount, bool is_last_call) { @@ -288,31 +289,58 @@ void Maxwell3D::CallMethod(u32 method, u32 method_argument, bool is_last_call) { ASSERT_MSG(method < Regs::NUM_REGS, "Invalid Maxwell3D register, increase the size of the Regs structure"); + const u32 argument = ProcessShadowRam(method, method_argument); + ProcessDirtyRegisters(method, argument); + if (draw_command[method]) { regs.reg_array[method] = method_argument; deferred_draw_method.push_back(method); - auto u32_to_u8 = [&](const u32 argument) { - inline_index_draw_indexes.push_back(static_cast(argument & 0x000000ff)); - inline_index_draw_indexes.push_back(static_cast((argument & 0x0000ff00) >> 8)); - inline_index_draw_indexes.push_back(static_cast((argument & 0x00ff0000) >> 16)); - inline_index_draw_indexes.push_back(static_cast((argument & 0xff000000) >> 24)); + auto update_inline_index = [&](const u32 index) { + inline_index_draw_indexes.push_back(static_cast(index & 0x000000ff)); + inline_index_draw_indexes.push_back(static_cast((index & 0x0000ff00) >> 8)); + inline_index_draw_indexes.push_back(static_cast((index & 0x00ff0000) >> 16)); + inline_index_draw_indexes.push_back(static_cast((index & 0xff000000) >> 24)); + draw_mode = DrawMode::InlineIndex; }; - if (MAXWELL3D_REG_INDEX(draw_inline_index) == method) { - u32_to_u8(method_argument); - } else if (MAXWELL3D_REG_INDEX(inline_index_2x16.even) == method) { - u32_to_u8(regs.inline_index_2x16.even); - u32_to_u8(regs.inline_index_2x16.odd); - } else if (MAXWELL3D_REG_INDEX(inline_index_4x8.index0) == method) { - u32_to_u8(regs.inline_index_4x8.index0); - u32_to_u8(regs.inline_index_4x8.index1); - u32_to_u8(regs.inline_index_4x8.index2); - u32_to_u8(regs.inline_index_4x8.index3); + switch (method) { + case MAXWELL3D_REG_INDEX(draw.end): + switch (draw_mode) { + case DrawMode::General: + ProcessDraw(1); + break; + case DrawMode::InlineIndex: + regs.index_buffer.count = static_cast(inline_index_draw_indexes.size() / 4); + regs.index_buffer.format = Regs::IndexFormat::UnsignedInt; + ProcessDraw(1); + inline_index_draw_indexes.clear(); + break; + case DrawMode::Instance: + break; + } + break; + case MAXWELL3D_REG_INDEX(draw_inline_index): + update_inline_index(method_argument); + break; + case MAXWELL3D_REG_INDEX(inline_index_2x16.even): + update_inline_index(regs.inline_index_2x16.even); + update_inline_index(regs.inline_index_2x16.odd); + break; + case MAXWELL3D_REG_INDEX(inline_index_4x8.index0): + update_inline_index(regs.inline_index_4x8.index0); + update_inline_index(regs.inline_index_4x8.index1); + update_inline_index(regs.inline_index_4x8.index2); + update_inline_index(regs.inline_index_4x8.index3); + break; + case MAXWELL3D_REG_INDEX(draw.instance_id): + draw_mode = + (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Subsequent) || + (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Unchanged) + ? DrawMode::Instance + : DrawMode::General; + break; } } else { ProcessDeferredDraw(); - - const u32 argument = ProcessShadowRam(method, method_argument); - ProcessDirtyRegisters(method, argument); ProcessMethodCall(method, argument, method_argument, is_last_call); } } @@ -626,57 +654,27 @@ void Maxwell3D::ProcessDraw(u32 instance_count) { } void Maxwell3D::ProcessDeferredDraw() { - if (deferred_draw_method.empty()) { + if (draw_mode != DrawMode::Instance || deferred_draw_method.empty()) { return; } - enum class DrawMode { - Undefined, - General, - Instance, - }; - DrawMode draw_mode{DrawMode::Undefined}; u32 method_count = static_cast(deferred_draw_method.size()); - u32 method = deferred_draw_method[method_count - 1]; - if (MAXWELL3D_REG_INDEX(draw.end) != method) { - return; - } - draw_mode = (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Subsequent) || - (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Unchanged) - ? DrawMode::Instance - : DrawMode::General; - u32 instance_count = 0; - if (draw_mode == DrawMode::Instance) { - u32 vertex_buffer_count = 0; - u32 index_buffer_count = 0; - for (u32 index = 0; index < method_count; ++index) { - method = deferred_draw_method[index]; - if (method == MAXWELL3D_REG_INDEX(vertex_buffer.count)) { - instance_count = ++vertex_buffer_count; - } else if (method == MAXWELL3D_REG_INDEX(index_buffer.count)) { - instance_count = ++index_buffer_count; - } - } - ASSERT_MSG(!(vertex_buffer_count && index_buffer_count), - "Instance both indexed and direct?"); - } else { - instance_count = 1; - for (u32 index = 0; index < method_count; ++index) { - method = deferred_draw_method[index]; - if (MAXWELL3D_REG_INDEX(draw_inline_index) == method || - MAXWELL3D_REG_INDEX(inline_index_2x16.even) == method || - MAXWELL3D_REG_INDEX(inline_index_4x8.index0) == method) { - regs.index_buffer.count = static_cast(inline_index_draw_indexes.size() / 4); - regs.index_buffer.format = Regs::IndexFormat::UnsignedInt; - break; - } + u32 instance_count = 1; + u32 vertex_buffer_count = 0; + u32 index_buffer_count = 0; + for (u32 index = 0; index < method_count; ++index) { + u32 method = deferred_draw_method[index]; + if (method == MAXWELL3D_REG_INDEX(vertex_buffer.count)) { + instance_count = ++vertex_buffer_count; + } else if (method == MAXWELL3D_REG_INDEX(index_buffer.count)) { + instance_count = ++index_buffer_count; } } + ASSERT_MSG(!(vertex_buffer_count && index_buffer_count), "Instance both indexed and direct?"); ProcessDraw(instance_count); deferred_draw_method.clear(); - inline_index_draw_indexes.clear(); } } // namespace Tegra::Engines diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 13a5e370c..ffb9f275f 100755 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -3148,10 +3148,12 @@ private: /// Handles use of topology overrides (e.g., to avoid using a topology assigned from a macro) void ProcessTopologyOverride(); - void ProcessDraw(u32 instance_count = 1); - + /// Handles deferred draw(e.g., instance draw). void ProcessDeferredDraw(); + /// Handles a draw. + void ProcessDraw(u32 instance_count = 1); + /// Returns a query's value or an empty object if the value will be deferred through a cache. std::optional GetQueryResult(); @@ -3178,6 +3180,8 @@ private: std::array draw_command{}; std::vector deferred_draw_method; + enum class DrawMode : u32 { General = 0, Instance, InlineIndex }; + DrawMode draw_mode{DrawMode::General}; }; #define ASSERT_REG_POSITION(field_name, position) \