From 6f5c75886587f0d258818c003e95c1fe52cd419a Mon Sep 17 00:00:00 2001 From: lizzie Date: Sat, 21 Mar 2026 18:06:49 +0000 Subject: [PATCH] [video_core/engines/maxwell3d] memory inline DrawState to reduce indirection on hot paths Signed-off-by: lizzie --- src/video_core/CMakeLists.txt | 1 - src/video_core/buffer_cache/buffer_cache.h | 32 +-- .../buffer_cache/buffer_cache_base.h | 6 +- src/video_core/engines/draw_manager.cpp | 246 ++++++++---------- src/video_core/engines/draw_manager.h | 117 --------- src/video_core/engines/maxwell_3d.cpp | 13 +- src/video_core/engines/maxwell_3d.h | 73 +++++- src/video_core/gpu_thread.cpp | 6 +- src/video_core/macro.cpp | 32 +-- .../renderer_opengl/gl_rasterizer.cpp | 18 +- .../renderer_opengl/gl_shader_cache.cpp | 6 +- .../renderer_vulkan/fixed_pipeline_state.cpp | 6 +- .../renderer_vulkan/vk_pipeline_cache.cpp | 2 +- .../renderer_vulkan/vk_query_cache.cpp | 4 +- .../renderer_vulkan/vk_rasterizer.cpp | 23 +- 15 files changed, 233 insertions(+), 352 deletions(-) delete mode 100644 src/video_core/engines/draw_manager.h diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 3324682639..259e4801d3 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -44,7 +44,6 @@ add_library(video_core STATIC engines/sw_blitter/converter.h engines/const_buffer_info.h engines/draw_manager.cpp - engines/draw_manager.h engines/engine_interface.h engines/engine_upload.cpp engines/engine_upload.h diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 014b4a318e..83c94b2fc3 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -356,7 +356,7 @@ void BufferCache

::BindHostGeometryBuffers(bool is_indexed) { if (is_indexed) { BindHostIndexBuffer(); } else if constexpr (!HAS_FULL_INDEX_AND_PRIMITIVE_SUPPORT) { - const auto& draw_state = maxwell3d->draw_manager->GetDrawState(); + const auto& draw_state = maxwell3d->draw_manager.draw_state; if (draw_state.topology == Maxwell::PrimitiveTopology::Quads || draw_state.topology == Maxwell::PrimitiveTopology::QuadStrip) { runtime.BindQuadIndexBuffer(draw_state.topology, draw_state.vertex_buffer.first, @@ -740,30 +740,25 @@ void BufferCache

::BindHostIndexBuffer() { TouchBuffer(buffer, channel_state->index_buffer.buffer_id); const u32 offset = buffer.Offset(channel_state->index_buffer.device_addr); const u32 size = channel_state->index_buffer.size; - const auto& draw_state = maxwell3d->draw_manager->GetDrawState(); - if (!draw_state.inline_index_draw_indexes.empty()) [[unlikely]] { + const auto& draw_state = maxwell3d->draw_manager.draw_state; + if (draw_state.inline_index_draw_indexes.empty()) { + SynchronizeBuffer(buffer, channel_state->index_buffer.device_addr, size); + } else { if constexpr (USE_MEMORY_MAPS_FOR_UPLOADS) { auto upload_staging = runtime.UploadStagingBuffer(size); - std::array copies{ - {BufferCopy{.src_offset = upload_staging.offset, .dst_offset = 0, .size = size}}}; - std::memcpy(upload_staging.mapped_span.data(), - draw_state.inline_index_draw_indexes.data(), size); + std::array copies{{BufferCopy{.src_offset = upload_staging.offset, .dst_offset = 0, .size = size}}}; + std::memcpy(upload_staging.mapped_span.data(), draw_state.inline_index_draw_indexes.data(), size); runtime.CopyBuffer(buffer, upload_staging.buffer, copies, true); } else { buffer.ImmediateUpload(0, draw_state.inline_index_draw_indexes); } - } else { - SynchronizeBuffer(buffer, channel_state->index_buffer.device_addr, size); } if constexpr (HAS_FULL_INDEX_AND_PRIMITIVE_SUPPORT) { - const u32 new_offset = - offset + draw_state.index_buffer.first * draw_state.index_buffer.FormatSizeInBytes(); + const u32 new_offset = offset + draw_state.index_buffer.first * draw_state.index_buffer.FormatSizeInBytes(); runtime.BindIndexBuffer(buffer, new_offset, size); } else { buffer.MarkUsage(offset, size); - runtime.BindIndexBuffer(draw_state.topology, draw_state.index_buffer.format, - draw_state.index_buffer.first, draw_state.index_buffer.count, - buffer, offset, size); + runtime.BindIndexBuffer(draw_state.topology, draw_state.index_buffer.format, draw_state.index_buffer.first, draw_state.index_buffer.count, buffer, offset, size); } } @@ -945,10 +940,9 @@ void BufferCache

::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32 return alignment > 1 && (offset % alignment) != 0; } }(); - const bool use_fast_buffer = needs_alignment_stream || - (has_host_buffer && - size <= channel_state->uniform_buffer_skip_cache_size && - !memory_tracker.IsRegionGpuModified(device_addr, size)); + const bool use_fast_buffer = needs_alignment_stream + || (has_host_buffer && size <= channel_state->uniform_buffer_skip_cache_size + && !memory_tracker.IsRegionGpuModified(device_addr, size)); if (use_fast_buffer) { if constexpr (IS_OPENGL) { if (runtime.HasFastBufferSubData()) { @@ -1226,7 +1220,7 @@ template void BufferCache

::UpdateIndexBuffer() { // We have to check for the dirty flags and index count // The index count is currently changed without updating the dirty flags - const auto& draw_state = maxwell3d->draw_manager->GetDrawState(); + const auto& draw_state = maxwell3d->draw_manager.draw_state; const auto& index_buffer_ref = draw_state.index_buffer; auto& flags = maxwell3d->dirty.flags; if (!flags[Dirty::IndexBuffer]) { diff --git a/src/video_core/buffer_cache/buffer_cache_base.h b/src/video_core/buffer_cache/buffer_cache_base.h index 08524bd854..473cc6842e 100644 --- a/src/video_core/buffer_cache/buffer_cache_base.h +++ b/src/video_core/buffer_cache/buffer_cache_base.h @@ -32,7 +32,7 @@ #include "video_core/control/channel_state_cache.h" #include "video_core/delayed_destruction_ring.h" #include "video_core/dirty_flags.h" -#include "video_core/engines/draw_manager.h" +#include "video_core/engines/maxwell_3d.h" #include "video_core/engines/kepler_compute.h" #include "video_core/engines/maxwell_3d.h" #include "video_core/memory_manager.h" @@ -305,7 +305,7 @@ public: [[nodiscard]] bool IsRegionCpuModified(DAddr addr, size_t size); void SetDrawIndirect( - const Tegra::Engines::DrawManager::IndirectParams* current_draw_indirect_) { + const Tegra::Engines::Maxwell3D::DrawManager::IndirectParams* current_draw_indirect_) { current_draw_indirect = current_draw_indirect_; } @@ -480,7 +480,7 @@ private: #endif DelayedDestructionRing delayed_destruction_ring; - const Tegra::Engines::DrawManager::IndirectParams* current_draw_indirect{}; + const Tegra::Engines::Maxwell3D::DrawManager::IndirectParams* current_draw_indirect{}; u32 last_index_count = 0; diff --git a/src/video_core/engines/draw_manager.cpp b/src/video_core/engines/draw_manager.cpp index 971025cb55..079c7bdc09 100644 --- a/src/video_core/engines/draw_manager.cpp +++ b/src/video_core/engines/draw_manager.cpp @@ -1,23 +1,24 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "common/settings.h" #include "video_core/dirty_flags.h" -#include "video_core/engines/draw_manager.h" +#include "video_core/engines/maxwell_3d.h" #include "video_core/rasterizer_interface.h" namespace Tegra::Engines { -DrawManager::DrawManager(Maxwell3D* maxwell3d_) : maxwell3d(maxwell3d_) {} -void DrawManager::ProcessMethodCall(u32 method, u32 argument) { - const auto& regs{maxwell3d->regs}; +void Maxwell3D::DrawManager::ProcessMethodCall(Maxwell3D& maxwell3d, u32 method, u32 argument) { switch (method) { case MAXWELL3D_REG_INDEX(clear_surface): - return Clear(1); + return Clear(maxwell3d, 1); case MAXWELL3D_REG_INDEX(draw.begin): - return DrawBegin(); + return DrawBegin(maxwell3d); case MAXWELL3D_REG_INDEX(draw.end): - return DrawEnd(); + return DrawEnd(maxwell3d); case MAXWELL3D_REG_INDEX(vertex_buffer.first): case MAXWELL3D_REG_INDEX(vertex_buffer.count): case MAXWELL3D_REG_INDEX(index_buffer.first): @@ -33,33 +34,29 @@ void DrawManager::ProcessMethodCall(u32 method, u32 argument) { case MAXWELL3D_REG_INDEX(index_buffer32_first): case MAXWELL3D_REG_INDEX(index_buffer16_first): case MAXWELL3D_REG_INDEX(index_buffer8_first): - return DrawIndexSmall(argument); + return DrawIndexSmall(maxwell3d, argument); case MAXWELL3D_REG_INDEX(draw_inline_index): - SetInlineIndexBuffer(argument); + SetInlineIndexBuffer(maxwell3d, argument); break; case MAXWELL3D_REG_INDEX(inline_index_2x16.even): - SetInlineIndexBuffer(regs.inline_index_2x16.even); - SetInlineIndexBuffer(regs.inline_index_2x16.odd); + SetInlineIndexBuffer(maxwell3d, maxwell3d.regs.inline_index_2x16.even); + SetInlineIndexBuffer(maxwell3d, maxwell3d.regs.inline_index_2x16.odd); break; case MAXWELL3D_REG_INDEX(inline_index_4x8.index0): - SetInlineIndexBuffer(regs.inline_index_4x8.index0); - SetInlineIndexBuffer(regs.inline_index_4x8.index1); - SetInlineIndexBuffer(regs.inline_index_4x8.index2); - SetInlineIndexBuffer(regs.inline_index_4x8.index3); + SetInlineIndexBuffer(maxwell3d, maxwell3d.regs.inline_index_4x8.index0); + SetInlineIndexBuffer(maxwell3d, maxwell3d.regs.inline_index_4x8.index1); + SetInlineIndexBuffer(maxwell3d, maxwell3d.regs.inline_index_4x8.index2); + SetInlineIndexBuffer(maxwell3d, maxwell3d.regs.inline_index_4x8.index3); break; case MAXWELL3D_REG_INDEX(vertex_array_instance_first): - DrawArrayInstanced(regs.vertex_array_instance_first.topology.Value(), - regs.vertex_array_instance_first.start.Value(), - regs.vertex_array_instance_first.count.Value(), false); + DrawArrayInstanced(maxwell3d, maxwell3d.regs.vertex_array_instance_first.topology.Value(), maxwell3d.regs.vertex_array_instance_first.start.Value(), maxwell3d.regs.vertex_array_instance_first.count.Value(), false); break; case MAXWELL3D_REG_INDEX(vertex_array_instance_subsequent): { - DrawArrayInstanced(regs.vertex_array_instance_subsequent.topology.Value(), - regs.vertex_array_instance_subsequent.start.Value(), - regs.vertex_array_instance_subsequent.count.Value(), true); + DrawArrayInstanced(maxwell3d, maxwell3d.regs.vertex_array_instance_subsequent.topology.Value(), maxwell3d.regs.vertex_array_instance_subsequent.start.Value(), maxwell3d.regs.vertex_array_instance_subsequent.count.Value(), true); break; } case MAXWELL3D_REG_INDEX(draw_texture.src_y0): { - DrawTexture(); + DrawTexture(maxwell3d); break; } default: @@ -67,101 +64,87 @@ void DrawManager::ProcessMethodCall(u32 method, u32 argument) { } } -void DrawManager::Clear(u32 layer_count) { - if (maxwell3d->ShouldExecute()) { - maxwell3d->rasterizer->Clear(layer_count); +void Maxwell3D::DrawManager::Clear(Maxwell3D& maxwell3d, u32 layer_count) { + if (maxwell3d.ShouldExecute()) { + maxwell3d.rasterizer->Clear(layer_count); } } -void DrawManager::DrawDeferred() { +void Maxwell3D::DrawManager::DrawDeferred(Maxwell3D& maxwell3d) { if (draw_state.draw_mode != DrawMode::Instance || draw_state.instance_count == 0) { return; } - DrawEnd(draw_state.instance_count + 1, true); + DrawEnd(maxwell3d, draw_state.instance_count + 1, true); draw_state.instance_count = 0; } -void DrawManager::DrawArray(PrimitiveTopology topology, u32 vertex_first, u32 vertex_count, - u32 base_instance, u32 num_instances) { +void Maxwell3D::DrawManager::DrawArray(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 vertex_first, u32 vertex_count, u32 base_instance, u32 num_instances) { draw_state.topology = topology; draw_state.vertex_buffer.first = vertex_first; draw_state.vertex_buffer.count = vertex_count; draw_state.base_instance = base_instance; - ProcessDraw(false, num_instances); + ProcessDraw(maxwell3d, false, num_instances); } -void DrawManager::DrawArrayInstanced(PrimitiveTopology topology, u32 vertex_first, u32 vertex_count, - bool subsequent) { +void Maxwell3D::DrawManager::DrawArrayInstanced(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 vertex_first, u32 vertex_count, bool subsequent) { draw_state.topology = topology; draw_state.vertex_buffer.first = vertex_first; draw_state.vertex_buffer.count = vertex_count; - if (!subsequent) { draw_state.instance_count = 1; } - draw_state.base_instance = draw_state.instance_count - 1; draw_state.draw_mode = DrawMode::Instance; draw_state.instance_count++; - ProcessDraw(false, 1); + ProcessDraw(maxwell3d, false, 1); } -void DrawManager::DrawIndex(PrimitiveTopology topology, u32 index_first, u32 index_count, - u32 base_index, u32 base_instance, u32 num_instances) { - const auto& regs{maxwell3d->regs}; +void Maxwell3D::DrawManager::DrawIndex(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 index_first, u32 index_count, u32 base_index, u32 base_instance, u32 num_instances) { draw_state.topology = topology; - draw_state.index_buffer = regs.index_buffer; + draw_state.index_buffer = maxwell3d.regs.index_buffer; draw_state.index_buffer.first = index_first; draw_state.index_buffer.count = index_count; draw_state.base_index = base_index; draw_state.base_instance = base_instance; - ProcessDraw(true, num_instances); + ProcessDraw(maxwell3d, true, num_instances); } -void DrawManager::DrawArrayIndirect(PrimitiveTopology topology) { +void Maxwell3D::DrawManager::DrawArrayIndirect(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology) { draw_state.topology = topology; - - ProcessDrawIndirect(); + ProcessDrawIndirect(maxwell3d); } -void DrawManager::DrawIndexedIndirect(PrimitiveTopology topology, u32 index_first, - u32 index_count) { - const auto& regs{maxwell3d->regs}; +void Maxwell3D::DrawManager::DrawIndexedIndirect(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 index_first, u32 index_count) { draw_state.topology = topology; - draw_state.index_buffer = regs.index_buffer; + draw_state.index_buffer = maxwell3d.regs.index_buffer; draw_state.index_buffer.first = index_first; draw_state.index_buffer.count = index_count; - - ProcessDrawIndirect(); + ProcessDrawIndirect(maxwell3d); } -void DrawManager::SetInlineIndexBuffer(u32 index) { - draw_state.inline_index_draw_indexes.push_back(static_cast(index & 0x000000ff)); - draw_state.inline_index_draw_indexes.push_back(static_cast((index & 0x0000ff00) >> 8)); - draw_state.inline_index_draw_indexes.push_back(static_cast((index & 0x00ff0000) >> 16)); - draw_state.inline_index_draw_indexes.push_back(static_cast((index & 0xff000000) >> 24)); +void Maxwell3D::DrawManager::SetInlineIndexBuffer(Maxwell3D& maxwell3d, u32 index) { + draw_state.inline_index_draw_indexes.push_back(u8(index & 0x000000ff)); + draw_state.inline_index_draw_indexes.push_back(u8((index & 0x0000ff00) >> 8)); + draw_state.inline_index_draw_indexes.push_back(u8((index & 0x00ff0000) >> 16)); + draw_state.inline_index_draw_indexes.push_back(u8((index & 0xff000000) >> 24)); draw_state.draw_mode = DrawMode::InlineIndex; } -void DrawManager::DrawBegin() { - const auto& regs{maxwell3d->regs}; - auto reset_instance_count = regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::First; - auto increment_instance_count = - regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Subsequent; +void Maxwell3D::DrawManager::DrawBegin(Maxwell3D& maxwell3d) { + auto reset_instance_count = maxwell3d.regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::First; + auto increment_instance_count = maxwell3d.regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Subsequent; if (reset_instance_count) { - DrawDeferred(); + DrawDeferred(maxwell3d); draw_state.instance_count = 0; draw_state.draw_mode = DrawMode::General; } else if (increment_instance_count) { draw_state.instance_count++; draw_state.draw_mode = DrawMode::Instance; } - - draw_state.topology = regs.draw.topology; + draw_state.topology = maxwell3d.regs.draw.topology; } -void DrawManager::DrawEnd(u32 instance_count, bool force_draw) { - const auto& regs{maxwell3d->regs}; +void Maxwell3D::DrawManager::DrawEnd(Maxwell3D& maxwell3d, u32 instance_count, bool force_draw) { switch (draw_state.draw_mode) { case DrawMode::Instance: if (!force_draw) { @@ -169,119 +152,100 @@ void DrawManager::DrawEnd(u32 instance_count, bool force_draw) { } [[fallthrough]]; case DrawMode::General: - draw_state.base_instance = regs.global_base_instance_index; - draw_state.base_index = regs.global_base_vertex_index; + draw_state.base_instance = maxwell3d.regs.global_base_instance_index; + draw_state.base_index = maxwell3d.regs.global_base_vertex_index; if (draw_state.draw_indexed) { - draw_state.index_buffer = regs.index_buffer; - ProcessDraw(true, instance_count); + draw_state.index_buffer = maxwell3d.regs.index_buffer; + ProcessDraw(maxwell3d, true, instance_count); } else { - draw_state.vertex_buffer = regs.vertex_buffer; - ProcessDraw(false, instance_count); + draw_state.vertex_buffer = maxwell3d.regs.vertex_buffer; + ProcessDraw(maxwell3d, false, instance_count); } draw_state.draw_indexed = false; break; case DrawMode::InlineIndex: - draw_state.base_instance = regs.global_base_instance_index; - draw_state.base_index = regs.global_base_vertex_index; - draw_state.index_buffer = regs.index_buffer; - draw_state.index_buffer.count = - static_cast(draw_state.inline_index_draw_indexes.size() / 4); + draw_state.base_instance = maxwell3d.regs.global_base_instance_index; + draw_state.base_index = maxwell3d.regs.global_base_vertex_index; + draw_state.index_buffer = maxwell3d.regs.index_buffer; + draw_state.index_buffer.count = u32(draw_state.inline_index_draw_indexes.size() / 4); draw_state.index_buffer.format = Maxwell3D::Regs::IndexFormat::UnsignedInt; - maxwell3d->dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; - ProcessDraw(true, instance_count); + maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; + ProcessDraw(maxwell3d, true, instance_count); draw_state.inline_index_draw_indexes.clear(); break; } } -void DrawManager::DrawIndexSmall(u32 argument) { - const auto& regs{maxwell3d->regs}; - IndexBufferSmall index_small_params{argument}; - draw_state.base_instance = regs.global_base_instance_index; - draw_state.base_index = regs.global_base_vertex_index; - draw_state.index_buffer = regs.index_buffer; +void Maxwell3D::DrawManager::DrawIndexSmall(Maxwell3D& maxwell3d, u32 argument) { + Maxwell3D::Regs::IndexBufferSmall index_small_params{argument}; + draw_state.base_instance = maxwell3d.regs.global_base_instance_index; + draw_state.base_index = maxwell3d.regs.global_base_vertex_index; + draw_state.index_buffer = maxwell3d.regs.index_buffer; draw_state.index_buffer.first = index_small_params.first; draw_state.index_buffer.count = index_small_params.count; draw_state.topology = index_small_params.topology; - maxwell3d->dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; - ProcessDraw(true, 1); + maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; + ProcessDraw(maxwell3d, true, 1); } -void DrawManager::DrawTexture() { - const auto& regs{maxwell3d->regs}; - draw_texture_state.dst_x0 = static_cast(regs.draw_texture.dst_x0) / 4096.f; - draw_texture_state.dst_y0 = static_cast(regs.draw_texture.dst_y0) / 4096.f; - const auto dst_width = static_cast(regs.draw_texture.dst_width) / 4096.f; - const auto dst_height = static_cast(regs.draw_texture.dst_height) / 4096.f; - const bool lower_left{regs.window_origin.mode != - Maxwell3D::Regs::WindowOrigin::Mode::UpperLeft}; +void Maxwell3D::DrawManager::DrawTexture(Maxwell3D& maxwell3d) { + draw_texture_state.dst_x0 = f32(maxwell3d.regs.draw_texture.dst_x0) / 4096.f; + draw_texture_state.dst_y0 = f32(maxwell3d.regs.draw_texture.dst_y0) / 4096.f; + const auto dst_width = f32(maxwell3d.regs.draw_texture.dst_width) / 4096.f; + const auto dst_height = f32(maxwell3d.regs.draw_texture.dst_height) / 4096.f; + const bool lower_left{maxwell3d.regs.window_origin.mode != Maxwell3D::Regs::WindowOrigin::Mode::UpperLeft}; if (lower_left) { - draw_texture_state.dst_y0 = - static_cast(regs.surface_clip.height) - draw_texture_state.dst_y0; + draw_texture_state.dst_y0 = f32(maxwell3d.regs.surface_clip.height) - draw_texture_state.dst_y0; } draw_texture_state.dst_x1 = draw_texture_state.dst_x0 + dst_width; draw_texture_state.dst_y1 = draw_texture_state.dst_y0 + dst_height; - draw_texture_state.src_x0 = static_cast(regs.draw_texture.src_x0) / 4096.f; - draw_texture_state.src_y0 = static_cast(regs.draw_texture.src_y0) / 4096.f; - draw_texture_state.src_x1 = - (static_cast(regs.draw_texture.dx_du) / 4294967296.f) * dst_width + - draw_texture_state.src_x0; - draw_texture_state.src_y1 = - (static_cast(regs.draw_texture.dy_dv) / 4294967296.f) * dst_height + - draw_texture_state.src_y0; - draw_texture_state.src_sampler = regs.draw_texture.src_sampler; - draw_texture_state.src_texture = regs.draw_texture.src_texture; - maxwell3d->rasterizer->DrawTexture(); -} - -void DrawManager::UpdateTopology() { - const auto& regs{maxwell3d->regs}; - switch (regs.primitive_topology_control) { - case PrimitiveTopologyControl::UseInBeginMethods: + draw_texture_state.src_x0 = f32(maxwell3d.regs.draw_texture.src_x0) / 4096.f; + draw_texture_state.src_y0 = f32(maxwell3d.regs.draw_texture.src_y0) / 4096.f; + draw_texture_state.src_x1 = (f32(maxwell3d.regs.draw_texture.dx_du) / 4294967296.f) * dst_width + draw_texture_state.src_x0; + draw_texture_state.src_y1 = (f32(maxwell3d.regs.draw_texture.dy_dv) / 4294967296.f) * dst_height + draw_texture_state.src_y0; + draw_texture_state.src_sampler = maxwell3d.regs.draw_texture.src_sampler; + draw_texture_state.src_texture = maxwell3d.regs.draw_texture.src_texture; + maxwell3d.rasterizer->DrawTexture(); +} + +void Maxwell3D::DrawManager::UpdateTopology(Maxwell3D& maxwell3d) { + switch (maxwell3d.regs.primitive_topology_control) { + case Maxwell3D::Regs::PrimitiveTopologyControl::UseInBeginMethods: break; - case PrimitiveTopologyControl::UseSeparateState: - switch (regs.topology_override) { - case PrimitiveTopologyOverride::None: + case Maxwell3D::Regs::PrimitiveTopologyControl::UseSeparateState: + switch (maxwell3d.regs.topology_override) { + case Maxwell3D::Regs::PrimitiveTopologyOverride::None: break; - case PrimitiveTopologyOverride::Points: - draw_state.topology = PrimitiveTopology::Points; + case Maxwell3D::Regs::PrimitiveTopologyOverride::Points: + draw_state.topology = Maxwell3D::Regs::PrimitiveTopology::Points; break; - case PrimitiveTopologyOverride::Lines: - draw_state.topology = PrimitiveTopology::Lines; + case Maxwell3D::Regs::PrimitiveTopologyOverride::Lines: + draw_state.topology = Maxwell3D::Regs::PrimitiveTopology::Lines; break; - case PrimitiveTopologyOverride::LineStrip: - draw_state.topology = PrimitiveTopology::LineStrip; + case Maxwell3D::Regs::PrimitiveTopologyOverride::LineStrip: + draw_state.topology = Maxwell3D::Regs::PrimitiveTopology::LineStrip; break; default: - draw_state.topology = static_cast(regs.topology_override); + draw_state.topology = Maxwell3D::Regs::PrimitiveTopology(maxwell3d.regs.topology_override); break; } break; } } -void DrawManager::ProcessDraw(bool draw_indexed, u32 instance_count) { - LOG_TRACE(HW_GPU, "called, topology={}, count={}", draw_state.topology, - draw_indexed ? draw_state.index_buffer.count : draw_state.vertex_buffer.count); - - UpdateTopology(); - - if (maxwell3d->ShouldExecute()) { - maxwell3d->rasterizer->Draw(draw_indexed, instance_count); +void Maxwell3D::DrawManager::ProcessDraw(Maxwell3D& maxwell3d, bool draw_indexed, u32 instance_count) { + LOG_TRACE(HW_GPU, "called, topology={}, count={}", draw_state.topology, draw_indexed ? draw_state.index_buffer.count : draw_state.vertex_buffer.count); + UpdateTopology(maxwell3d); + if (maxwell3d.ShouldExecute()) { + maxwell3d.rasterizer->Draw(draw_indexed, instance_count); } } -void DrawManager::ProcessDrawIndirect() { - LOG_TRACE( - HW_GPU, - "called, topology={}, is_indexed={}, includes_count={}, buffer_size={}, max_draw_count={}", - draw_state.topology, indirect_state.is_indexed, indirect_state.include_count, - indirect_state.buffer_size, indirect_state.max_draw_counts); - - UpdateTopology(); - - if (maxwell3d->ShouldExecute()) { - maxwell3d->rasterizer->DrawIndirect(); +void Maxwell3D::DrawManager::ProcessDrawIndirect(Maxwell3D& maxwell3d) { + LOG_TRACE(HW_GPU, "called, topology={}, is_indexed={}, includes_count={}, buffer_size={}, max_draw_count={}", draw_state.topology, indirect_state.is_indexed, indirect_state.include_count, indirect_state.buffer_size, indirect_state.max_draw_counts); + UpdateTopology(maxwell3d); + if (maxwell3d.ShouldExecute()) { + maxwell3d.rasterizer->DrawIndirect(); } } } // namespace Tegra::Engines diff --git a/src/video_core/engines/draw_manager.h b/src/video_core/engines/draw_manager.h deleted file mode 100644 index cfc8127fc6..0000000000 --- a/src/video_core/engines/draw_manager.h +++ /dev/null @@ -1,117 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once -#include "common/common_types.h" -#include "video_core/engines/maxwell_3d.h" - -namespace VideoCore { -class RasterizerInterface; -} - -namespace Tegra::Engines { -using PrimitiveTopologyControl = Maxwell3D::Regs::PrimitiveTopologyControl; -using PrimitiveTopology = Maxwell3D::Regs::PrimitiveTopology; -using PrimitiveTopologyOverride = Maxwell3D::Regs::PrimitiveTopologyOverride; -using IndexBuffer = Maxwell3D::Regs::IndexBuffer; -using VertexBuffer = Maxwell3D::Regs::VertexBuffer; -using IndexBufferSmall = Maxwell3D::Regs::IndexBufferSmall; - -class DrawManager { -public: - enum class DrawMode : u32 { General = 0, Instance, InlineIndex }; - struct State { - PrimitiveTopology topology{}; - DrawMode draw_mode{}; - bool draw_indexed{}; - u32 base_index{}; - VertexBuffer vertex_buffer; - IndexBuffer index_buffer; - u32 base_instance{}; - u32 instance_count{}; - std::vector inline_index_draw_indexes; - }; - - struct DrawTextureState { - f32 dst_x0; - f32 dst_y0; - f32 dst_x1; - f32 dst_y1; - f32 src_x0; - f32 src_y0; - f32 src_x1; - f32 src_y1; - u32 src_sampler; - u32 src_texture; - }; - - struct IndirectParams { - bool is_byte_count; - bool is_indexed; - bool include_count; - GPUVAddr count_start_address; - GPUVAddr indirect_start_address; - size_t buffer_size; - size_t max_draw_counts; - size_t stride; - }; - - explicit DrawManager(Maxwell3D* maxwell_3d); - - void ProcessMethodCall(u32 method, u32 argument); - - void Clear(u32 layer_count); - - void DrawDeferred(); - - void DrawArray(PrimitiveTopology topology, u32 vertex_first, u32 vertex_count, - u32 base_instance, u32 num_instances); - void DrawArrayInstanced(PrimitiveTopology topology, u32 vertex_first, u32 vertex_count, - bool subsequent); - - void DrawIndex(PrimitiveTopology topology, u32 index_first, u32 index_count, u32 base_index, - u32 base_instance, u32 num_instances); - - void DrawArrayIndirect(PrimitiveTopology topology); - - void DrawIndexedIndirect(PrimitiveTopology topology, u32 index_first, u32 index_count); - - const State& GetDrawState() const { - return draw_state; - } - - const DrawTextureState& GetDrawTextureState() const { - return draw_texture_state; - } - - IndirectParams& GetIndirectParams() { - return indirect_state; - } - - const IndirectParams& GetIndirectParams() const { - return indirect_state; - } - -private: - void SetInlineIndexBuffer(u32 index); - - void DrawBegin(); - - void DrawEnd(u32 instance_count = 1, bool force_draw = false); - - void DrawIndexSmall(u32 argument); - - void DrawTexture(); - - void UpdateTopology(); - - void ProcessDraw(bool draw_indexed, u32 instance_count); - - void ProcessDrawIndirect(); - - Maxwell3D* maxwell3d{}; - State draw_state{}; - DrawTextureState draw_texture_state{}; - IndirectParams indirect_state{}; -}; -} // namespace Tegra::Engines diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 6d9ebd6296..9aaa99f7ff 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -13,7 +13,7 @@ #include "core/core.h" #include "core/core_timing.h" #include "video_core/dirty_flags.h" -#include "video_core/engines/draw_manager.h" +#include "video_core/engines/maxwell_3d.h" #include "video_core/engines/maxwell_3d.h" #include "video_core/gpu.h" #include "video_core/memory_manager.h" @@ -26,7 +26,8 @@ namespace Tegra::Engines { constexpr u32 MacroRegistersStart = 0xE00; Maxwell3D::Maxwell3D(Core::System& system_, MemoryManager& memory_manager_) - : draw_manager{std::make_unique(this)}, system{system_} + : draw_manager() + , system{system_} , memory_manager{memory_manager_} #ifdef ARCHITECTURE_x86_64 , macro_engine(bool(Settings::values.disable_macro_jit)) @@ -373,8 +374,7 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume case MAXWELL3D_REG_INDEX(sync_info): return ProcessSyncPoint(); case MAXWELL3D_REG_INDEX(launch_dma): - return upload_state.ProcessExec(regs.launch_dma.memory_layout.Value() == - Regs::LaunchDMA::Layout::Pitch); + return upload_state.ProcessExec(regs.launch_dma.memory_layout.Value() == Regs::LaunchDMA::Layout::Pitch); case MAXWELL3D_REG_INDEX(inline_data): upload_state.ProcessData(argument, is_last_call); return; @@ -386,7 +386,7 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume case MAXWELL3D_REG_INDEX(tiled_cache_barrier): return rasterizer->TiledCacheBarrier(); default: - draw_manager->ProcessMethodCall(method, argument); + draw_manager.ProcessMethodCall(*this, method, argument); break; } } @@ -401,8 +401,7 @@ void Maxwell3D::CallMacroMethod(u32 method, const std::vector& parameters) // Execute the current macro. macro_engine.Execute(*this, macro_positions[entry], parameters); - - draw_manager->DrawDeferred(); + draw_manager.DrawDeferred(*this); } void Maxwell3D::CallMethod(u32 method, u32 method_argument, bool is_last_call) { diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index b73082b7ef..3ac79e0eb8 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -25,6 +25,7 @@ #include "video_core/gpu.h" #include "video_core/macro.h" #include "video_core/textures/texture.h" +#include "video_core/engines/maxwell_3d.h" namespace Core { class System; @@ -40,8 +41,6 @@ class RasterizerInterface; namespace Tegra::Engines { -class DrawManager; - /** * This Engine is known as GF100_3D. Documentation can be found in: * https://github.com/NVIDIA/open-gpu-doc/blob/master/classes/3d/clb197.h @@ -543,7 +542,7 @@ public: } GPUVAddr StorageLimitAddress() const { return (GPUVAddr{storage_limit_address_high} << 32) | - GPUVAddr{storage_limit_address_low}; + GPUVAddr{storage_limit_address_low}; } }; @@ -819,7 +818,7 @@ public: u32 Map(std::size_t index) const { const std::array maps{target0, target1, target2, target3, - target4, target5, target6, target7}; + target4, target5, target6, target7}; ASSERT(index < maps.size()); return maps[index]; } @@ -1831,7 +1830,7 @@ public: bool AnyEnabled() const { return output0_enable || output1_enable || output2_enable || output3_enable || - output4_enable || output5_enable || output6_enable || output7_enable; + output4_enable || output5_enable || output6_enable || output7_enable; } }; @@ -1870,7 +1869,7 @@ public: bool AnyEnabled() const { return plane0 || plane1 || plane2 || plane3 || plane4 || plane5 || plane6 || - plane7; + plane7; } }; @@ -3023,8 +3022,7 @@ public: u32 bindless_texture_const_buffer_slot; ///< 0x2608 u32 trap_handler; ///< 0x260C INSERT_PADDING_BYTES_NOINIT(0x1F0); - std::array, NumTransformFeedbackBuffers> - stream_out_layout; ///< 0x2800 + std::array, NumTransformFeedbackBuffers> stream_out_layout; ///< 0x2800 INSERT_PADDING_BYTES_NOINIT(0x93C); ShaderPerformance shader_performance; ///< 0x333C INSERT_PADDING_BYTES_NOINIT(0x18); @@ -3035,6 +3033,62 @@ public: }; // clang-format on + struct DrawManager { + enum class DrawMode : u32 { General = 0, Instance, InlineIndex }; + struct State { + Maxwell3D::Regs::PrimitiveTopology topology{}; + DrawMode draw_mode{}; + bool draw_indexed{}; + u32 base_index{}; + Maxwell3D::Regs::VertexBuffer vertex_buffer; + Maxwell3D::Regs::IndexBuffer index_buffer; + u32 base_instance{}; + u32 instance_count{}; + std::vector inline_index_draw_indexes; + }; + struct DrawTextureState { + f32 dst_x0; + f32 dst_y0; + f32 dst_x1; + f32 dst_y1; + f32 src_x0; + f32 src_y0; + f32 src_x1; + f32 src_y1; + u32 src_sampler; + u32 src_texture; + }; + struct IndirectParams { + bool is_byte_count; + bool is_indexed; + bool include_count; + GPUVAddr count_start_address; + GPUVAddr indirect_start_address; + size_t buffer_size; + size_t max_draw_counts; + size_t stride; + }; + void ProcessMethodCall(Maxwell3D& maxwell3d, u32 method, u32 argument); + void Clear(Maxwell3D& maxwell3d, u32 layer_count); + void DrawDeferred(Maxwell3D& maxwell3d); + void DrawArray(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 vertex_first, u32 vertex_count, u32 base_instance, u32 num_instances); + void DrawArrayInstanced(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 vertex_first, u32 vertex_count, bool subsequent); + void DrawIndex(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 index_first, u32 index_count, u32 base_index, u32 base_instance, u32 num_instances); + void DrawArrayIndirect(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology); + void DrawIndexedIndirect(Maxwell3D& maxwell3d, Maxwell3D::Regs::PrimitiveTopology topology, u32 index_first, u32 index_count); + void SetInlineIndexBuffer(Maxwell3D& maxwell3d, u32 index); + void DrawBegin(Maxwell3D& maxwell3d); + void DrawEnd(Maxwell3D& maxwell3d, u32 instance_count = 1, bool force_draw = false); + void DrawIndexSmall(Maxwell3D& maxwell3d, u32 argument); + void DrawTexture(Maxwell3D& maxwell3d); + void UpdateTopology(Maxwell3D& maxwell3d); + void ProcessDraw(Maxwell3D& maxwell3d, bool draw_indexed, u32 instance_count); + void ProcessDrawIndirect(Maxwell3D& maxwell3d); + State draw_state{}; + DrawTextureState draw_texture_state{}; + IndirectParams indirect_state{}; + }; + Regs regs{}; /// Store temporary hw register values, used by some calls to restore state after a operation @@ -3102,8 +3156,7 @@ public: Tables tables{}; } dirty; - std::unique_ptr draw_manager; - friend class DrawManager; + DrawManager draw_manager; GPUVAddr GetMacroAddress(size_t index) const { return macro_addresses[index]; diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp index 8d8d857a02..f7cd27b0d3 100644 --- a/src/video_core/gpu_thread.cpp +++ b/src/video_core/gpu_thread.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project @@ -63,9 +63,7 @@ ThreadManager::ThreadManager(Core::System& system_, bool is_async_) ThreadManager::~ThreadManager() = default; -void ThreadManager::StartThread(VideoCore::RendererBase& renderer, - Core::Frontend::GraphicsContext& context, - Tegra::Control::Scheduler& scheduler) { +void ThreadManager::StartThread(VideoCore::RendererBase& renderer, Core::Frontend::GraphicsContext& context, Tegra::Control::Scheduler& scheduler) { rasterizer = renderer.ReadRasterizer(); thread = std::jthread(RunThread, std::ref(system), std::ref(renderer), std::ref(context), std::ref(scheduler), std::ref(state)); diff --git a/src/video_core/macro.cpp b/src/video_core/macro.cpp index 66cea5afbd..cbd21a0743 100644 --- a/src/video_core/macro.cpp +++ b/src/video_core/macro.cpp @@ -31,7 +31,7 @@ #include "common/settings.h" #include "common/container_hash.h" #include "video_core/engines/maxwell_3d.h" -#include "video_core/engines/draw_manager.h" +#include "video_core/engines/maxwell_3d.h" #include "video_core/dirty_flags.h" #include "video_core/rasterizer_interface.h" #include "video_core/macro.h" @@ -83,7 +83,7 @@ void HLE_DrawArraysIndirect::Execute(Engines::Maxwell3D& maxwell3d, std::spanGetIndirectParams(); + auto& params = maxwell3d.draw_manager.indirect_state; params.is_byte_count = false; params.is_indexed = false; params.include_count = false; @@ -98,7 +98,7 @@ void HLE_DrawArraysIndirect::Execute(Engines::Maxwell3D& maxwell3d, std::spanDrawArrayIndirect(topology); + maxwell3d.draw_manager.DrawArrayIndirect(maxwell3d, topology); if (extended) { maxwell3d.engine_state = Maxwell3D::EngineHint::None; @@ -127,7 +127,7 @@ void HLE_DrawArraysIndirect::Fallback(Engines::Maxwell3D& maxwell3d, std::spanDrawArray(topology, vertex_first, vertex_count, base_instance, instance_count); + maxwell3d.draw_manager.DrawArray(maxwell3d, topology, vertex_first, vertex_count, base_instance, instance_count); if (extended) { maxwell3d.regs.global_base_instance_index = 0; maxwell3d.engine_state = Maxwell3D::EngineHint::None; @@ -154,7 +154,7 @@ void HLE_DrawIndexedIndirect::Execute(Engines::Maxwell3D& maxwell3d, std::spanGetIndirectParams(); + auto& params = maxwell3d.draw_manager.indirect_state; params.is_byte_count = false; params.is_indexed = true; params.include_count = false; @@ -164,7 +164,7 @@ void HLE_DrawIndexedIndirect::Execute(Engines::Maxwell3D& maxwell3d, std::spanDrawIndexedIndirect(topology, 0, estimate); + maxwell3d.draw_manager.DrawIndexedIndirect(maxwell3d, topology, 0, estimate); maxwell3d.regs.vertex_id_base = 0x0; maxwell3d.regs.global_base_vertex_index = 0x0; maxwell3d.regs.global_base_instance_index = 0x0; @@ -187,7 +187,7 @@ void HLE_DrawIndexedIndirect::Fallback(Engines::Maxwell3D& maxwell3d, std::span< maxwell3d.SetHLEReplacementAttributeType(0, 0x640, Maxwell3D::HLEReplacementAttributeType::BaseVertex); maxwell3d.SetHLEReplacementAttributeType(0, 0x644, Maxwell3D::HLEReplacementAttributeType::BaseInstance); } - maxwell3d.draw_manager->DrawIndex(Tegra::Maxwell3D::Regs::PrimitiveTopology(parameters[0]), parameters[3], parameters[1], element_base, base_instance, instance_count); + maxwell3d.draw_manager.DrawIndex(maxwell3d, Tegra::Maxwell3D::Regs::PrimitiveTopology(parameters[0]), parameters[3], parameters[1], element_base, base_instance, instance_count); maxwell3d.regs.vertex_id_base = 0x0; maxwell3d.regs.global_base_vertex_index = 0x0; maxwell3d.regs.global_base_instance_index = 0x0; @@ -206,7 +206,7 @@ void HLE_MultiLayerClear::Execute(Engines::Maxwell3D& maxwell3d, std::spanClear(num_layers); + maxwell3d.draw_manager.Clear(maxwell3d, num_layers); } void HLE_MultiDrawIndexedIndirectCount::Execute(Engines::Maxwell3D& maxwell3d, std::span parameters, [[maybe_unused]] u32 method) { const auto topology = Maxwell3D::Regs::PrimitiveTopology(parameters[2]); @@ -230,7 +230,7 @@ void HLE_MultiDrawIndexedIndirectCount::Execute(Engines::Maxwell3D& maxwell3d, s const std::size_t draw_count = end_indirect - start_indirect; const u32 estimate = static_cast(maxwell3d.EstimateIndexBufferSize()); maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; - auto& params = maxwell3d.draw_manager->GetIndirectParams(); + auto& params = maxwell3d.draw_manager.indirect_state; params.is_byte_count = false; params.is_indexed = true; params.include_count = true; @@ -244,7 +244,7 @@ void HLE_MultiDrawIndexedIndirectCount::Execute(Engines::Maxwell3D& maxwell3d, s maxwell3d.SetHLEReplacementAttributeType(0, 0x640, Maxwell3D::HLEReplacementAttributeType::BaseVertex); maxwell3d.SetHLEReplacementAttributeType(0, 0x644, Maxwell3D::HLEReplacementAttributeType::BaseInstance); maxwell3d.SetHLEReplacementAttributeType(0, 0x648, Maxwell3D::HLEReplacementAttributeType::DrawID); - maxwell3d.draw_manager->DrawIndexedIndirect(topology, 0, estimate); + maxwell3d.draw_manager.DrawIndexedIndirect(maxwell3d, topology, 0, estimate); maxwell3d.engine_state = Maxwell3D::EngineHint::None; maxwell3d.replace_table.clear(); } @@ -280,7 +280,7 @@ void HLE_MultiDrawIndexedIndirectCount::Fallback(Engines::Maxwell3D& maxwell3d, maxwell3d.CallMethod(0x8e3, 0x648, true); maxwell3d.CallMethod(0x8e4, static_cast(index), true); maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; - maxwell3d.draw_manager->DrawIndex(topology, parameters[base + 2], parameters[base], base_vertex, base_instance, parameters[base + 1]); + maxwell3d.draw_manager.DrawIndex(maxwell3d, topology, parameters[base + 2], parameters[base], base_vertex, base_instance, parameters[base + 1]); } } void HLE_DrawIndirectByteCount::Execute(Engines::Maxwell3D& maxwell3d, std::span parameters, [[maybe_unused]] u32 method) { @@ -290,7 +290,7 @@ void HLE_DrawIndirectByteCount::Execute(Engines::Maxwell3D& maxwell3d, std::span Fallback(maxwell3d, parameters); return; } - auto& params = maxwell3d.draw_manager->GetIndirectParams(); + auto& params = maxwell3d.draw_manager.indirect_state; params.is_byte_count = true; params.is_indexed = false; params.include_count = false; @@ -302,18 +302,14 @@ void HLE_DrawIndirectByteCount::Execute(Engines::Maxwell3D& maxwell3d, std::span maxwell3d.regs.draw.begin = parameters[0]; maxwell3d.regs.draw_auto_stride = parameters[1]; maxwell3d.regs.draw_auto_byte_count = parameters[2]; - maxwell3d.draw_manager->DrawArrayIndirect(topology); + maxwell3d.draw_manager.DrawArrayIndirect(maxwell3d, topology); } void HLE_DrawIndirectByteCount::Fallback(Engines::Maxwell3D& maxwell3d, std::span parameters) { maxwell3d.RefreshParameters(); - maxwell3d.regs.draw.begin = parameters[0]; maxwell3d.regs.draw_auto_stride = parameters[1]; maxwell3d.regs.draw_auto_byte_count = parameters[2]; - - maxwell3d.draw_manager->DrawArray( - maxwell3d.regs.draw.topology, 0, - maxwell3d.regs.draw_auto_byte_count / maxwell3d.regs.draw_auto_stride, 0, 1); + maxwell3d.draw_manager.DrawArray(maxwell3d, maxwell3d.regs.draw.topology, 0, maxwell3d.regs.draw_auto_byte_count / maxwell3d.regs.draw_auto_stride, 0, 1); } void HLE_C713C83D8F63CCF3::Execute(Engines::Maxwell3D& maxwell3d, std::span parameters, [[maybe_unused]] u32 method) { maxwell3d.RefreshParameters(); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index e268c4d2c6..3ce367e0d3 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -245,7 +245,7 @@ void RasterizerOpenGL::PrepareDraw(bool is_indexed, Func&& draw_func) { SyncState(); - const auto& draw_state = maxwell3d->draw_manager->GetDrawState(); + const auto& draw_state = maxwell3d->draw_manager.draw_state; const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(draw_state.topology); BeginTransformFeedback(pipeline, primitive_mode); @@ -260,12 +260,12 @@ void RasterizerOpenGL::PrepareDraw(bool is_indexed, Func&& draw_func) { void RasterizerOpenGL::Draw(bool is_indexed, u32 instance_count) { PrepareDraw(is_indexed, [this, is_indexed, instance_count](GLenum primitive_mode) { - const auto& draw_state = maxwell3d->draw_manager->GetDrawState(); - const GLuint base_instance = static_cast(draw_state.base_instance); - const GLsizei num_instances = static_cast(instance_count); + const auto& draw_state = maxwell3d->draw_manager.draw_state; + const GLuint base_instance = GLuint(draw_state.base_instance); + const GLsizei num_instances = GLsizei(instance_count); if (is_indexed) { - const GLint base_vertex = static_cast(draw_state.base_index); - const GLsizei num_vertices = static_cast(draw_state.index_buffer.count); + const GLint base_vertex = GLint(draw_state.base_index); + const GLsizei num_vertices = GLsizei(draw_state.index_buffer.count); const GLvoid* const offset = buffer_cache_runtime.IndexOffset(); const GLenum format = MaxwellToGL::IndexFormat(draw_state.index_buffer.format); if (num_instances == 1 && base_instance == 0 && base_vertex == 0) { @@ -302,7 +302,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, u32 instance_count) { } void RasterizerOpenGL::DrawIndirect() { - const auto& params = maxwell3d->draw_manager->GetIndirectParams(); + const auto& params = maxwell3d->draw_manager.indirect_state; buffer_cache.SetDrawIndirect(¶ms); PrepareDraw(params.is_indexed, [this, ¶ms](GLenum primitive_mode) { if (params.is_byte_count) { @@ -358,12 +358,12 @@ void RasterizerOpenGL::DrawTexture() { SyncState(); - const auto& draw_texture_state = maxwell3d->draw_manager->GetDrawTextureState(); + const auto& draw_texture_state = maxwell3d->draw_manager.draw_texture_state; const auto& sampler = texture_cache.GetGraphicsSampler(draw_texture_state.src_sampler); const auto& texture = texture_cache.GetImageView(draw_texture_state.src_texture); const auto Scale = [&](auto dim) -> s32 { - return Settings::values.resolution_info.ScaleUp(static_cast(dim)); + return Settings::values.resolution_info.ScaleUp(s32(dim)); }; Region2D dst_region = { diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index aac7732005..18df857bc2 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -25,7 +25,7 @@ #include "shader_recompiler/frontend/maxwell/control_flow.h" #include "shader_recompiler/frontend/maxwell/translate_program.h" #include "shader_recompiler/profile.h" -#include "video_core/engines/draw_manager.h" +#include "video_core/engines/maxwell_3d.h" #include "video_core/engines/kepler_compute.h" #include "video_core/engines/maxwell_3d.h" #include "video_core/memory_manager.h" @@ -362,7 +362,7 @@ GraphicsPipeline* ShaderCache::CurrentGraphicsPipeline() { const auto& regs{maxwell3d->regs}; graphics_key.raw = 0; graphics_key.early_z.Assign(regs.mandated_early_z != 0 ? 1 : 0); - graphics_key.gs_input_topology.Assign(maxwell3d->draw_manager->GetDrawState().topology); + graphics_key.gs_input_topology.Assign(maxwell3d->draw_manager.draw_state.topology); graphics_key.tessellation_primitive.Assign(regs.tessellation.params.domain_type.Value()); graphics_key.tessellation_spacing.Assign(regs.tessellation.params.spacing.Value()); graphics_key.tessellation_clockwise.Assign( @@ -402,7 +402,7 @@ GraphicsPipeline* ShaderCache::BuiltPipeline(GraphicsPipeline* pipeline) const n // If games are using a small index count, we can assume these are full screen quads. // Usually these shaders are only used once for building textures so we can assume they // can't be built async - const auto& draw_state = maxwell3d->draw_manager->GetDrawState(); + const auto& draw_state = maxwell3d->draw_manager.draw_state; if (draw_state.index_buffer.count <= 6 || draw_state.vertex_buffer.count <= 6) { return pipeline; } diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp index 06cbd9e6da..8e95b7ad53 100644 --- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp +++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project @@ -12,7 +12,7 @@ #include "common/cityhash.h" #include "common/common_types.h" #include "common/settings.h" -#include "video_core/engines/draw_manager.h" +#include "video_core/engines/maxwell_3d.h" #include "video_core/renderer_vulkan/fixed_pipeline_state.h" #include "video_core/renderer_vulkan/vk_state_tracker.h" @@ -54,7 +54,7 @@ void RefreshXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFeatures& features) { const Maxwell& regs = maxwell3d.regs; - const auto topology_ = maxwell3d.draw_manager->GetDrawState().topology; + const auto topology_ = maxwell3d.draw_manager.draw_state.topology; raw1 = 0; extended_dynamic_state.Assign(features.has_extended_dynamic_state ? 1 : 0); diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 77a4e8616a..c73ccf8436 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -675,7 +675,7 @@ GraphicsPipeline* PipelineCache::BuiltPipeline(GraphicsPipeline* pipeline) const // If games are using a small index count, we can assume these are full screen quads. // Usually these shaders are only used once for building textures so we can assume they // can't be built async - const auto& draw_state = maxwell3d->draw_manager->GetDrawState(); + const auto& draw_state = maxwell3d->draw_manager.draw_state; if (draw_state.index_buffer.count <= 6 || draw_state.vertex_buffer.count <= 6) { return pipeline; } diff --git a/src/video_core/renderer_vulkan/vk_query_cache.cpp b/src/video_core/renderer_vulkan/vk_query_cache.cpp index 8518d89eee..94cec29ca7 100644 --- a/src/video_core/renderer_vulkan/vk_query_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_query_cache.cpp @@ -16,7 +16,7 @@ #include "video_core/renderer_vulkan/vk_texture_cache.h" #include "common/bit_util.h" #include "common/common_types.h" -#include "video_core/engines/draw_manager.h" +#include "video_core/engines/maxwell_3d.h" #include "video_core/host1x/gpu_device_memory_manager.h" #include "video_core/query_cache/query_cache.h" #include "video_core/rasterizer_interface.h" @@ -902,7 +902,7 @@ private: streams_mask = 0; // reset previously recorded streams runtime.View3DRegs([this](Maxwell3D& maxwell3d) { buffers_count = 0; - out_topology = maxwell3d.draw_manager->GetDrawState().topology; + out_topology = maxwell3d.draw_manager.draw_state.topology; for (size_t i = 0; i < Maxwell3D::Regs::NumTransformFeedbackBuffers; i++) { const auto& tf = maxwell3d.regs.transform_feedback; if (tf.buffers[i].enable == 0) { diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index f867980a6f..efe6691c92 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -20,7 +20,7 @@ #include "video_core/buffer_cache/buffer_cache.h" #include "video_core/gpu_logging/gpu_logging.h" #include "video_core/control/channel_state.h" -#include "video_core/engines/draw_manager.h" +#include "video_core/engines/maxwell_3d.h" #include "video_core/engines/kepler_compute.h" #include "video_core/engines/maxwell_3d.h" #include "video_core/host1x/gpu_device_memory_manager.h" @@ -46,7 +46,6 @@ namespace Vulkan { using Maxwell = Tegra::Engines::Maxwell3D::Regs; -using MaxwellDrawState = Tegra::Engines::DrawManager::State; using VideoCommon::ImageViewId; using VideoCommon::ImageViewType; @@ -151,7 +150,7 @@ VkRect2D GetScissorState(const Maxwell& regs, size_t index, u32 up_scale = 1, u3 return scissor; } -DrawParams MakeDrawParams(const MaxwellDrawState& draw_state, u32 num_instances, bool is_indexed) { +DrawParams MakeDrawParams(const Tegra::Engines::Maxwell3D::DrawManager::State& draw_state, u32 num_instances, bool is_indexed) { DrawParams params{ .base_instance = draw_state.base_instance, .num_instances = num_instances, @@ -231,15 +230,13 @@ void RasterizerVulkan::PrepareDraw(bool is_indexed, Func&& draw_func) { UpdateDynamicStates(); HandleTransformFeedback(); - query_cache.CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, - maxwell3d->regs.zpass_pixel_count_enable); - + query_cache.CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, maxwell3d->regs.zpass_pixel_count_enable); draw_func(); } void RasterizerVulkan::Draw(bool is_indexed, u32 instance_count) { PrepareDraw(is_indexed, [this, is_indexed, instance_count] { - const auto& draw_state = maxwell3d->draw_manager->GetDrawState(); + const auto& draw_state = maxwell3d->draw_manager.draw_state; const u32 num_instances{instance_count}; const DrawParams draw_params{MakeDrawParams(draw_state, num_instances, is_indexed)}; @@ -298,7 +295,7 @@ void RasterizerVulkan::Draw(bool is_indexed, u32 instance_count) { } void RasterizerVulkan::DrawIndirect() { - const auto& params = maxwell3d->draw_manager->GetIndirectParams(); + const auto& params = maxwell3d->draw_manager.indirect_state; buffer_cache.SetDrawIndirect(¶ms); PrepareDraw(params.is_indexed, [this, ¶ms] { const auto indirect_buffer = buffer_cache.GetDrawIndirectBuffer(); @@ -368,9 +365,8 @@ void RasterizerVulkan::DrawTexture() { UpdateDynamicStates(); - query_cache.CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, - maxwell3d->regs.zpass_pixel_count_enable); - const auto& draw_texture_state = maxwell3d->draw_manager->GetDrawTextureState(); + query_cache.CounterEnable(VideoCommon::QueryType::ZPassPixelCount64, maxwell3d->regs.zpass_pixel_count_enable); + const auto& draw_texture_state = maxwell3d->draw_manager.draw_texture_state; const auto& sampler = texture_cache.GetGraphicsSampler(draw_texture_state.src_sampler); const auto& texture = texture_cache.GetImageView(draw_texture_state.src_texture); const auto* framebuffer = texture_cache.GetFramebuffer(); @@ -1530,10 +1526,9 @@ void RasterizerVulkan::UpdateDepthBiasEnable(Tegra::Engines::Maxwell3D::Regs& re regs.polygon_offset_line_enable, regs.polygon_offset_fill_enable, }; - const u32 topology_index = static_cast(maxwell3d->draw_manager->GetDrawState().topology); + const u32 topology_index = u32(maxwell3d->draw_manager.draw_state.topology); const u32 enable = enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]]; - scheduler.Record( - [enable](vk::CommandBuffer cmdbuf) { cmdbuf.SetDepthBiasEnableEXT(enable != 0); }); + scheduler.Record([enable](vk::CommandBuffer cmdbuf) { cmdbuf.SetDepthBiasEnableEXT(enable != 0); }); } void RasterizerVulkan::UpdateLogicOpEnable(Tegra::Engines::Maxwell3D::Regs& regs) {