OSDN Git Service

freedreno/ir3: Add workaround for VS samgq
authorKristian H. Kristensen <hoegsberg@chromium.org>
Wed, 27 Mar 2019 22:31:49 +0000 (15:31 -0700)
committerKristian H. Kristensen <hoegsberg@chromium.org>
Thu, 28 Mar 2019 17:26:32 +0000 (10:26 -0700)
This instruction needs a workaround when used from vertex shaders.

Fixes:

  dEQP-GLES3.functional.shaders.texture_functions.texturegradoffset.sampler2dshadow_vertex
  dEQP-GLES3.functional.shaders.texture_functions.texturegradoffset.sampler3d_fixed_vertex
  dEQP-GLES3.functional.shaders.texture_functions.texturegradoffset.sampler3d_float_vertex
  dEQP-GLES3.functional.shaders.texture_functions.textureprojgradoffset.sampler2dshadow_vertex
  dEQP-GLES3.functional.shaders.texture_functions.textureprojgradoffset.sampler3d_fixed_vertex
  dEQP-GLES3.functional.shaders.texture_functions.textureprojgradoffset.sampler3d_float_vertex
  dEQP-GLES3.functional.shaders.texture_functions.textureprojgrad.sampler2dshadow_vertex

Signed-off-by: Kristian H. Kristensen <hoegsberg@chromium.org>
Reviewed-by: Rob Clark <robdclark@gmail.com>
src/freedreno/ir3/ir3.c
src/freedreno/ir3/ir3.h
src/freedreno/ir3/ir3_compiler.c
src/freedreno/ir3/ir3_compiler.h
src/freedreno/ir3/ir3_compiler_nir.c
src/freedreno/ir3/ir3_legalize.c

index 1bded7d..8c7410a 100644 (file)
@@ -46,11 +46,12 @@ void * ir3_alloc(struct ir3 *shader, int sz)
 }
 
 struct ir3 * ir3_create(struct ir3_compiler *compiler,
-               unsigned nin, unsigned nout)
+               gl_shader_stage type, unsigned nin, unsigned nout)
 {
        struct ir3 *shader = rzalloc(compiler, struct ir3);
 
        shader->compiler = compiler;
+       shader->type = type;
        shader->ninputs = nin;
        shader->inputs = ir3_alloc(shader, sizeof(shader->inputs[0]) * nin);
 
index 6e30f74..8f58d67 100644 (file)
@@ -408,6 +408,7 @@ static inline int ir3_neighbor_count(struct ir3_instruction *instr)
 
 struct ir3 {
        struct ir3_compiler *compiler;
+       gl_shader_stage type;
 
        unsigned ninputs, noutputs;
        struct ir3_instruction **inputs;
@@ -523,7 +524,7 @@ block_id(struct ir3_block *block)
 }
 
 struct ir3 * ir3_create(struct ir3_compiler *compiler,
-               unsigned nin, unsigned nout);
+               gl_shader_stage type, unsigned nin, unsigned nout);
 void ir3_destroy(struct ir3 *shader);
 void * ir3_assemble(struct ir3 *shader,
                struct ir3_info *info, uint32_t gpu_id);
index ac126d5..b0f2b13 100644 (file)
@@ -52,6 +52,10 @@ struct ir3_compiler * ir3_compiler_create(struct fd_device *dev, uint32_t gpu_id
        compiler->gpu_id = gpu_id;
        compiler->set = ir3_ra_alloc_reg_set(compiler);
 
+       if (compiler->gpu_id >= 600) {
+               compiler->samgq_workaround = true;
+       }
+
        if (compiler->gpu_id >= 400) {
                /* need special handling for "flat" */
                compiler->flat_bypass = true;
index 1bc5997..181125f 100644 (file)
@@ -63,6 +63,10 @@ struct ir3_compiler {
         * index coordinate:
         */
        bool array_index_add_half;
+
+       /* on a6xx, rewrite samgp to sequence of samgq0-3 in vertex shaders:
+        */
+       bool samgq_workaround;
 };
 
 struct ir3_compiler * ir3_compiler_create(struct fd_device *dev, uint32_t gpu_id);
index 3b343a3..ad287af 100644 (file)
@@ -2438,7 +2438,7 @@ emit_instructions(struct ir3_context *ctx)
         */
        ninputs += max_sysvals[ctx->so->type];
 
-       ctx->ir = ir3_create(ctx->compiler, ninputs, noutputs);
+       ctx->ir = ir3_create(ctx->compiler, ctx->so->type, ninputs, noutputs);
 
        /* Create inputs in first block: */
        ctx->block = get_block(ctx, nir_start_block(fxn));
index cb9a3f9..e28cac2 100644 (file)
@@ -41,6 +41,7 @@
 
 struct ir3_legalize_ctx {
        struct ir3_compiler *compiler;
+       gl_shader_stage type;
        bool has_ssbo;
        bool need_pixlod;
        int max_bary;
@@ -212,7 +213,20 @@ legalize_block(struct ir3_legalize_ctx *ctx, struct ir3_block *block)
                        }
                }
 
-               list_addtail(&n->node, &block->instr_list);
+               if (ctx->compiler->samgq_workaround &&
+                       ctx->type == MESA_SHADER_VERTEX && n->opc == OPC_SAMGQ) {
+                       struct ir3_instruction *samgp;
+
+                       for (i = 0; i < 4; i++) {
+                               samgp = ir3_instr_clone(n);
+                               samgp->opc = OPC_SAMGP0 + i;
+                               if (i > 1)
+                                       samgp->flags |= IR3_INSTR_SY;
+                       }
+                       list_delinit(&n->node);
+               } else {
+                       list_addtail(&n->node, &block->instr_list);
+               }
 
                if (is_sfu(n))
                        regmask_set(&state->needs_ss, n->regs[0]);
@@ -480,6 +494,7 @@ ir3_legalize(struct ir3 *ir, bool *has_ssbo, bool *need_pixlod, int *max_bary)
 
        ctx->max_bary = -1;
        ctx->compiler = ir->compiler;
+       ctx->type = ir->type;
 
        /* allocate per-block data: */
        list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {