mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 02:47:02 +02:00
shader: assemble point inputs for merged geometry shaders
This commit is contained in:
@@ -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),
|
||||
u32(mesh.primitives_per_group));
|
||||
const auto step = u32(mesh.InputPrimitiveStep());
|
||||
const auto size = u32(mesh.InputPrimitiveSize());
|
||||
const auto chunk = entry_ir.IMul(primitive_chunk, step);
|
||||
const auto vertices =
|
||||
minimum(subtract_saturate(draw(0), chunk), u32(mesh.vertices_per_group));
|
||||
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,
|
||||
{subtract_saturate(vertices, u32(3)), step})),
|
||||
{subtract_saturate(vertices, size), step})),
|
||||
u32(1)));
|
||||
const auto wave = entry_ir.ShiftRightLogical(local, u32(6));
|
||||
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)));
|
||||
// GS adjacency addresses local ES records in LDS. Strip winding alternates
|
||||
// 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))
|
||||
: u32(0);
|
||||
const auto vertex = entry_ir.IMul(local, step);
|
||||
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.BitwiseOr(entry_ir.ShiftLeftLogical(first, u32(2)),
|
||||
entry_ir.ShiftLeftLogical(second, u32(18))));
|
||||
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 index_bytes = draw(3);
|
||||
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 ||
|
||||
regs.gs_regs.rsrc2.es_vgpr_component_count != 3u);
|
||||
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) ||
|
||||
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) {
|
||||
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,
|
||||
|
||||
@@ -79,14 +79,18 @@ struct ShaderMeshInputInfo: ShaderWorkgroupInputInfo {
|
||||
uint32_t max_primitives = 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 {
|
||||
return input_primitive == static_cast<uint32_t>(Prospero::PrimitiveType::kTriList) ? 3u : 1u;
|
||||
}
|
||||
[[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 {
|
||||
return primitives == 0u ? 0u : (primitives - 1u) * InputPrimitiveStep() + 3u;
|
||||
return primitives == 0u ? 0u : (primitives - 1u) * InputPrimitiveStep() + InputPrimitiveSize();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user