freedreno/ir3: Fix SSBO size for bindless SSBO's
authorConnor Abbott <cwabbott0@gmail.com>
Tue, 21 Jul 2020 14:20:14 +0000 (16:20 +0200)
committerMarge Bot <eric+marge@anholt.net>
Tue, 21 Jul 2020 19:53:32 +0000 (19:53 +0000)
We theoretically could push these sizes to the const file
opportunistically, which appears to be what the blob does, but the
maximum number of SSBO's is way too big to do that unconditionally. Just
use resinfo to get the size for now.

Fixes on turnip: dEQP-VK.ssbo.unsized_array_length.*

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6012>

src/freedreno/ir3/ir3_compiler_nir.c
src/freedreno/ir3/ir3_nir.c

index 10a51eb55e7a4a410c5e2326c48c82350e34e1ca..8c4df26b99a898924555254d3c80c7c898334d40 100644 (file)
@@ -847,6 +847,28 @@ static void
 emit_intrinsic_ssbo_size(struct ir3_context *ctx, nir_intrinsic_instr *intr,
                struct ir3_instruction **dst)
 {
+       if (ir3_bindless_resource(intr->src[0])) {
+               struct ir3_block *b = ctx->block;
+               struct ir3_instruction *ibo = ir3_ssbo_to_ibo(ctx, intr->src[0]);
+               struct ir3_instruction *resinfo = ir3_RESINFO(b, ibo, 0);
+               resinfo->cat6.iim_val = 1;
+               resinfo->cat6.d = 1;
+               resinfo->cat6.type = TYPE_U32;
+               resinfo->cat6.typed = false;
+               /* resinfo has no writemask and always writes out 3 components */
+               resinfo->regs[0]->wrmask = MASK(3);
+               ir3_handle_bindless_cat6(resinfo, intr->src[0]);
+               struct ir3_instruction *resinfo_dst;
+               ir3_split_dest(b, &resinfo_dst, resinfo, 0, 1);
+               /* Unfortunately resinfo returns the array length, i.e. in dwords,
+                * while NIR expects us to return the size in bytes.
+                *
+                * TODO: fix this in NIR.
+                */
+               *dst = ir3_SHL_B(b, resinfo_dst, 0, create_immed(b, 2), 0);
+               return;
+       }
+
        /* SSBO size stored as a const starting at ssbo_sizes: */
        const struct ir3_const_state *const_state = ir3_const_state(ctx->so);
        unsigned blk_idx = nir_src_as_uint(intr->src[0]);
index c779a57f7c5176c85161137b5dffb50b15f2aa62..068191a903ab1b2cdc8f51174e432a3167502788 100644 (file)
@@ -503,6 +503,8 @@ ir3_nir_scan_driver_consts(nir_shader *shader,
 
                                switch (intr->intrinsic) {
                                case nir_intrinsic_get_buffer_size:
+                                       if (ir3_bindless_resource(intr->src[0]))
+                                               break;
                                        idx = nir_src_as_uint(intr->src[0]);
                                        if (layout->ssbo_size.mask & (1 << idx))
                                                break;