From b358e0e67fac397713bc00e0b8e0278d691af282 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Wed, 24 Jan 2018 17:44:35 +0100 Subject: [PATCH] ac/shader: scan if fragment shaders write memory It's better to do that in ac_shader_info. Signed-off-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen --- src/amd/common/ac_nir_to_llvm.c | 6 ----- src/amd/common/ac_nir_to_llvm.h | 1 - src/amd/common/ac_shader_info.c | 41 ++++++++++++++++++++++++++++----- src/amd/common/ac_shader_info.h | 1 + src/amd/vulkan/radv_pipeline.c | 6 ++--- 5 files changed, 39 insertions(+), 16 deletions(-) diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index 581ccf63c9a..7b6d7bca9c1 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -4558,9 +4558,6 @@ static LLVMValueRef radv_load_ssbo(struct ac_shader_abi *abi, { struct nir_to_llvm_context *ctx = nir_to_llvm_context_from_abi(abi); - if (write && ctx->stage == MESA_SHADER_FRAGMENT) - ctx->shader_info->fs.writes_memory = true; - return LLVMBuildLoad(ctx->builder, buffer_ptr, ""); } @@ -4591,9 +4588,6 @@ static LLVMValueRef radv_get_sampler_desc(struct ac_shader_abi *abi, assert(base_index < layout->binding_count); - if (write && ctx->stage == MESA_SHADER_FRAGMENT) - ctx->shader_info->fs.writes_memory = true; - switch (desc_type) { case AC_DESC_IMAGE: type = ctx->ac.v8i32; diff --git a/src/amd/common/ac_nir_to_llvm.h b/src/amd/common/ac_nir_to_llvm.h index 1656289e06e..1484bf1d839 100644 --- a/src/amd/common/ac_nir_to_llvm.h +++ b/src/amd/common/ac_nir_to_llvm.h @@ -179,7 +179,6 @@ struct ac_shader_variant_info { bool writes_stencil; bool writes_sample_mask; bool early_fragment_test; - bool writes_memory; bool prim_id_input; bool layer_input; } fs; diff --git a/src/amd/common/ac_shader_info.c b/src/amd/common/ac_shader_info.c index 5716ec043d5..d771cd250dc 100644 --- a/src/amd/common/ac_shader_info.c +++ b/src/amd/common/ac_shader_info.c @@ -31,7 +31,7 @@ static void mark_sampler_desc(const nir_variable *var, } static void -gather_intrinsic_info(const nir_intrinsic_instr *instr, +gather_intrinsic_info(const nir_shader *nir, const nir_intrinsic_instr *instr, struct ac_shader_info *info) { switch (instr->intrinsic) { @@ -104,15 +104,43 @@ gather_intrinsic_info(const nir_intrinsic_instr *instr, dim == GLSL_SAMPLER_DIM_SUBPASS_MS) info->ps.uses_input_attachments = true; mark_sampler_desc(instr->variables[0]->var, info); + + if (nir_intrinsic_image_store || + nir_intrinsic_image_atomic_add || + nir_intrinsic_image_atomic_min || + nir_intrinsic_image_atomic_max || + nir_intrinsic_image_atomic_and || + nir_intrinsic_image_atomic_or || + nir_intrinsic_image_atomic_xor || + nir_intrinsic_image_atomic_exchange || + nir_intrinsic_image_atomic_comp_swap) { + if (nir->info.stage == MESA_SHADER_FRAGMENT) + info->ps.writes_memory = true; + } break; } + case nir_intrinsic_store_ssbo: + case nir_intrinsic_ssbo_atomic_add: + case nir_intrinsic_ssbo_atomic_imin: + case nir_intrinsic_ssbo_atomic_umin: + case nir_intrinsic_ssbo_atomic_imax: + case nir_intrinsic_ssbo_atomic_umax: + case nir_intrinsic_ssbo_atomic_and: + case nir_intrinsic_ssbo_atomic_or: + case nir_intrinsic_ssbo_atomic_xor: + case nir_intrinsic_ssbo_atomic_exchange: + case nir_intrinsic_ssbo_atomic_comp_swap: + if (nir->info.stage == MESA_SHADER_FRAGMENT) + info->ps.writes_memory = true; + break; default: break; } } static void -gather_tex_info(const nir_tex_instr *instr, struct ac_shader_info *info) +gather_tex_info(const nir_shader *nir, const nir_tex_instr *instr, + struct ac_shader_info *info) { if (instr->sampler) mark_sampler_desc(instr->sampler->var, info); @@ -121,15 +149,16 @@ gather_tex_info(const nir_tex_instr *instr, struct ac_shader_info *info) } static void -gather_info_block(const nir_block *block, struct ac_shader_info *info) +gather_info_block(const nir_shader *nir, const nir_block *block, + struct ac_shader_info *info) { nir_foreach_instr(instr, block) { switch (instr->type) { case nir_instr_type_intrinsic: - gather_intrinsic_info(nir_instr_as_intrinsic(instr), info); + gather_intrinsic_info(nir, nir_instr_as_intrinsic(instr), info); break; case nir_instr_type_tex: - gather_tex_info(nir_instr_as_tex(instr), info); + gather_tex_info(nir, nir_instr_as_tex(instr), info); break; default: break; @@ -165,6 +194,6 @@ ac_nir_shader_info_pass(const struct nir_shader *nir, gather_info_input_decl(nir, variable, info); nir_foreach_block(block, func->impl) { - gather_info_block(block, info); + gather_info_block(nir, block, info); } } diff --git a/src/amd/common/ac_shader_info.h b/src/amd/common/ac_shader_info.h index 2be61679fc7..59b749576aa 100644 --- a/src/amd/common/ac_shader_info.h +++ b/src/amd/common/ac_shader_info.h @@ -42,6 +42,7 @@ struct ac_shader_info { bool force_persample; bool needs_sample_positions; bool uses_input_attachments; + bool writes_memory; } ps; struct { bool uses_grid_size; diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 62faa3e473b..589e49a813d 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -2497,7 +2497,7 @@ radv_pipeline_init(struct radv_pipeline *pipeline, unsigned z_order; pipeline->graphics.db_shader_control = 0; - if (ps->info.fs.early_fragment_test || !ps->info.fs.writes_memory) + if (ps->info.fs.early_fragment_test || !ps->info.info.ps.writes_memory) z_order = V_02880C_EARLY_Z_THEN_LATE_Z; else z_order = V_02880C_LATE_Z; @@ -2509,8 +2509,8 @@ radv_pipeline_init(struct radv_pipeline *pipeline, S_02880C_MASK_EXPORT_ENABLE(ps->info.fs.writes_sample_mask) | S_02880C_Z_ORDER(z_order) | S_02880C_DEPTH_BEFORE_SHADER(ps->info.fs.early_fragment_test) | - S_02880C_EXEC_ON_HIER_FAIL(ps->info.fs.writes_memory) | - S_02880C_EXEC_ON_NOOP(ps->info.fs.writes_memory); + S_02880C_EXEC_ON_HIER_FAIL(ps->info.info.ps.writes_memory) | + S_02880C_EXEC_ON_NOOP(ps->info.info.ps.writes_memory); if (pipeline->device->physical_device->has_rbplus) pipeline->graphics.db_shader_control |= S_02880C_DUAL_QUAD_DISABLE(1);