From: Samuel Pitoiset Date: Thu, 11 Jun 2020 14:27:17 +0000 (+0200) Subject: radv: compute CB_SHADER_MASK from the fragment shader outputs X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=70cc80805ce5b027bece7334349ae8b028bf2862;p=mesa.git radv: compute CB_SHADER_MASK from the fragment shader outputs The fragment shader doesn't necessarily output the number of components expected by the target format. Fixes new dEQP-VK.draw.output_location.*. Signed-off-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen Part-of: --- diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 76244ecf503..fcc23aacd37 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -530,7 +530,6 @@ radv_pipeline_compute_spi_color_formats(struct radv_pipeline *pipeline, if (blend->mrt0_is_dual_src) col_format |= (col_format & 0xf) << 4; - blend->cb_shader_mask = ac_get_cb_shader_mask(col_format); blend->spi_shader_col_format = col_format; } @@ -5119,6 +5118,11 @@ radv_pipeline_init(struct radv_pipeline *pipeline, blend.spi_shader_col_format = V_028714_SPI_SHADER_32_R; } + blend.cb_shader_mask = ps->info.ps.cb_shader_mask; + if (blend.mrt0_is_dual_src) { + blend.cb_shader_mask |= (blend.cb_shader_mask & 0xf) << 4; + } + if (extra && (extra->custom_blend_mode == V_028808_CB_ELIMINATE_FAST_CLEAR || extra->custom_blend_mode == V_028808_CB_FMASK_DECOMPRESS || diff --git a/src/amd/vulkan/radv_shader.h b/src/amd/vulkan/radv_shader.h index 7a621f732ef..ee4b01a34c2 100644 --- a/src/amd/vulkan/radv_shader.h +++ b/src/amd/vulkan/radv_shader.h @@ -310,6 +310,7 @@ struct radv_shader_info { uint32_t explicit_shaded_mask; uint32_t float16_shaded_mask; uint32_t num_interp; + uint32_t cb_shader_mask; bool can_discard; bool early_fragment_test; bool post_depth_coverage; diff --git a/src/amd/vulkan/radv_shader_info.c b/src/amd/vulkan/radv_shader_info.c index c7e26ba176f..dc4aea1d219 100644 --- a/src/amd/vulkan/radv_shader_info.c +++ b/src/amd/vulkan/radv_shader_info.c @@ -537,6 +537,17 @@ gather_info_output_decl_ps(const nir_shader *nir, const nir_variable *var, default: break; } + + if (idx >= FRAG_RESULT_DATA0 && idx <= FRAG_RESULT_DATA7) { + unsigned num_components = glsl_get_component_slots(glsl_without_array(var->type)); + unsigned num_slots = glsl_count_attribute_slots(var->type, false); + unsigned write_mask = (1 << num_components) - 1; + unsigned slot = idx - FRAG_RESULT_DATA0; + + for (unsigned i = 0; i < num_slots; i++) { + info->ps.cb_shader_mask |= write_mask << ((slot + i) * 4); + } + } } static void @@ -834,4 +845,18 @@ radv_nir_shader_info_pass(const struct nir_shader *nir, } info->float_controls_mode = nir->info.float_controls_execution_mode; + + if (nir->info.stage == MESA_SHADER_FRAGMENT) { + /* If the i-th output is used, all previous outputs must be + * non-zero to match the target format. + * TODO: compact MRT to avoid holes and to remove this + * workaround. + */ + unsigned num_targets = (util_last_bit(info->ps.cb_shader_mask) + 3) / 4; + for (unsigned i = 0; i < num_targets; i++) { + if (!(info->ps.cb_shader_mask & (0xf << (i * 4)))) { + info->ps.cb_shader_mask |= 0xf << (i * 4); + } + } + } }