[vulkan] Adjusted TFB Topology entry and use

This commit is contained in:
CamilleLaVey 2026-03-14 00:26:55 -04:00
parent 610e9eb516
commit 40b2fd0e6b
3 changed files with 56 additions and 3 deletions

View file

@ -12,6 +12,7 @@
#include "common/settings.h"
#include "core/core.h"
#include "core/core_timing.h"
#include "shader_recompiler/program_header.h"
#include "video_core/dirty_flags.h"
#include "video_core/engines/draw_manager.h"
#include "video_core/engines/maxwell_3d.h"
@ -22,6 +23,37 @@
namespace Tegra::Engines {
namespace {
[[nodiscard]] Maxwell3D::Regs::PrimitiveTopology PrimitiveTopologyFromGeometryOutput(
Shader::OutputTopology topology) {
switch (topology) {
case Shader::OutputTopology::PointList:
return Maxwell3D::Regs::PrimitiveTopology::Points;
case Shader::OutputTopology::LineStrip:
return Maxwell3D::Regs::PrimitiveTopology::LineStrip;
case Shader::OutputTopology::TriangleStrip:
return Maxwell3D::Regs::PrimitiveTopology::TriangleStrip;
}
return Maxwell3D::Regs::PrimitiveTopology::Triangles;
}
[[nodiscard]] Maxwell3D::Regs::PrimitiveTopology PrimitiveTopologyFromTessellationOutput(
Maxwell3D::Regs::Tessellation::OutputPrimitives topology) {
switch (topology) {
case Maxwell3D::Regs::Tessellation::OutputPrimitives::Points:
return Maxwell3D::Regs::PrimitiveTopology::Points;
case Maxwell3D::Regs::Tessellation::OutputPrimitives::Lines:
return Maxwell3D::Regs::PrimitiveTopology::Lines;
case Maxwell3D::Regs::Tessellation::OutputPrimitives::Triangles_CW:
case Maxwell3D::Regs::Tessellation::OutputPrimitives::Triangles_CCW:
return Maxwell3D::Regs::PrimitiveTopology::Triangles;
}
return Maxwell3D::Regs::PrimitiveTopology::Triangles;
}
} // namespace
/// First register id that is actually a Macro call.
constexpr u32 MacroRegistersStart = 0xE00;
@ -666,6 +698,22 @@ Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const {
return tsc_entry;
}
Maxwell3D::Regs::PrimitiveTopology Maxwell3D::GetTransformFeedbackOutputTopology() const {
if (regs.IsShaderConfigEnabled(Regs::ShaderType::Geometry)) {
const GPUVAddr shader_addr = regs.program_region.Address() +
regs.pipelines[static_cast<size_t>(Regs::ShaderType::Geometry)]
.offset;
Shader::ProgramHeader sph{};
memory_manager.ReadBlockUnsafe(shader_addr, &sph, sizeof(sph));
return PrimitiveTopologyFromGeometryOutput(sph.common3.output_topology.Value());
}
if (regs.IsShaderConfigEnabled(Regs::ShaderType::Tessellation)) {
return PrimitiveTopologyFromTessellationOutput(
regs.tessellation.params.output_primitives.Value());
}
return draw_manager->GetDrawState().topology;
}
u32 Maxwell3D::GetRegisterValue(u32 method) const {
ASSERT(method < Regs::NUM_REGS && "Invalid Maxwell3D register");
return regs.reg_array[method];

View file

@ -3153,6 +3153,8 @@ private:
/// Retrieves information about a specific TSC entry from the TSC buffer.
Texture::TSCEntry GetTSCEntry(u32 tsc_index) const;
[[nodiscard]] Regs::PrimitiveTopology GetTransformFeedbackOutputTopology() const;
/**
* Call a macro on this engine.
*

View file

@ -957,7 +957,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.GetTransformFeedbackOutputTopology();
for (size_t i = 0; i < Maxwell3D::Regs::NumTransformFeedbackBuffers; i++) {
const auto& tf = maxwell3d.regs.transform_feedback;
if (tf.buffers[i].enable == 0) {
@ -968,7 +968,9 @@ private:
LOG_WARNING(Render_Vulkan, "TransformFeedback stream {} out of range", stream);
continue;
}
last_queries_stride[stream] += tf.controls[i].stride;
if (last_queries_stride[stream] == 0) {
last_queries_stride[stream] = tf.controls[i].stride;
}
streams_mask |= 1ULL << stream;
buffers_count = std::max<size_t>(buffers_count, stream + 1);
}
@ -1177,7 +1179,8 @@ public:
if (tf.controls[i].stream != subreport) {
continue;
}
new_query->stride += tf.controls[i].stride;
new_query->stride = tf.controls[i].stride;
break;
}
});
}