diff options
author | Eric Anholt <[email protected]> | 2018-12-05 15:41:35 -0800 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2019-04-12 15:59:31 -0700 |
commit | 6b1c6598250955552439c3320bf26de6458c5281 (patch) | |
tree | 426f6d2c75340f8e186813ab2bcd4ac7a67e098a /src/broadcom | |
parent | 1e0a72ce096bf368e184acfbeed28916cc0e968f (diff) |
v3d: Add Compute Shader compilation support.
While waiting for the CSD UABI to get reviewed, I keep having to rebase
the CS patch. Just land the compiler side for now to keep it from
diverging.
For now this covers just GLES 3.1 compute shaders, not CL kernels.
Diffstat (limited to 'src/broadcom')
-rw-r--r-- | src/broadcom/compiler/nir_to_vir.c | 8 | ||||
-rw-r--r-- | src/broadcom/compiler/v3d_compiler.h | 6 | ||||
-rw-r--r-- | src/broadcom/compiler/vir.c | 34 |
3 files changed, 44 insertions, 4 deletions
diff --git a/src/broadcom/compiler/nir_to_vir.c b/src/broadcom/compiler/nir_to_vir.c index 2b196324754..a7b3adb6c63 100644 --- a/src/broadcom/compiler/nir_to_vir.c +++ b/src/broadcom/compiler/nir_to_vir.c @@ -1806,7 +1806,7 @@ ntq_emit_intrinsic(struct v3d_compile *c, nir_intrinsic_instr *instr) case nir_intrinsic_memory_barrier_atomic_counter: case nir_intrinsic_memory_barrier_buffer: case nir_intrinsic_memory_barrier_image: - case nir_intrinsic_memory_barrier_shared: + case nir_intrinsic_group_memory_barrier: /* We don't do any instruction scheduling of these NIR * instructions between each other, so we just need to make * sure that the TMU operations before the barrier are flushed @@ -1869,6 +1869,10 @@ ntq_emit_intrinsic(struct v3d_compile *c, nir_intrinsic_instr *instr) vir_uniform_ui(c, 0xffff))); break; + case nir_intrinsic_load_subgroup_id: + ntq_store_dest(c, &instr->dest, 0, vir_EIDX(c)); + break; + default: fprintf(stderr, "Unknown intrinsic: "); nir_print_instr(&instr->instr, stderr); @@ -2444,6 +2448,8 @@ v3d_nir_to_vir(struct v3d_compile *c) case MESA_SHADER_VERTEX: emit_vert_end(c); break; + case MESA_SHADER_COMPUTE: + break; default: unreachable("bad stage"); } diff --git a/src/broadcom/compiler/v3d_compiler.h b/src/broadcom/compiler/v3d_compiler.h index 94247860c68..b2bc40b10fe 100644 --- a/src/broadcom/compiler/v3d_compiler.h +++ b/src/broadcom/compiler/v3d_compiler.h @@ -691,6 +691,12 @@ struct v3d_fs_prog_data { bool uses_center_w; }; +struct v3d_compute_prog_data { + struct v3d_prog_data base; + /* Size in bytes of the workgroup's shared space. */ + uint32_t shared_size; +}; + static inline bool vir_has_uniform(struct qinst *inst) { diff --git a/src/broadcom/compiler/vir.c b/src/broadcom/compiler/vir.c index b785b53c62c..6655e5e73bc 100644 --- a/src/broadcom/compiler/vir.c +++ b/src/broadcom/compiler/vir.c @@ -562,6 +562,21 @@ v3d_lower_nir(struct v3d_compile *c) } } + /* CS textures may not have return_size reflecting the shadow state. */ + nir_foreach_variable(var, &c->s->uniforms) { + const struct glsl_type *type = glsl_without_array(var->type); + unsigned array_len = MAX2(glsl_get_length(var->type), 1); + + if (!glsl_type_is_sampler(type) || + !glsl_sampler_type_is_shadow(type)) + continue; + + for (int i = 0; i < array_len; i++) { + tex_options.lower_tex_packing[var->data.binding + i] = + nir_lower_tex_packing_16; + } + } + NIR_PASS_V(c->s, nir_lower_tex, &tex_options); NIR_PASS_V(c->s, nir_lower_system_values); } @@ -670,6 +685,13 @@ v3d_fs_set_prog_data(struct v3d_compile *c, } static void +v3d_cs_set_prog_data(struct v3d_compile *c, + struct v3d_compute_prog_data *prog_data) +{ + prog_data->shared_size = c->s->info.cs.shared_size; +} + +static void v3d_set_prog_data(struct v3d_compile *c, struct v3d_prog_data *prog_data) { @@ -679,7 +701,9 @@ v3d_set_prog_data(struct v3d_compile *c, v3d_set_prog_data_uniforms(c, prog_data); - if (c->s->info.stage == MESA_SHADER_VERTEX) { + if (c->s->info.stage == MESA_SHADER_COMPUTE) { + v3d_cs_set_prog_data(c, (struct v3d_compute_prog_data *)prog_data); + } else if (c->s->info.stage == MESA_SHADER_VERTEX) { v3d_vs_set_prog_data(c, (struct v3d_vs_prog_data *)prog_data); } else { assert(c->s->info.stage == MESA_SHADER_FRAGMENT); @@ -865,13 +889,17 @@ uint64_t *v3d_compile(const struct v3d_compiler *compiler, c->fs_key = (struct v3d_fs_key *)key; prog_data = rzalloc_size(NULL, sizeof(struct v3d_fs_prog_data)); break; + case MESA_SHADER_COMPUTE: + prog_data = rzalloc_size(NULL, + sizeof(struct v3d_compute_prog_data)); + break; default: unreachable("unsupported shader stage"); } if (c->s->info.stage == MESA_SHADER_VERTEX) { v3d_nir_lower_vs_early(c); - } else { + } else if (c->s->info.stage != MESA_SHADER_COMPUTE) { assert(c->s->info.stage == MESA_SHADER_FRAGMENT); v3d_nir_lower_fs_early(c); } @@ -880,7 +908,7 @@ uint64_t *v3d_compile(const struct v3d_compiler *compiler, if (c->s->info.stage == MESA_SHADER_VERTEX) { v3d_nir_lower_vs_late(c); - } else { + } else if (c->s->info.stage != MESA_SHADER_COMPUTE) { assert(c->s->info.stage == MESA_SHADER_FRAGMENT); v3d_nir_lower_fs_late(c); } |