diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 7e1632c9484..714a0d9926b 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -126,6 +126,7 @@ const struct radv_dynamic_state default_dynamic_state = { .tess_domain_origin = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT, .logic_op_enable = 0u, .stippled_line_enable = 0u, + .alpha_to_coverage_enable = 0u, }; static void @@ -267,6 +268,8 @@ radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer, const struct radv_dy RADV_CMP_COPY(stippled_line_enable, RADV_DYNAMIC_LINE_STIPPLE_ENABLE); + RADV_CMP_COPY(alpha_to_coverage_enable, RADV_DYNAMIC_ALPHA_TO_COVERAGE_ENABLE); + #undef RADV_CMP_COPY cmd_buffer->state.dirty |= dest_mask; @@ -1460,7 +1463,8 @@ radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer) RADV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE | RADV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE | RADV_CMD_DIRTY_DYNAMIC_STENCIL_OP | - RADV_CMD_DIRTY_DYNAMIC_PATCH_CONTROL_POINTS; + RADV_CMD_DIRTY_DYNAMIC_PATCH_CONTROL_POINTS | + RADV_CMD_DIRTY_DYNAMIC_ALPHA_TO_COVERAGE_ENABLE; if (!cmd_buffer->state.emitted_graphics_pipeline || cmd_buffer->state.emitted_graphics_pipeline->negative_one_to_one != pipeline->negative_one_to_one || @@ -3358,6 +3362,27 @@ radv_emit_line_stipple_enable(struct radv_cmd_buffer *cmd_buffer) radeon_set_context_reg(cmd_buffer->cs, R_028A48_PA_SC_MODE_CNTL_0, pa_sc_mode_cntl_0); } +static void +radv_emit_alpha_to_coverage_enable(struct radv_cmd_buffer *cmd_buffer) +{ + struct radv_dynamic_state *d = &cmd_buffer->state.dynamic; + unsigned db_alpha_to_mask = 0; + + if (cmd_buffer->device->instance->debug_flags & RADV_DEBUG_NO_ATOC_DITHERING) { + db_alpha_to_mask = S_028B70_ALPHA_TO_MASK_OFFSET0(2) | S_028B70_ALPHA_TO_MASK_OFFSET1(2) | + S_028B70_ALPHA_TO_MASK_OFFSET2(2) | S_028B70_ALPHA_TO_MASK_OFFSET3(2) | + S_028B70_OFFSET_ROUND(0); + } else { + db_alpha_to_mask = S_028B70_ALPHA_TO_MASK_OFFSET0(3) | S_028B70_ALPHA_TO_MASK_OFFSET1(1) | + S_028B70_ALPHA_TO_MASK_OFFSET2(0) | S_028B70_ALPHA_TO_MASK_OFFSET3(2) | + S_028B70_OFFSET_ROUND(1); + } + + db_alpha_to_mask |= S_028B70_ALPHA_TO_MASK_ENABLE(d->alpha_to_coverage_enable); + + radeon_set_context_reg(cmd_buffer->cs, R_028B70_DB_ALPHA_TO_MASK, db_alpha_to_mask); +} + static void radv_cmd_buffer_flush_dynamic_state(struct radv_cmd_buffer *cmd_buffer, bool pipeline_is_dirty) { @@ -3440,6 +3465,9 @@ radv_cmd_buffer_flush_dynamic_state(struct radv_cmd_buffer *cmd_buffer, bool pip if (states & RADV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE_ENABLE) radv_emit_line_stipple_enable(cmd_buffer); + if (states & RADV_CMD_DIRTY_DYNAMIC_ALPHA_TO_COVERAGE_ENABLE) + radv_emit_alpha_to_coverage_enable(cmd_buffer); + cmd_buffer->state.dirty &= ~states; } @@ -5878,6 +5906,17 @@ radv_CmdSetLineStippleEnableEXT(VkCommandBuffer commandBuffer, VkBool32 stippled state->dirty |= RADV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE_ENABLE; } +VKAPI_ATTR void VKAPI_CALL +radv_CmdSetAlphaToCoverageEnableEXT(VkCommandBuffer commandBuffer, VkBool32 alphaToCoverageEnable) +{ + RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); + struct radv_cmd_state *state = &cmd_buffer->state; + + state->dynamic.alpha_to_coverage_enable = alphaToCoverageEnable; + + state->dirty |= RADV_CMD_DIRTY_DYNAMIC_ALPHA_TO_COVERAGE_ENABLE; +} + VKAPI_ATTR void VKAPI_CALL radv_CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer *pCmdBuffers) diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 4403fa4ff42..0394160d158 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -63,7 +63,6 @@ struct radv_blend_state { uint32_t col_format_is_int10; uint32_t col_format_is_float32; uint32_t cb_shader_mask; - uint32_t db_alpha_to_mask; uint32_t commutative_4bit; @@ -717,21 +716,12 @@ radv_pipeline_init_blend_state(struct radv_graphics_pipeline *pipeline, const enum amd_gfx_level gfx_level = device->physical_device->rad_info.gfx_level; int i; - if (device->instance->debug_flags & RADV_DEBUG_NO_ATOC_DITHERING) - { - blend.db_alpha_to_mask = S_028B70_ALPHA_TO_MASK_OFFSET0(2) | S_028B70_ALPHA_TO_MASK_OFFSET1(2) | - S_028B70_ALPHA_TO_MASK_OFFSET2(2) | S_028B70_ALPHA_TO_MASK_OFFSET3(2) | - S_028B70_OFFSET_ROUND(0); - } - else - { - blend.db_alpha_to_mask = S_028B70_ALPHA_TO_MASK_OFFSET0(3) | S_028B70_ALPHA_TO_MASK_OFFSET1(1) | - S_028B70_ALPHA_TO_MASK_OFFSET2(0) | S_028B70_ALPHA_TO_MASK_OFFSET3(2) | - S_028B70_OFFSET_ROUND(1); - } - - if (state->ms && state->ms->alpha_to_coverage_enable) { - blend.db_alpha_to_mask |= S_028B70_ALPHA_TO_MASK_ENABLE(1); + if (state->ms && ((pipeline->dynamic_states & RADV_DYNAMIC_ALPHA_TO_COVERAGE_ENABLE) || + state->ms->alpha_to_coverage_enable)) { + /* When alpha to coverage is enabled, the driver needs to select a color export format with + * alpha. When this state is dynamic, always select a format with alpha because it's hard to + * change color export formats dynamically (note that it's suboptimal). + */ blend.need_src_alpha |= 0x1; } @@ -1904,6 +1894,10 @@ radv_pipeline_init_dynamic_state(struct radv_graphics_pipeline *pipeline, dynamic->stippled_line_enable = state->rs->line.stipple.enable; } + if (states & RADV_DYNAMIC_ALPHA_TO_COVERAGE_ENABLE) { + dynamic->alpha_to_coverage_enable = state->ms->alpha_to_coverage_enable; + } + pipeline->dynamic_state.mask = states; } @@ -4792,7 +4786,6 @@ radv_pipeline_emit_blend_state(struct radeon_cmdbuf *ctx_cs, radeon_set_context_reg_seq(ctx_cs, R_028780_CB_BLEND0_CONTROL, 8); radeon_emit_array(ctx_cs, blend->cb_blend_control, 8); - radeon_set_context_reg(ctx_cs, R_028B70_DB_ALPHA_TO_MASK, blend->db_alpha_to_mask); if (pdevice->rad_info.has_rbplus) { diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 51f7d6f3fae..ff27b6f6c78 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -1359,6 +1359,8 @@ struct radv_dynamic_state { bool logic_op_enable; bool stippled_line_enable; + + bool alpha_to_coverage_enable; }; extern const struct radv_dynamic_state default_dynamic_state;