diff --git a/src/imagination/pco/pco_data.h b/src/imagination/pco/pco_data.h index baa1bb2fc9a..2dc0757cefa 100644 --- a/src/imagination/pco/pco_data.h +++ b/src/imagination/pco/pco_data.h @@ -119,6 +119,7 @@ typedef struct _pco_fs_data { } uses; struct { + bool alpha_to_one; bool sample_mask; } meta_present; } pco_fs_data; diff --git a/src/imagination/pco/pco_nir_pvfio.c b/src/imagination/pco/pco_nir_pvfio.c index 6fffa5ce779..2e852c441e2 100644 --- a/src/imagination/pco/pco_nir_pvfio.c +++ b/src/imagination/pco/pco_nir_pvfio.c @@ -1136,6 +1136,38 @@ bool pco_nir_lower_alpha_to_coverage(nir_shader *shader) NULL); } +static nir_def * +lower_alpha_to_one(nir_builder *b, nir_instr *instr, UNUSED void *cb_data) +{ + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); + + nir_src *input_src = &intr->src[0]; + nir_def *input = input_src->ssa; + nir_src *offset = &intr->src[1]; + assert(nir_src_as_uint(*offset) == 0); + + /* Skip color write that don't include alpha. */ + if (input->num_components != 4) + return NULL; + + b->cursor = nir_before_instr(&intr->instr); + + /* TODO: define or other way of representing bit 0 of metadata... */ + nir_def *alpha_to_one_enabled = + nir_ine_imm(b, + nir_ubitfield_extract_imm(b, nir_load_fs_meta_pco(b), 0, 1), + 0); + + nir_def *alpha = nir_bcsel(b, + alpha_to_one_enabled, + nir_imm_float(b, 1.0f), + nir_channel(b, input, 3)); + + nir_src_rewrite(input_src, nir_vector_insert_imm(b, input, alpha, 3)); + + return NIR_LOWER_INSTR_PROGRESS; +} + static bool is_load_sample_mask(const nir_instr *instr, UNUSED const void *cb_data) { @@ -1191,6 +1223,12 @@ bool pco_nir_pfo(nir_shader *shader, pco_fs_data *fs) bool progress = false; + if (fs->meta_present.alpha_to_one) + progress |= nir_shader_lower_instructions(shader, + is_frag_color_out, + lower_alpha_to_one, + &state); + progress |= nir_shader_lower_instructions(shader, is_pfo, lower_pfo, &state); progress |= lower_isp_fb(&b, &state); diff --git a/src/imagination/vulkan/pvr_cmd_buffer.c b/src/imagination/vulkan/pvr_cmd_buffer.c index 06bc2f4ceb5..44e0944389d 100644 --- a/src/imagination/vulkan/pvr_cmd_buffer.c +++ b/src/imagination/vulkan/pvr_cmd_buffer.c @@ -3930,6 +3930,9 @@ static VkResult pvr_setup_descriptor_mappings( case PVR_BUFFER_TYPE_FS_META: { uint32_t fs_meta = 0; + if (cmd_buffer->vk.dynamic_graphics_state.ms.alpha_to_one_enable) + fs_meta |= (1 << 0); + fs_meta |= cmd_buffer->vk.dynamic_graphics_state.ms.sample_mask << 9; diff --git a/src/imagination/vulkan/pvr_device.c b/src/imagination/vulkan/pvr_device.c index c203ebab94d..2bbc8a7c458 100644 --- a/src/imagination/vulkan/pvr_device.c +++ b/src/imagination/vulkan/pvr_device.c @@ -228,7 +228,7 @@ static void pvr_physical_device_get_supported_features( .depthBounds = false, .wideLines = false, .largePoints = true, - .alphaToOne = false, + .alphaToOne = true, .multiViewport = false, .samplerAnisotropy = false, .textureCompressionETC2 = true, diff --git a/src/imagination/vulkan/pvr_pipeline.c b/src/imagination/vulkan/pvr_pipeline.c index 2065da24030..f83cf5daa49 100644 --- a/src/imagination/vulkan/pvr_pipeline.c +++ b/src/imagination/vulkan/pvr_pipeline.c @@ -1846,6 +1846,7 @@ static void pvr_alloc_fs_sysvals(pco_data *data, nir_shader *nir) assert(BITSET_IS_EMPTY(system_values_read)); + has_meta |= data->fs.meta_present.alpha_to_one; has_meta |= data->fs.meta_present.sample_mask; if (!has_meta) return; @@ -2479,6 +2480,11 @@ pvr_preprocess_shader_data(pco_data *data, data->fs.uses.alpha_to_coverage = state->ms->alpha_to_coverage_enable; + if (BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_MS_ALPHA_TO_ONE_ENABLE) || + (state->ms && state->ms->alpha_to_one_enable)) { + data->fs.meta_present.alpha_to_one = true; + } + if (BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_MS_SAMPLE_MASK) || (state->ms && state->ms->sample_mask != 0xffff)) { data->fs.meta_present.sample_mask = true;