aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristian H. Kristensen <[email protected]>2019-03-27 15:31:49 -0700
committerKristian H. Kristensen <[email protected]>2019-03-28 10:26:32 -0700
commit107a8ec3b331f0b9bbaa489689ffd080100ef6e9 (patch)
treed5e697fda78e0062af3c67a7e5522b1cf935538a
parentf30d4a1ccaece3578fb92d245cc44a5c7dccdd7d (diff)
freedreno/ir3: Add workaround for VS samgq
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 <[email protected]> Reviewed-by: Rob Clark <[email protected]>
-rw-r--r--src/freedreno/ir3/ir3.c3
-rw-r--r--src/freedreno/ir3/ir3.h3
-rw-r--r--src/freedreno/ir3/ir3_compiler.c4
-rw-r--r--src/freedreno/ir3/ir3_compiler.h4
-rw-r--r--src/freedreno/ir3/ir3_compiler_nir.c2
-rw-r--r--src/freedreno/ir3/ir3_legalize.c17
6 files changed, 29 insertions, 4 deletions
diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c
index 1bded7dd122..8c7410a8213 100644
--- a/src/freedreno/ir3/ir3.c
+++ b/src/freedreno/ir3/ir3.c
@@ -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);
diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h
index 6e30f74d4ab..8f58d67fb94 100644
--- a/src/freedreno/ir3/ir3.h
+++ b/src/freedreno/ir3/ir3.h
@@ -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);
diff --git a/src/freedreno/ir3/ir3_compiler.c b/src/freedreno/ir3/ir3_compiler.c
index ac126d5b98f..b0f2b139d5e 100644
--- a/src/freedreno/ir3/ir3_compiler.c
+++ b/src/freedreno/ir3/ir3_compiler.c
@@ -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;
diff --git a/src/freedreno/ir3/ir3_compiler.h b/src/freedreno/ir3/ir3_compiler.h
index 1bc59970c4e..181125fa3b1 100644
--- a/src/freedreno/ir3/ir3_compiler.h
+++ b/src/freedreno/ir3/ir3_compiler.h
@@ -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);
diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c
index 3b343a3055f..ad287afd308 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -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));
diff --git a/src/freedreno/ir3/ir3_legalize.c b/src/freedreno/ir3/ir3_legalize.c
index cb9a3f97292..e28cac216b5 100644
--- a/src/freedreno/ir3/ir3_legalize.c
+++ b/src/freedreno/ir3/ir3_legalize.c
@@ -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) {