diff --git a/src/asahi/vulkan/hk_cmd_buffer.c b/src/asahi/vulkan/hk_cmd_buffer.c index ff4d69cb7e3..874ff46ffd6 100644 --- a/src/asahi/vulkan/hk_cmd_buffer.c +++ b/src/asahi/vulkan/hk_cmd_buffer.c @@ -695,8 +695,11 @@ hk_upload_usc_words(struct hk_cmd_buffer *cmd, struct hk_shader *s, hk_usc_upload_spilled_rt_descs(&b, cmd); } - agx_usc_uniform( - &b, 4, 8, root_ptr + hk_root_descriptor_offset(draw.blend_constant)); + if (cmd->state.gfx.uses_blend_constant) { + agx_usc_uniform( + &b, 4, 8, + root_ptr + hk_root_descriptor_offset(draw.blend_constant)); + } /* The SHARED state is baked into linked->usc for non-fragment shaders. We * don't pass around the information to bake the tilebuffer layout. diff --git a/src/asahi/vulkan/hk_cmd_buffer.h b/src/asahi/vulkan/hk_cmd_buffer.h index 1a491742e83..2a69a1c12af 100644 --- a/src/asahi/vulkan/hk_cmd_buffer.h +++ b/src/asahi/vulkan/hk_cmd_buffer.h @@ -268,6 +268,9 @@ struct hk_graphics_state { struct hk_linked_shader *linked[PIPE_SHADER_TYPES]; bool generate_primitive_id; + /* Whether blend constants are required by the active blend state */ + bool uses_blend_constant; + /* Tessellation state */ struct { uint64_t out_draws; diff --git a/src/asahi/vulkan/hk_cmd_draw.c b/src/asahi/vulkan/hk_cmd_draw.c index f5e747c5a82..92528535590 100644 --- a/src/asahi/vulkan/hk_cmd_draw.c +++ b/src/asahi/vulkan/hk_cmd_draw.c @@ -2534,6 +2534,36 @@ hk_depth_bias_factor(VkFormat format, bool exact, bool force_unorm) } } +static bool +uses_blend_constant(const struct vk_color_blend_state *cb) +{ + static_assert(VK_BLEND_FACTOR_CONSTANT_COLOR + 1 == + VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR); + + static_assert(VK_BLEND_FACTOR_CONSTANT_COLOR + 2 == + VK_BLEND_FACTOR_CONSTANT_ALPHA); + + static_assert(VK_BLEND_FACTOR_CONSTANT_COLOR + 3 == + VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA); + + for (unsigned i = 0; i < cb->attachment_count; ++i) { + unsigned factors[] = { + cb->attachments[i].src_color_blend_factor, + cb->attachments[i].src_alpha_blend_factor, + cb->attachments[i].dst_color_blend_factor, + cb->attachments[i].dst_alpha_blend_factor, + }; + + for (unsigned j = 0; j < ARRAY_SIZE(factors); ++j) { + if (factors[j] >= VK_BLEND_FACTOR_CONSTANT_COLOR && + factors[j] <= VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA) + return true; + } + } + + return false; +} + static void hk_flush_dynamic_state(struct hk_cmd_buffer *cmd, struct hk_cs *cs, uint32_t draw_id, struct agx_draw draw) @@ -2576,6 +2606,10 @@ hk_flush_dynamic_state(struct hk_cmd_buffer *cmd, struct hk_cs *cs, desc->root_dirty = true; } + if (IS_DIRTY(CB_BLEND_EQUATIONS) || IS_DIRTY(CB_BLEND_ENABLES)) { + gfx->uses_blend_constant = uses_blend_constant(&dyn->cb); + } + if (IS_DIRTY(MS_SAMPLE_MASK)) { desc->root.draw.api_sample_mask = dyn->ms.sample_mask; desc->root_dirty = true;