[vulkan] Implemented active color output tracking in runtime info and update fragment color handling

This commit is contained in:
CamilleLaVey 2026-03-06 18:51:45 -04:00
parent 8a4fc945df
commit 03c4b0a864
4 changed files with 21 additions and 2 deletions

View file

@ -491,6 +491,9 @@ void EmitSetPatch(EmitContext& ctx, IR::Patch patch, Id value) {
} }
void EmitSetFragColor(EmitContext& ctx, u32 index, u32 component, Id value) { void EmitSetFragColor(EmitContext& ctx, u32 index, u32 component, Id value) {
if (!ctx.runtime_info.active_color_outputs[index]) {
return;
}
const Id component_id{ctx.Const(component)}; const Id component_id{ctx.Const(component)};
const AttributeType type{ctx.runtime_info.color_output_types[index]}; const AttributeType type{ctx.runtime_info.color_output_types[index]};
if (type == AttributeType::Float) { if (type == AttributeType::Float) {

View file

@ -1688,8 +1688,10 @@ void EmitContext::DefineOutputs(const IR::Program& program) {
case Stage::Fragment: case Stage::Fragment:
for (u32 index = 0; index < 8; ++index) { for (u32 index = 0; index < 8; ++index) {
const bool need_dual_source = runtime_info.dual_source_blend && index <= 1; const bool need_dual_source = runtime_info.dual_source_blend && index <= 1;
if (!need_dual_source && !info.stores_frag_color[index] && const bool should_declare = runtime_info.active_color_outputs[index] &&
!profile.need_declared_frag_colors) { (info.stores_frag_color[index] ||
profile.need_declared_frag_colors);
if (!need_dual_source && !should_declare) {
continue; continue;
} }
const Id type{GetAttributeType(*this, runtime_info.color_output_types[index])}; const Id type{GetAttributeType(*this, runtime_info.color_output_types[index])};

View file

@ -111,6 +111,9 @@ struct RuntimeInfo {
/// Output types for each color attachment /// Output types for each color attachment
std::array<AttributeType, 8> color_output_types{}; std::array<AttributeType, 8> color_output_types{};
/// Fragment color outputs that are active for the current pipeline.
std::array<bool, 8> active_color_outputs{true, true, true, true, true, true, true, true};
/// Dual source blending /// Dual source blending
bool dual_source_blend{}; bool dual_source_blend{};
}; };

View file

@ -249,6 +249,17 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program
dst_a == F::Source1Alpha_GL || dst_a == F::OneMinusSource1Alpha_GL; dst_a == F::Source1Alpha_GL || dst_a == F::OneMinusSource1Alpha_GL;
} }
for (size_t i = 0; i < info.active_color_outputs.size(); ++i) {
const auto format = static_cast<Tegra::RenderTargetFormat>(key.state.color_formats[i]);
info.active_color_outputs[i] = format != Tegra::RenderTargetFormat::NONE;
}
if (info.dual_source_blend && info.active_color_outputs[0]) {
info.active_color_outputs[1] = true;
}
if (info.alpha_test_func && *info.alpha_test_func != Shader::CompareFunction::Always) {
info.active_color_outputs[0] = true;
}
if (device.IsMoltenVK()) { if (device.IsMoltenVK()) {
for (size_t i = 0; i < 8; ++i) { for (size_t i = 0; i < 8; ++i) {
const auto format = static_cast<Tegra::RenderTargetFormat>(key.state.color_formats[i]); const auto format = static_cast<Tegra::RenderTargetFormat>(key.state.color_formats[i]);