ac/shader: scan if fragment shaders write memory
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Wed, 24 Jan 2018 16:44:35 +0000 (17:44 +0100)
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>
Fri, 26 Jan 2018 11:14:27 +0000 (12:14 +0100)
It's better to do that in ac_shader_info.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
src/amd/common/ac_nir_to_llvm.c
src/amd/common/ac_nir_to_llvm.h
src/amd/common/ac_shader_info.c
src/amd/common/ac_shader_info.h
src/amd/vulkan/radv_pipeline.c

index 581ccf6..7b6d7bc 100644 (file)
@@ -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;
index 1656289..1484bf1 100644 (file)
@@ -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;
index 5716ec0..d771cd2 100644 (file)
@@ -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);
        }
 }
index 2be6167..59b7495 100644 (file)
@@ -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;
index 62faa3e..589e49a 100644 (file)
@@ -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);