aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/shader_environment.cpp
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-11-01 13:25:40 -0500
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-11-01 13:25:40 -0500
commit235e2f5f5548e20620c247b76586cbb559f4158d (patch)
tree4b282626b7d70498cb493653a585ac9d8a4f074c /src/video_core/shader_environment.cpp
parent6bde8c20d1f7c020a920e59a989c03822a08445d (diff)
parent004ca96531812ea3674273ed568e3a672e664932 (diff)
Merge remote-tracking branch 'origin/feat/nx2-mesh-shaders' into test/linux-all-prs
Diffstat (limited to 'src/video_core/shader_environment.cpp')
-rw-r--r--src/video_core/shader_environment.cpp25
1 files changed, 23 insertions, 2 deletions
diff --git a/src/video_core/shader_environment.cpp b/src/video_core/shader_environment.cpp
index 9d189ad4f0..78438769f5 100644
--- a/src/video_core/shader_environment.cpp
+++ b/src/video_core/shader_environment.cpp
@@ -470,8 +470,16 @@ GraphicsEnvironment::GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_,
gpu_memory->ReadBlock(program_base + start_address, &sph, sizeof(sph));
initial_offset = sizeof(sph);
texture_bound = maxwell3d->regs.bindless_texture_const_buffer_slot;
- if (maxwell3d->GetNativeMacroEngine().native_turing) {
- if (program != Maxwell::ShaderType::VertexB && program != Maxwell::ShaderType::Pixel) {
+ const auto& regs{maxwell3d->regs};
+ const bool native{maxwell3d->GetNativeMacroEngine().native_turing};
+ // Task and mesh programs: the task in the vertex slot, its mesh program in the tessellation
+ // slot (without a task, the mesh program is in the vertex slot).
+ const bool mesh_slot{native && regs.IsMeshEnabled() &&
+ (program == Maxwell::ShaderType::VertexB ||
+ program == Maxwell::ShaderType::Tessellation)};
+ if (native) {
+ if (program != Maxwell::ShaderType::VertexB && program != Maxwell::ShaderType::Pixel &&
+ !mesh_slot) {
throw Shader::RuntimeError("Unsupported native graphics shader stage {}", static_cast<u32>(program));
}
if (std::getenv("EDEN_NATIVE_DRAW_DIAGNOSTICS")) {
@@ -516,6 +524,19 @@ GraphicsEnvironment::GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_,
ASSERT_MSG(false, "Invalid program={}", program);
break;
}
+ if (mesh_slot) {
+ const bool has_task{regs.IsShaderConfigEnabled(Maxwell::ShaderType::Tessellation)};
+ stage = program == Maxwell::ShaderType::VertexB && has_task ? Shader::Stage::Task
+ : Shader::Stage::Mesh;
+ mesh_registers = {regs.reg_array[Maxwell::MeshShaderA], regs.reg_array[Maxwell::MeshShaderB],
+ regs.reg_array[Maxwell::MeshInitShader]};
+ if (stage == Shader::Stage::Mesh && regs.IsShaderConfigEnabled(Maxwell::ShaderType::Geometry)) {
+ const auto& geometry{regs.pipelines[static_cast<size_t>(Maxwell::ShaderType::Geometry)]};
+ const GPUVAddr address{(static_cast<u64>(geometry.reserved[0] & 0xff) << 32) |
+ geometry.reserved[1]};
+ gpu_memory->ReadBlock(address, &mesh_primitive_header, sizeof(mesh_primitive_header));
+ }
+ }
const u64 local_size{sph.LocalMemorySize()};
ASSERT(local_size <= (std::numeric_limits<u32>::max)());
local_memory_size = static_cast<u32>(local_size) + sph.common3.shader_local_memory_crs_size;