shader: leave the start instance out of mesh and NGG instance ID VGPRs

Co-authored-by: Senaxx <michelbeld@gmail.com>
This commit is contained in:
nmzikandSenaxx committed 2026-10-26 07:43:11 +01:00
1 parent 5429888d4c
commit 943bc19f46
4 files changed
+11 -13

No files matched your search

@@ -1161,7 +1161,6 @@ void RenderExecutor::ExecutePreparedDraw(uint64_t submit_id, CommandBuffer& buff
if (mesh_active) { if (mesh_active) {
draw_data = {draw.index_count, draw_data = {draw.index_count,
static_cast<uint32_t>(emit.vertex_offset), static_cast<uint32_t>(emit.vertex_offset),
emit.first_instance,
index_source.guest_element_size, index_source.guest_element_size,
static_cast<uint32_t>(index_source.address), static_cast<uint32_t>(index_source.address),
static_cast<uint32_t>(index_source.address >> 32u)}; static_cast<uint32_t>(index_source.address >> 32u)};
@@ -1244,12 +1244,12 @@ IR::Program TranslateProgram(const Decoder::Program& decoded, const CFG::Graph&
entry_ir.BitwiseOr(wave_info, entry_ir.BitwiseOr(entry_ir.ShiftLeftLogical( entry_ir.BitwiseOr(wave_info, entry_ir.BitwiseOr(entry_ir.ShiftLeftLogical(
primitive_count, u32(8)), primitive_count, u32(8)),
vertex_count))); vertex_count)));
// Instance IDs exclude the start instance, which shaders add from user data.
if (mesh.fast_launch) { if (mesh.fast_launch) {
// Fast launch broadcasts the subgroup's base vertex and instance to every lane. // Fast launch broadcasts the subgroup's base vertex and instance to every lane.
entry_ir.SetVectorReg(static_cast<IR::VectorReg>(5), entry_ir.IAdd(draw(1), group)); entry_ir.SetVectorReg(static_cast<IR::VectorReg>(5), entry_ir.IAdd(draw(1), group));
entry_ir.SetVectorReg( entry_ir.SetVectorReg(static_cast<IR::VectorReg>(6),
static_cast<IR::VectorReg>(6), builtin(IR::StageInputKind::WorkgroupId, 1));
entry_ir.IAdd(draw(2), builtin(IR::StageInputKind::WorkgroupId, 1)));
} else { } else {
// GS adjacency addresses local ES records in LDS. Fans retain the draw's // GS adjacency addresses local ES records in LDS. Fans retain the draw's
// center in every subgroup; strip winding follows the global primitive. // center in every subgroup; strip winding follows the global primitive.
@@ -1277,14 +1277,14 @@ IR::Program TranslateProgram(const Decoder::Program& decoded, const CFG::Graph&
entry_ir.ShiftLeftLogical(second, u32(18)))); entry_ir.ShiftLeftLogical(second, u32(18))));
entry_ir.SetVectorReg(static_cast<IR::VectorReg>(1), entry_ir.SetVectorReg(static_cast<IR::VectorReg>(1),
entry_ir.ShiftLeftLogical(third, u32(2))); entry_ir.ShiftLeftLogical(third, u32(2)));
const auto index_bytes = draw(3); const auto index_bytes = draw(2);
const auto indexed = entry_ir.INotEqual(index_bytes, u32(0)); const auto indexed = entry_ir.INotEqual(index_bytes, u32(0));
const auto index_low = draw(4); const auto index_low = draw(3);
const auto byte_offset = entry_ir.IAdd(entry_ir.BitwiseAnd(index_low, u32(3)), const auto byte_offset = entry_ir.IAdd(entry_ir.BitwiseAnd(index_low, u32(3)),
entry_ir.IMul(input_vertex, index_bytes)); entry_ir.IMul(input_vertex, index_bytes));
const auto index_resource = entry_ir.Emit( const auto index_resource = entry_ir.Emit(
IR::ValueOpcode::GetAddressResource, IR::ValueOpcode::GetAddressResource,
{entry_ir.BitwiseAnd(index_low, u32(~3u)), draw(5)}); {entry_ir.BitwiseAnd(index_low, u32(~3u)), draw(4)});
const auto memory_index = static_cast<uint32_t>(result.memory_info.size()); const auto memory_index = static_cast<uint32_t>(result.memory_info.size());
result.memory_info.push_back({.kind = IR::ResourceKind::Global}); result.memory_info.push_back({.kind = IR::ResourceKind::Global});
const auto packed_index = entry_ir.Emit( const auto packed_index = entry_ir.Emit(
@@ -1298,9 +1298,8 @@ IR::Program TranslateProgram(const Decoder::Program& decoded, const CFG::Graph&
entry_ir.IMul(index_bytes, u32(8))})); entry_ir.IMul(index_bytes, u32(8))}));
entry_ir.SetVectorReg(static_cast<IR::VectorReg>(5), entry_ir.SetVectorReg(static_cast<IR::VectorReg>(5),
entry_ir.IAdd(draw(1), entry_ir.Select(indexed, index, input_vertex))); entry_ir.IAdd(draw(1), entry_ir.Select(indexed, index, input_vertex)));
entry_ir.SetVectorReg( entry_ir.SetVectorReg(static_cast<IR::VectorReg>(8),
static_cast<IR::VectorReg>(8), builtin(IR::StageInputKind::WorkgroupId, 1));
entry_ir.IAdd(draw(2), builtin(IR::StageInputKind::WorkgroupId, 1)));
} }
} else if (options.stage == ShaderType::Local) { } else if (options.stage == ShaderType::Local) {
entry_ir.SetScalarReg(static_cast<IR::ScalarReg>(3), IR::U32(IR::Value(64u))); entry_ir.SetScalarReg(static_cast<IR::ScalarReg>(3), IR::U32(IR::Value(64u)));
+1 -1
View File
@@ -365,7 +365,7 @@ static_assert(static_cast<uint32_t>(DescriptorBindingKind::Count) == 58u);
struct PushData { struct PushData {
static constexpr uint32_t DwordCount = 32; static constexpr uint32_t DwordCount = 32;
static constexpr uint32_t MeshDrawDwordCount = 6; static constexpr uint32_t MeshDrawDwordCount = 5;
static constexpr uint32_t NoStart = UINT32_MAX; static constexpr uint32_t NoStart = UINT32_MAX;
std::array<uint32_t, DwordCount> dwords {}; std::array<uint32_t, DwordCount> dwords {};
+2 -2
View File
@@ -11787,7 +11787,7 @@ void TestMeshInputAssembly() {
options.user_data_count = 0; options.user_data_count = 0;
options.input_info.vertex = &input; options.input_info.vertex = &input;
auto program = Frontend::TranslateProgram(decoded, graph, options); auto program = Frontend::TranslateProgram(decoded, graph, options);
const uint32_t draw[] = {test.count, test.base_vertex, 7, test.width, const uint32_t draw[] = {test.count, test.base_vertex, test.width,
test.address_low, 0x12}; test.address_low, 0x12};
Inst *load = nullptr; Inst *load = nullptr;
for (auto &inst : *program.blocks.front()) { for (auto &inst : *program.blocks.front()) {
@@ -11832,7 +11832,7 @@ void TestMeshInputAssembly() {
Check(sgprs[2] == test.group_info && sgprs[3] == test.wave_info && Check(sgprs[2] == test.group_info && sgprs[3] == test.wave_info &&
vgprs[0] == ((test.first << 2) | (test.second << 18)) && vgprs[0] == ((test.first << 2) | (test.second << 18)) &&
vgprs[1] == test.third * 4 && vgprs[5] == test.vertex_id && vgprs[1] == test.third * 4 && vgprs[5] == test.vertex_id &&
vgprs[test.fast_launch ? 6 : 8] == 9u, vgprs[test.fast_launch ? 6 : 8] == 2u,
"mesh prolog changed input assembly, wave counts, vertex ID, or instance ID"); "mesh prolog changed input assembly, wave counts, vertex ID, or instance ID");
} }
} }