st/nir: fix atomic lowering for gallium drivers
authorTimothy Arceri <tarceri@itsqueeze.com>
Mon, 19 Mar 2018 11:23:55 +0000 (22:23 +1100)
committerTimothy Arceri <tarceri@itsqueeze.com>
Tue, 20 Mar 2018 03:29:53 +0000 (14:29 +1100)
i965 and gallium handle the atomic buffer index differently. It was
just by luck that the single piglit test for this was passing.

For gallium we use the atomic binding so that we match the handling
in st_bind_atomics().

On radeonsi this fixes the CTS test:
KHR-GL43.shader_storage_buffer_object.advanced-write-fragment

It also fixes tressfx hair rendering in Tomb Raider.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/compiler/nir/nir.h
src/compiler/nir/nir_lower_atomics.c
src/mesa/drivers/dri/i965/brw_link.cpp
src/mesa/state_tracker/st_glsl_to_nir.cpp

index d7baabd6f6ee4d9672665b0fb76ae09654fb96c2..0d207d0ea54da479be4f1bb5b3d889716f6a819f 100644 (file)
@@ -2710,7 +2710,8 @@ typedef struct nir_lower_bitmap_options {
 void nir_lower_bitmap(nir_shader *shader, const nir_lower_bitmap_options *options);
 
 bool nir_lower_atomics(nir_shader *shader,
-                       const struct gl_shader_program *shader_program);
+                       const struct gl_shader_program *shader_program,
+                       bool use_binding_as_idx);
 bool nir_lower_atomics_to_ssbo(nir_shader *shader, unsigned ssbo_offset);
 bool nir_lower_to_source_mods(nir_shader *shader);
 
index bdab4b87377374243daeada6cbd2230a9d536210..6b046bc426ea9a095eab73ea809ec217cb51e377 100644 (file)
@@ -38,7 +38,7 @@
 static bool
 lower_instr(nir_intrinsic_instr *instr,
             const struct gl_shader_program *shader_program,
-            nir_shader *shader)
+            nir_shader *shader, bool use_binding_as_idx)
 {
    nir_intrinsic_op op;
    switch (instr->intrinsic) {
@@ -98,9 +98,12 @@ lower_instr(nir_intrinsic_instr *instr,
    void *mem_ctx = ralloc_parent(instr);
    unsigned uniform_loc = instr->variables[0]->var->data.location;
 
+   unsigned idx = use_binding_as_idx ?
+      instr->variables[0]->var->data.binding :
+      shader_program->data->UniformStorage[uniform_loc].opaque[shader->info.stage].index;
+
    nir_intrinsic_instr *new_instr = nir_intrinsic_instr_create(mem_ctx, op);
-   nir_intrinsic_set_base(new_instr,
-      shader_program->data->UniformStorage[uniform_loc].opaque[shader->info.stage].index);
+   nir_intrinsic_set_base(new_instr, idx);
 
    nir_load_const_instr *offset_const =
       nir_load_const_instr_create(mem_ctx, 1, 32);
@@ -174,7 +177,8 @@ lower_instr(nir_intrinsic_instr *instr,
 
 bool
 nir_lower_atomics(nir_shader *shader,
-                  const struct gl_shader_program *shader_program)
+                  const struct gl_shader_program *shader_program,
+                  bool use_binding_as_idx)
 {
    bool progress = false;
 
@@ -184,7 +188,8 @@ nir_lower_atomics(nir_shader *shader,
             nir_foreach_instr_safe(instr, block) {
                if (instr->type == nir_instr_type_intrinsic)
                   progress |= lower_instr(nir_instr_as_intrinsic(instr),
-                                          shader_program, shader);
+                                          shader_program, shader,
+                                          use_binding_as_idx);
             }
          }
 
index b08b56a935301b926e1ef7f8c8a5d9a3ddd1d9e5..274a738cbbf91693b7fc603578830e34927c172d 100644 (file)
@@ -299,7 +299,7 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg)
       brw_shader_gather_info(prog->nir, prog);
 
       NIR_PASS_V(prog->nir, nir_lower_samplers, shProg);
-      NIR_PASS_V(prog->nir, nir_lower_atomics, shProg);
+      NIR_PASS_V(prog->nir, nir_lower_atomics, shProg, false);
       NIR_PASS_V(prog->nir, nir_lower_atomics_to_ssbo,
                  prog->nir->info.num_abos);
 
index 2eb2ece5b164be9b6a6bb455a0f45ad4a5f61d96..9bb99f3061026cc7ac88a73cd7853646072ef7c7 100644 (file)
@@ -414,7 +414,7 @@ st_glsl_to_nir_post_opts(struct st_context *st, struct gl_program *prog,
    st_set_prog_affected_state_flags(prog);
 
    NIR_PASS_V(nir, st_nir_lower_builtin);
-   NIR_PASS_V(nir, nir_lower_atomics, shader_program);
+   NIR_PASS_V(nir, nir_lower_atomics, shader_program, true);
 
    if (st->ctx->_Shader->Flags & GLSL_DUMP) {
       _mesa_log("\n");