diff options
author | Boris Brezillon <boris.brezillon@collabora.com> | 2020-10-13 12:26:11 +0200 |
---|---|---|
committer | Boris Brezillon <boris.brezillon@collabora.com> | 2020-10-15 08:05:23 +0200 |
commit | 2f3f5da91dee2aa9727e7e2244a262584b0d9c02 (patch) | |
tree | c61d5b979ee554ca26c12de42aa731a86064b31c | |
parent | 8da0a1d5fd4ed256e9cae0d0e61493be3efade85 (diff) |
pan/bi: Collect return addresses of blend calls
We will need that for blend shaders so they can be passed a return
address and jump back to the fragment shader when they're done.
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7151>
-rw-r--r-- | src/panfrost/bifrost/bi_pack.c | 31 | ||||
-rw-r--r-- | src/panfrost/bifrost/bifrost_compile.c | 2 | ||||
-rw-r--r-- | src/panfrost/bifrost/compiler.h | 3 | ||||
-rw-r--r-- | src/panfrost/util/pan_ir.h | 3 |
4 files changed, 39 insertions, 0 deletions
diff --git a/src/panfrost/bifrost/bi_pack.c b/src/panfrost/bifrost/bi_pack.c index 86b7efc8044..0c9dd39459d 100644 --- a/src/panfrost/bifrost/bi_pack.c +++ b/src/panfrost/bifrost/bi_pack.c @@ -1078,6 +1078,34 @@ bi_terminate_discarded_threads(bi_context *ctx) return false; } +static void +bi_collect_blend_ret_addr(bi_context *ctx, struct util_dynarray *emission, + const bi_clause *clause) +{ + /* No need to collect return addresses when we're in a blend shader. */ + if (ctx->is_blend) + return; + + const bi_bundle *bundle = &clause->bundles[clause->bundle_count - 1]; + const bi_instruction *ins = bundle->add; + + if (!ins || ins->type != BI_BLEND) + return; + + /* We don't support non-terminal blend instructions yet. + * That would requires fixing blend shaders to restore the registers + * they use before jumping back to the fragment shader, which is + * currently not supported. + */ + assert(0); + + assert(ins->blend_location < ARRAY_SIZE(ctx->blend_ret_offsets)); + assert(!ctx->blend_ret_offsets[ins->blend_location]); + ctx->blend_ret_offsets[ins->blend_location] = + util_dynarray_num_elements(emission, uint8_t); + assert(!(ctx->blend_ret_offsets[ins->blend_location] & 0x7)); +} + void bi_pack(bi_context *ctx, struct util_dynarray *emission) { @@ -1101,6 +1129,9 @@ bi_pack(bi_context *ctx, struct util_dynarray *emission) bi_clause *next_2 = is_last ? succ_clause : NULL; bi_pack_clause(ctx, clause, next, next_2, emission, ctx->stage, tdd); + + if (!is_last) + bi_collect_blend_ret_addr(ctx, emission, clause); } } } diff --git a/src/panfrost/bifrost/bifrost_compile.c b/src/panfrost/bifrost/bifrost_compile.c index b8191d946c2..1dbfa4361cf 100644 --- a/src/panfrost/bifrost/bifrost_compile.c +++ b/src/panfrost/bifrost/bifrost_compile.c @@ -1806,6 +1806,8 @@ bifrost_compile_shader_nir(nir_shader *nir, panfrost_program *program, bi_print_shader(ctx, stdout); bi_pack(ctx, &program->compiled); + memcpy(program->blend_ret_offsets, ctx->blend_ret_offsets, sizeof(program->blend_ret_offsets)); + if (bifrost_debug & BIFROST_DBG_SHADERS) disassemble_bifrost(stdout, program->compiled.data, program->compiled.size, true); diff --git a/src/panfrost/bifrost/compiler.h b/src/panfrost/bifrost/compiler.h index 7a2a1fd91e6..1debc43f87b 100644 --- a/src/panfrost/bifrost/compiler.h +++ b/src/panfrost/bifrost/compiler.h @@ -453,6 +453,9 @@ typedef struct { /* Blend constants */ float blend_constants[4]; + /* Blend return offsets */ + uint32_t blend_ret_offsets[8]; + /* Blend tile buffer conversion desc */ uint64_t blend_desc; diff --git a/src/panfrost/util/pan_ir.h b/src/panfrost/util/pan_ir.h index 7a04f256068..ccb087f7bf6 100644 --- a/src/panfrost/util/pan_ir.h +++ b/src/panfrost/util/pan_ir.h @@ -88,6 +88,9 @@ typedef struct { /* For Bifrost - output type for each RT */ nir_alu_type blend_types[8]; + /* For Bifrost - return address for blend instructions */ + uint32_t blend_ret_offsets[8]; + /* Prepended before uniforms, mapping to SYSVAL_ names for the * sysval */ |