#include "graphics/shader/shader.h" #include "common/assert.h" namespace Libs::Graphics { namespace { constexpr uint32_t PsInputOffsetMask = 0x0000001fu; constexpr uint32_t PsInputFlatShade = 0x00000400u; } // namespace uint32_t ShaderPixelExportTarget(uint32_t shader_mask, uint32_t export_index) { for (uint32_t target = 0; target < 8u; target++) { if (((shader_mask >> (target * 4u)) & 0xfu) == 0u) { continue; } if (export_index == 0u) { return target; } export_index--; } return UINT32_MAX; } uint32_t ShaderPixelParameterMappedLocation(const ShaderPixelInputInfo& info, uint32_t input) { return input < info.input_num ? info.interpolator_settings[input] & PsInputOffsetMask : input; } uint32_t ShaderPixelParameterLocation(const ShaderPixelInputInfo& info, std::span active_inputs, uint32_t input) { if (info.parameter_mode != ShaderPixelParameterMode::Rectangle) { return ShaderPixelParameterMappedLocation(info, input); } std::array used_locations {}; for (const auto active_input: active_inputs) { used_locations[ShaderPixelParameterMappedLocation(info, active_input)] = true; } std::array 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; // Rectangle expansion broadcasts flat aliases through separate outputs. 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()); } used_locations[location] = true; } if (active_input == input) { return location; } } return ShaderPixelParameterMappedLocation(info, input); } bool ShaderPixelParameterIsFlat(const ShaderPixelInputInfo& info, uint32_t input) { return input < info.input_num && (info.interpolator_settings[input] & PsInputFlatShade) != 0 && !ShaderPixelParameterIsCustom(info, input); } bool ShaderPixelParameterIsCustom(const ShaderPixelInputInfo& info, uint32_t input) { return input < 32u && (info.custom_interpolation_mask & (1u << input)) != 0; } } // namespace Libs::Graphics