mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
Fix pixel shader input aliases
This commit is contained in:
@@ -388,6 +388,19 @@ void DefineInputs(EmitterState& state) {
|
||||
}
|
||||
}
|
||||
for (auto& input: state.inputs) {
|
||||
if (state.program.stage == ShaderType::Pixel &&
|
||||
input.kind == IR::StageInputKind::Parameter) {
|
||||
const auto location = PixelParameterLocation(state, input.location);
|
||||
const auto alias = std::ranges::find_if(state.inputs, [&](const InputBinding& other) {
|
||||
return other.kind == IR::StageInputKind::Parameter && other.variable_id != 0 &&
|
||||
PixelParameterLocation(state, other.location) == location;
|
||||
});
|
||||
if (alias != state.inputs.end()) {
|
||||
EXIT_IF(alias->per_vertex != input.per_vertex);
|
||||
input.variable_id = alias->variable_id;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
uint32_t type = TypeU32(state);
|
||||
switch (input.kind) {
|
||||
case IR::StageInputKind::VertexIndex:
|
||||
|
||||
@@ -226,6 +226,18 @@ void CollectPixelInputs(const Program& program, const ShaderPixelInputInfo* pixe
|
||||
}
|
||||
}
|
||||
}
|
||||
// Aliases of a vertex output share one SPIR-V interface variable. If any
|
||||
// alias reads raw vertices, interpolate the other aliases from those too.
|
||||
for (uint32_t input = 0; input < pixel->input_num; input++) {
|
||||
for (uint32_t alias = 0; alias < pixel->input_num; alias++) {
|
||||
if (ShaderPixelParameterMappedLocation(*pixel, input) ==
|
||||
ShaderPixelParameterMappedLocation(*pixel, alias) &&
|
||||
ShaderPixelParameterIsFlat(*pixel, input) ==
|
||||
ShaderPixelParameterIsFlat(*pixel, alias)) {
|
||||
per_vertex[input] = per_vertex[input] || per_vertex[alias];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (uint32_t input = 0; input < pixel->input_num; input++) {
|
||||
AddInput(info, StageInputKind::Parameter, input, 4, fmt::format("in_param_{}", input),
|
||||
per_vertex[input]);
|
||||
|
||||
@@ -40,12 +40,15 @@ std::vector<Parameter> GetParameters(const ShaderVertexInputInfo& vertex_info,
|
||||
}
|
||||
|
||||
std::vector<Parameter> parameters;
|
||||
std::array<bool, 32> output_locations {};
|
||||
for (const auto input: active_inputs) {
|
||||
const auto input_location = ShaderPixelParameterMappedLocation(*pixel_info, input);
|
||||
if ((vertex_info.stage.program->param_export_mask & (1u << input_location)) != 0) {
|
||||
parameters.push_back({input_location,
|
||||
ShaderPixelParameterLocation(*pixel_info, active_inputs, input),
|
||||
const auto output_location = ShaderPixelParameterLocation(*pixel_info, active_inputs, input);
|
||||
if ((vertex_info.stage.program->param_export_mask & (1u << input_location)) != 0 &&
|
||||
!output_locations[output_location]) {
|
||||
parameters.push_back({input_location, output_location,
|
||||
ShaderPixelParameterIsFlat(*pixel_info, input)});
|
||||
output_locations[output_location] = true;
|
||||
}
|
||||
}
|
||||
return parameters;
|
||||
|
||||
@@ -19,19 +19,31 @@ uint32_t ShaderPixelParameterLocation(const ShaderPixelInputInfo& info,
|
||||
std::span<const uint32_t> active_inputs, uint32_t input) {
|
||||
std::array<bool, 32> used_locations {};
|
||||
for (const auto active_input: active_inputs) {
|
||||
auto location = ShaderPixelParameterMappedLocation(info, active_input);
|
||||
if (location < used_locations.size() && used_locations[location]) {
|
||||
location = active_input;
|
||||
while (location < used_locations.size() && used_locations[location]) {
|
||||
location++;
|
||||
used_locations[ShaderPixelParameterMappedLocation(info, active_input)] = true;
|
||||
}
|
||||
std::array<uint32_t, 64> group_locations;
|
||||
group_locations.fill(UINT32_MAX);
|
||||
for (const auto active_input: active_inputs) {
|
||||
const auto mapped = ShaderPixelParameterMappedLocation(info, active_input);
|
||||
const auto group = mapped * 2u + ShaderPixelParameterIsFlat(info, active_input);
|
||||
auto& location = group_locations[group];
|
||||
if (location == UINT32_MAX) {
|
||||
location = mapped;
|
||||
// Smooth and custom interpolation read the same vertex output. Only
|
||||
// differing flat/smooth rectangle outputs need separate locations.
|
||||
if (group_locations[group ^ 1u] != UINT32_MAX) {
|
||||
location = 0;
|
||||
while (location < used_locations.size() && used_locations[location]) {
|
||||
location++;
|
||||
}
|
||||
EXIT_NOT_IMPLEMENTED(location >= used_locations.size());
|
||||
}
|
||||
EXIT_NOT_IMPLEMENTED(location >= used_locations.size());
|
||||
used_locations[location] = true;
|
||||
}
|
||||
|
||||
if (active_input == input) {
|
||||
return location;
|
||||
}
|
||||
used_locations[location] = true;
|
||||
}
|
||||
return ShaderPixelParameterMappedLocation(info, input);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user