aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/engines/draw_manager.cpp
diff options
context:
space:
mode:
authorDjihads <76681596+Djihads80@users.noreply.github.com>2026-10-29 02:25:36 +0100
committerGitHub <noreply@github.com>2026-10-29 02:25:36 +0100
commit0bb5055b6541c74f47603a8dff0569a509cbaf18 (patch)
treeda827ff9c4f2f9a5309ee2804ee689f608c0ac2f /src/video_core/engines/draw_manager.cpp
parent1af7fe72927af9fc64aa4af117bc9b30043c4dc7 (diff)
parent535b6769709eb22333af26269f1b16f37adce4db (diff)
Merge pull request #1 from Djihads80/yumekiru/ns2-progress-v2
Experimental NS2 support and accumulated GPU fixes
Diffstat (limited to 'src/video_core/engines/draw_manager.cpp')
-rw-r--r--src/video_core/engines/draw_manager.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/video_core/engines/draw_manager.cpp b/src/video_core/engines/draw_manager.cpp
index 5891c25622..a610fb1661 100644
--- a/src/video_core/engines/draw_manager.cpp
+++ b/src/video_core/engines/draw_manager.cpp
@@ -5,11 +5,15 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <cstring>
+#include <fstream>
+#include <cstdlib>
+#include <set>
#include "common/settings.h"
#include "video_core/dirty_flags.h"
#include "video_core/engines/maxwell_3d.h"
#include "video_core/rasterizer_interface.h"
+#include "video_core/memory_manager.h"
namespace Tegra::Engines {
@@ -277,6 +281,45 @@ void Maxwell3D::DrawManager::ProcessDraw(Maxwell3D& maxwell3d, bool draw_indexed
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()) {
+ auto& native = maxwell3d.GetNativeMacroEngine();
+ if (native.native_turing) {
+ const auto count = draw_indexed ? draw_state.index_buffer.count : draw_state.vertex_buffer.count;
+ if (!count || !instance_count) return;
+ if (native.native_execution_failed) return;
+ if (Settings::values.renderer_backend.GetValue() != Settings::RendererBackend::Vulkan) {
+ native.native_execution_failed = true;
+ LOG_ERROR(HW_GPU, "Native graphics shaders require the experimental Vulkan path");
+ return;
+ }
+ if (std::getenv("EDEN_NATIVE_DRAW_DIAGNOSTICS")) {
+ static thread_local std::set<std::array<GPUVAddr, Maxwell3D::Regs::MaxShaderProgram>> captured;
+ std::array<GPUVAddr, Maxwell3D::Regs::MaxShaderProgram> programs{};
+ for (size_t stage = 0; stage < programs.size(); ++stage) {
+ if (!maxwell3d.regs.IsShaderConfigEnabled(stage)) continue;
+ const auto& pipeline = maxwell3d.regs.pipelines[stage];
+ programs[stage] = (GPUVAddr{pipeline.reserved[0] & 0xff} << 32) | pipeline.reserved[1];
+ }
+ if (captured.size() < 4096 && captured.insert(programs).second) {
+ std::ofstream registers("native-graphics-registers.bin", std::ios::binary);
+ registers.write(reinterpret_cast<const char*>(&maxwell3d.regs), sizeof(maxwell3d.regs));
+ for (size_t stage = 0; stage < Maxwell3D::Regs::MaxShaderProgram; ++stage) {
+ if (!maxwell3d.regs.IsShaderConfigEnabled(stage)) continue;
+ const auto& pipeline = maxwell3d.regs.pipelines[stage];
+ // C797 uses per-stage program addresses at 0x2014/0x2018,
+ // unlike Maxwell's program-region plus 0x2004 offset.
+ const GPUVAddr address = (GPUVAddr{pipeline.reserved[0] & 0xff} << 32) | pipeline.reserved[1];
+ LOG_INFO(HW_GPU, "Native graphics shader stage={}, address={:#x}", stage, address);
+ if (!maxwell3d.memory_manager.IsFullyMappedRange(address, 0x1000)) continue;
+ std::array<u8, 0x1000> bytes{};
+ maxwell3d.memory_manager.ReadBlockUnsafe(address, bytes.data(), bytes.size());
+ std::ofstream shader("native-graphics-shader-" + std::to_string(stage) + ".bin", std::ios::binary);
+ shader.write(reinterpret_cast<const char*>(bytes.data()), bytes.size());
+ }
+ LOG_DEBUG(HW_GPU, "Translating native graphics draw: indexed={}, vertices={}, instances={}",
+ draw_indexed, count, instance_count);
+ }
+ }
+ }
maxwell3d.rasterizer->Draw(draw_indexed, instance_count);
}
}
@@ -285,6 +328,12 @@ 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()) {
+ auto& native = maxwell3d.GetNativeMacroEngine();
+ if (native.native_turing) {
+ native.native_execution_failed = true;
+ LOG_ERROR(HW_GPU, "Native graphics shader translation required: indirect draw");
+ return;
+ }
maxwell3d.rasterizer->DrawIndirect();
}
}