mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 02:47:02 +02:00
Fix centroid interpolation weights
PPSA03792
This commit is contained in:
@@ -41,7 +41,9 @@ uint32_t EmitBuiltinU32(EmitterState& state, IR::StageInputKind kind, uint32_t c
|
||||
return EmitAddU32(state, local,
|
||||
EmitBinaryU32(state, spv::OpIMul, group, ConstantU32(state, size)));
|
||||
}
|
||||
const auto variable = InputVariableForKind(state, kind);
|
||||
const bool centroid = kind == IR::StageInputKind::BaryCoordSmoothCentroid;
|
||||
const auto variable = InputVariableForKind(
|
||||
state, centroid ? IR::StageInputKind::BaryCoordSmooth : kind);
|
||||
if (variable == 0) {
|
||||
return ConstantU32(state, 0);
|
||||
}
|
||||
@@ -74,15 +76,24 @@ uint32_t EmitBuiltinU32(EmitterState& state, IR::StageInputKind kind, uint32_t c
|
||||
state.builder.AddFunction(spv::OpBitcast, TypeU32(state), bits, value);
|
||||
return bits;
|
||||
}
|
||||
if (kind == IR::StageInputKind::BaryCoordSmooth ||
|
||||
if (centroid || kind == IR::StageInputKind::BaryCoordSmooth ||
|
||||
kind == IR::StageInputKind::BaryCoordNoPerspective) {
|
||||
const auto pointer = state.builder.AllocateId();
|
||||
const auto value = state.builder.AllocateId();
|
||||
const auto bits = state.builder.AllocateId();
|
||||
state.builder.AddFunction(spv::OpAccessChain,
|
||||
TypePointer(state, spv::StorageClassInput, TypeF32(state)),
|
||||
pointer, variable, ConstantU32(state, component + 1u));
|
||||
state.builder.AddFunction(spv::OpLoad, TypeF32(state), value, pointer);
|
||||
if (centroid) {
|
||||
const auto coordinates = state.builder.AllocateId();
|
||||
state.builder.RequireCapability(spv::CapabilityInterpolationFunction);
|
||||
state.builder.AddFunction(spv::OpExtInst, TypeF32Vector(state, 3), coordinates,
|
||||
GlslStd450(state), GLSLstd450InterpolateAtCentroid, variable);
|
||||
state.builder.AddFunction(spv::OpCompositeExtract, TypeF32(state), value,
|
||||
coordinates, component + 1u);
|
||||
} else {
|
||||
const auto pointer = state.builder.AllocateId();
|
||||
state.builder.AddFunction(spv::OpAccessChain,
|
||||
TypePointer(state, spv::StorageClassInput, TypeF32(state)),
|
||||
pointer, variable, ConstantU32(state, component + 1u));
|
||||
state.builder.AddFunction(spv::OpLoad, TypeF32(state), value, pointer);
|
||||
}
|
||||
state.builder.AddFunction(spv::OpBitcast, TypeU32(state), bits, value);
|
||||
return bits;
|
||||
}
|
||||
|
||||
@@ -1184,13 +1184,15 @@ IR::Program TranslateProgram(const Decoder::Program& decoded, const CFG::Graph&
|
||||
builtin(IR::StageInputKind::PrimitiveId));
|
||||
} else if (options.stage == ShaderType::Pixel) {
|
||||
const auto* ps = options.input_info.pixel;
|
||||
if (ps->ps_perspective_center_vgpr != UINT32_MAX) {
|
||||
entry_ir.SetVectorReg(static_cast<IR::VectorReg>(ps->ps_perspective_center_vgpr),
|
||||
builtin(IR::StageInputKind::BaryCoordSmooth, 0));
|
||||
entry_ir.SetVectorReg(
|
||||
static_cast<IR::VectorReg>(ps->ps_perspective_center_vgpr + 1u),
|
||||
builtin(IR::StageInputKind::BaryCoordSmooth, 1));
|
||||
}
|
||||
const auto barycentric_pair = [&](uint32_t reg, IR::StageInputKind kind) {
|
||||
if (reg != UINT32_MAX) {
|
||||
entry_ir.SetVectorReg(static_cast<IR::VectorReg>(reg), builtin(kind, 0));
|
||||
entry_ir.SetVectorReg(static_cast<IR::VectorReg>(reg + 1u), builtin(kind, 1));
|
||||
}
|
||||
};
|
||||
barycentric_pair(ps->ps_perspective_center_vgpr, IR::StageInputKind::BaryCoordSmooth);
|
||||
barycentric_pair(ps->ps_perspective_centroid_vgpr,
|
||||
IR::StageInputKind::BaryCoordSmoothCentroid);
|
||||
uint32_t reg = ps->ps_system_input_base;
|
||||
if (ps->ps_pos_x) {
|
||||
entry_ir.SetVectorReg(static_cast<IR::VectorReg>(reg++),
|
||||
|
||||
@@ -171,6 +171,7 @@ enum class StageInputKind {
|
||||
Layer,
|
||||
SampleId,
|
||||
BaryCoordSmooth,
|
||||
BaryCoordSmoothCentroid,
|
||||
BaryCoordNoPerspective,
|
||||
WorkgroupId,
|
||||
LocalInvocationId,
|
||||
|
||||
@@ -143,6 +143,7 @@ void ValidateValueReferences(const Program& program, ShaderStageInputInfo input_
|
||||
}
|
||||
break;
|
||||
case StageInputKind::BaryCoordSmooth:
|
||||
case StageInputKind::BaryCoordSmoothCentroid:
|
||||
case StageInputKind::BaryCoordNoPerspective:
|
||||
if (component >= 2u) {
|
||||
return Fail("typed barycentric component is out of range");
|
||||
@@ -287,7 +288,8 @@ void CollectBuiltinInputs(const Program& program, ShaderInfo& info) {
|
||||
case StageInputKind::Layer: AddInput(info, kind, 0, 1, "gl_Layer"); break;
|
||||
case StageInputKind::SampleId: AddInput(info, kind, 0, 1, "gl_SampleID"); break;
|
||||
case StageInputKind::BaryCoordSmooth:
|
||||
AddInput(info, kind, 0, 3, "gl_BaryCoordKHR");
|
||||
case StageInputKind::BaryCoordSmoothCentroid:
|
||||
AddInput(info, StageInputKind::BaryCoordSmooth, 0, 3, "gl_BaryCoordKHR");
|
||||
break;
|
||||
case StageInputKind::BaryCoordNoPerspective:
|
||||
AddInput(info, kind, 0, 3, "gl_BaryCoordNoPerspKHR");
|
||||
|
||||
@@ -584,6 +584,9 @@ static void ShaderGetStaticInputInfoPS(
|
||||
if ((active_inputs & 0x00000002u) != 0) {
|
||||
ps_info.ps_perspective_center_vgpr = (active_inputs & 0x00000001u) != 0 ? 2u : 0u;
|
||||
}
|
||||
if ((active_inputs & 0x00000004u) != 0) {
|
||||
ps_info.ps_perspective_centroid_vgpr = 2u * std::popcount(active_inputs & 0x3u);
|
||||
}
|
||||
for (uint32_t i = 0; i < data.num_input_semantics && i < ps_info.input_num && i < 32u; i++) {
|
||||
const auto& semantic = data.input_semantics[i];
|
||||
if (semantic.is_custom != 0 && semantic.is_f16 == 0) {
|
||||
@@ -707,6 +710,7 @@ void BuildStageStaticKey(const ShaderPixelInputInfo& info, std::vector<uint32_t>
|
||||
key.push_back(info.ps_system_input_base);
|
||||
key.push_back(info.custom_interpolation_mask);
|
||||
key.push_back(info.ps_perspective_center_vgpr);
|
||||
key.push_back(info.ps_perspective_centroid_vgpr);
|
||||
key.push_back(static_cast<uint32_t>(info.ps_pos_x));
|
||||
key.push_back(static_cast<uint32_t>(info.ps_pos_y));
|
||||
key.push_back(static_cast<uint32_t>(info.ps_pos_z));
|
||||
@@ -958,6 +962,7 @@ void ShaderDbgDumpInputInfo(const ShaderPixelInputInfo& info) {
|
||||
"\t ps_system_input_base = %u\n"
|
||||
"\t custom_interpolation_mask = 0x%08" PRIx32 "\n"
|
||||
"\t ps_perspective_center_vgpr = %" PRIu32 "\n"
|
||||
"\t ps_perspective_centroid_vgpr = %" PRIu32 "\n"
|
||||
"\t ps_pos_x = %s\n"
|
||||
"\t ps_pos_y = %s\n"
|
||||
"\t ps_pos_z = %s\n"
|
||||
@@ -970,7 +975,8 @@ void ShaderDbgDumpInputInfo(const ShaderPixelInputInfo& info) {
|
||||
"\t ps_early_z = %s\n"
|
||||
"\t ps_execute_on_noop = %s\n",
|
||||
info.input_num, info.ps_system_input_base, info.custom_interpolation_mask,
|
||||
info.ps_perspective_center_vgpr, info.ps_pos_x ? "true" : "false",
|
||||
info.ps_perspective_center_vgpr, info.ps_perspective_centroid_vgpr,
|
||||
info.ps_pos_x ? "true" : "false",
|
||||
info.ps_pos_y ? "true" : "false", info.ps_pos_z ? "true" : "false",
|
||||
info.ps_pos_w ? "true" : "false", info.ps_front_face ? "true" : "false",
|
||||
info.ps_ancillary ? "true" : "false",
|
||||
|
||||
@@ -157,6 +157,7 @@ struct ShaderPixelInputInfo {
|
||||
uint32_t ps_system_input_base = 0;
|
||||
uint32_t custom_interpolation_mask = 0;
|
||||
uint32_t ps_perspective_center_vgpr = UINT32_MAX;
|
||||
uint32_t ps_perspective_centroid_vgpr = UINT32_MAX;
|
||||
uint8_t target_output_mode[8] = {};
|
||||
std::array<Prospero::ColorComponentMapping, 8> target_export_mapping = {};
|
||||
uint32_t scratch_size_dwords = 0;
|
||||
|
||||
Reference in New Issue
Block a user