mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 08:13:05 +00:00
shader: assemble point inputs for merged geometry shaders
This commit is contained in:
1 parent
f880c58ccc
commit
1fd07c2c83
4 files changed
+33
-10
No files matched your search
@@ -1082,13 +1082,14 @@ IR::Program TranslateProgram(const Decoder::Program& decoded, const CFG::Graph&
|
|||||||
const auto primitive_chunk = entry_ir.IMul(builtin(IR::StageInputKind::WorkgroupId, 0),
|
const auto primitive_chunk = entry_ir.IMul(builtin(IR::StageInputKind::WorkgroupId, 0),
|
||||||
u32(mesh.primitives_per_group));
|
u32(mesh.primitives_per_group));
|
||||||
const auto step = u32(mesh.InputPrimitiveStep());
|
const auto step = u32(mesh.InputPrimitiveStep());
|
||||||
|
const auto size = u32(mesh.InputPrimitiveSize());
|
||||||
const auto chunk = entry_ir.IMul(primitive_chunk, step);
|
const auto chunk = entry_ir.IMul(primitive_chunk, step);
|
||||||
const auto vertices =
|
const auto vertices =
|
||||||
minimum(subtract_saturate(draw(0), chunk), u32(mesh.vertices_per_group));
|
minimum(subtract_saturate(draw(0), chunk), u32(mesh.vertices_per_group));
|
||||||
const auto primitives = entry_ir.Select(
|
const auto primitives = entry_ir.Select(
|
||||||
entry_ir.ULessThan(vertices, u32(3)), u32(0),
|
entry_ir.ULessThan(vertices, size), u32(0),
|
||||||
entry_ir.IAdd(IR::U32(entry_ir.Emit(IR::ValueOpcode::UDiv32,
|
entry_ir.IAdd(IR::U32(entry_ir.Emit(IR::ValueOpcode::UDiv32,
|
||||||
{subtract_saturate(vertices, u32(3)), step})),
|
{subtract_saturate(vertices, size), step})),
|
||||||
u32(1)));
|
u32(1)));
|
||||||
const auto wave = entry_ir.ShiftRightLogical(local, u32(6));
|
const auto wave = entry_ir.ShiftRightLogical(local, u32(6));
|
||||||
const auto wave_base = entry_ir.BitwiseAnd(local, u32(~63u));
|
const auto wave_base = entry_ir.BitwiseAnd(local, u32(~63u));
|
||||||
@@ -1103,17 +1104,23 @@ IR::Program TranslateProgram(const Decoder::Program& decoded, const CFG::Graph&
|
|||||||
vertex_count)));
|
vertex_count)));
|
||||||
// GS adjacency addresses local ES records in LDS. Strip winding alternates
|
// GS adjacency addresses local ES records in LDS. Strip winding alternates
|
||||||
// with the global primitive number, including across subgroup boundaries.
|
// with the global primitive number, including across subgroup boundaries.
|
||||||
const auto parity = mesh.InputPrimitiveStep() == 1u
|
const auto parity = mesh.input_primitive ==
|
||||||
|
static_cast<uint32_t>(Prospero::PrimitiveType::kTriStrip)
|
||||||
? entry_ir.BitwiseAnd(entry_ir.IAdd(primitive_chunk, local), u32(1))
|
? entry_ir.BitwiseAnd(entry_ir.IAdd(primitive_chunk, local), u32(1))
|
||||||
: u32(0);
|
: u32(0);
|
||||||
const auto vertex = entry_ir.IMul(local, step);
|
const auto vertex = entry_ir.IMul(local, step);
|
||||||
const auto first = entry_ir.IAdd(vertex, parity);
|
const auto first = entry_ir.IAdd(vertex, parity);
|
||||||
const auto second = entry_ir.ISub(entry_ir.IAdd(vertex, u32(1)), parity);
|
const auto second = mesh.InputPrimitiveSize() == 3u
|
||||||
|
? entry_ir.ISub(entry_ir.IAdd(vertex, u32(1)), parity)
|
||||||
|
: u32(0);
|
||||||
|
const auto third = mesh.InputPrimitiveSize() == 3u
|
||||||
|
? entry_ir.IAdd(vertex, u32(2))
|
||||||
|
: u32(0);
|
||||||
entry_ir.SetVectorReg(static_cast<IR::VectorReg>(0),
|
entry_ir.SetVectorReg(static_cast<IR::VectorReg>(0),
|
||||||
entry_ir.BitwiseOr(entry_ir.ShiftLeftLogical(first, u32(2)),
|
entry_ir.BitwiseOr(entry_ir.ShiftLeftLogical(first, u32(2)),
|
||||||
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(entry_ir.IAdd(vertex, u32(2)), u32(2)));
|
entry_ir.ShiftLeftLogical(third, u32(2)));
|
||||||
const auto input_vertex = entry_ir.IAdd(chunk, local);
|
const auto input_vertex = entry_ir.IAdd(chunk, local);
|
||||||
const auto index_bytes = draw(3);
|
const auto index_bytes = draw(3);
|
||||||
const auto indexed = entry_ir.INotEqual(index_bytes, u32(0));
|
const auto indexed = entry_ir.INotEqual(index_bytes, u32(0));
|
||||||
|
|||||||
@@ -781,9 +781,11 @@ ShaderParams PrepareProgram(const HW::VertexShaderInfo& regs, const HW::Context&
|
|||||||
EXIT_NOT_IMPLEMENTED(regs.gs_regs.rsrc1.gs_vgpr_component_count != 3u ||
|
EXIT_NOT_IMPLEMENTED(regs.gs_regs.rsrc1.gs_vgpr_component_count != 3u ||
|
||||||
regs.gs_regs.rsrc2.es_vgpr_component_count != 3u);
|
regs.gs_regs.rsrc2.es_vgpr_component_count != 3u);
|
||||||
const auto& group = user_config.GetGeControl();
|
const auto& group = user_config.GetGeControl();
|
||||||
if ((user_config.GetPrimType() != Prospero::PrimitiveType::kTriStrip &&
|
if ((user_config.GetPrimType() != Prospero::PrimitiveType::kPointList &&
|
||||||
|
user_config.GetPrimType() != Prospero::PrimitiveType::kTriStrip &&
|
||||||
user_config.GetPrimType() != Prospero::PrimitiveType::kTriList) ||
|
user_config.GetPrimType() != Prospero::PrimitiveType::kTriList) ||
|
||||||
sh.m_vgtGsOutPrimType != 2u || sh.m_vgtGsMaxVertOut < 3u || group.vertex_group_size < 3u ||
|
sh.m_vgtGsOutPrimType != 2u || sh.m_vgtGsMaxVertOut < 3u ||
|
||||||
|
group.vertex_group_size < mesh.InputPrimitiveSize() ||
|
||||||
mesh.max_vertices == 0u) {
|
mesh.max_vertices == 0u) {
|
||||||
EXIT("unsupported GS assembly: input=%u output=%u vertices=%u GE=%u/%u max_output=%u\n",
|
EXIT("unsupported GS assembly: input=%u output=%u vertices=%u GE=%u/%u max_output=%u\n",
|
||||||
mesh.input_primitive, sh.m_vgtGsOutPrimType, sh.m_vgtGsMaxVertOut,
|
mesh.input_primitive, sh.m_vgtGsOutPrimType, sh.m_vgtGsMaxVertOut,
|
||||||
|
|||||||
@@ -79,14 +79,18 @@ struct ShaderMeshInputInfo: ShaderWorkgroupInputInfo {
|
|||||||
uint32_t max_primitives = 0;
|
uint32_t max_primitives = 0;
|
||||||
uint32_t provoking_vertex = 0;
|
uint32_t provoking_vertex = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] constexpr uint32_t InputPrimitiveSize() const {
|
||||||
|
return input_primitive == static_cast<uint32_t>(Prospero::PrimitiveType::kPointList) ? 1u : 3u;
|
||||||
|
}
|
||||||
[[nodiscard]] constexpr uint32_t InputPrimitiveStep() const {
|
[[nodiscard]] constexpr uint32_t InputPrimitiveStep() const {
|
||||||
return input_primitive == static_cast<uint32_t>(Prospero::PrimitiveType::kTriList) ? 3u : 1u;
|
return input_primitive == static_cast<uint32_t>(Prospero::PrimitiveType::kTriList) ? 3u : 1u;
|
||||||
}
|
}
|
||||||
[[nodiscard]] constexpr uint32_t InputPrimitiveCount(uint32_t vertices) const {
|
[[nodiscard]] constexpr uint32_t InputPrimitiveCount(uint32_t vertices) const {
|
||||||
return vertices < 3u ? 0u : (vertices - 3u) / InputPrimitiveStep() + 1u;
|
const auto size = InputPrimitiveSize();
|
||||||
|
return vertices < size ? 0u : (vertices - size) / InputPrimitiveStep() + 1u;
|
||||||
}
|
}
|
||||||
[[nodiscard]] constexpr uint32_t InputVertexCount(uint32_t primitives) const {
|
[[nodiscard]] constexpr uint32_t InputVertexCount(uint32_t primitives) const {
|
||||||
return primitives == 0u ? 0u : (primitives - 1u) * InputPrimitiveStep() + 3u;
|
return primitives == 0u ? 0u : (primitives - 1u) * InputPrimitiveStep() + InputPrimitiveSize();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -9471,6 +9471,16 @@ void TestMeshInputAssembly() {
|
|||||||
0x40000305, 1, 2, 3, 0, 15, false},
|
0x40000305, 1, 2, 3, 0, 15, false},
|
||||||
{Prospero::PrimitiveType::kTriStrip, 5, 8, 0, 1, 0, 0, 11,
|
{Prospero::PrimitiveType::kTriStrip, 5, 8, 0, 1, 0, 0, 11,
|
||||||
0x40000305, 2, 1, 3, 0, 12, false},
|
0x40000305, 2, 1, 3, 0, 12, false},
|
||||||
|
{Prospero::PrimitiveType::kPointList, 12, 265, 22, 0, 2, 0x1002, 0,
|
||||||
|
0x40000101, 0, 0, 0, 528, 0xabcd, true},
|
||||||
|
{Prospero::PrimitiveType::kPointList, 12, 265, 22, 1, 2, 0x1002, 0,
|
||||||
|
0x40000101, 1, 0, 0, 532, 0, false},
|
||||||
|
{Prospero::PrimitiveType::kPointList, 1, 1, 0, 0, 0, 0, 11,
|
||||||
|
0x40000101, 0, 0, 0, 0, 11, false},
|
||||||
|
{Prospero::PrimitiveType::kPointList, 12, 265, 1, 1, 4, 0x1000, 5,
|
||||||
|
0x40000c0c, 1, 0, 0, 52, 0xabcd0128, true},
|
||||||
|
{Prospero::PrimitiveType::kPointList, 12, 265, 1, 64, 4, 0x1000, 0,
|
||||||
|
0x41000000, 64, 0, 0, 304, 0, false},
|
||||||
};
|
};
|
||||||
for (const auto &test : cases) {
|
for (const auto &test : cases) {
|
||||||
ShaderVertexInputInfo input{};
|
ShaderVertexInputInfo input{};
|
||||||
@@ -9532,7 +9542,7 @@ void TestMeshInputAssembly() {
|
|||||||
}
|
}
|
||||||
Check(sgpr3 == test.wave_info && vgprs[0] == ((test.first << 2) | (test.second << 18)) &&
|
Check(sgpr3 == test.wave_info && vgprs[0] == ((test.first << 2) | (test.second << 18)) &&
|
||||||
vgprs[1] == test.third * 4 && vgprs[5] == test.vertex_id && vgprs[8] == 9,
|
vgprs[1] == test.third * 4 && vgprs[5] == test.vertex_id && vgprs[8] == 9,
|
||||||
"mesh prolog changed triangle assembly, wave counts, vertex ID, or instance ID");
|
"mesh prolog changed input assembly, wave counts, vertex ID, or instance ID");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user