broadcom/vc4: Allow binding non-zero constant buffers.
authorEric Anholt <eric@anholt.net>
Wed, 7 Feb 2018 15:22:19 +0000 (15:22 +0000)
committerEric Anholt <eric@anholt.net>
Fri, 9 Mar 2018 17:59:54 +0000 (09:59 -0800)
We're going to use UBO loads for implementing YUV linear-to-T-format
blits.

src/gallium/drivers/vc4/vc4_context.h
src/gallium/drivers/vc4/vc4_program.c
src/gallium/drivers/vc4/vc4_qir.h
src/gallium/drivers/vc4/vc4_state.c
src/gallium/drivers/vc4/vc4_uniforms.c

index e0317a0e0c0dc1e3d0a0300c60c243b51d67f7c9..d92fcba42c65a59db960a3bf311c2805815ae334 100644 (file)
@@ -78,6 +78,7 @@
 #define VC4_DIRTY_COMPILED_VS   (1 << 24)
 #define VC4_DIRTY_COMPILED_FS   (1 << 25)
 #define VC4_DIRTY_FS_INPUTS     (1 << 26)
+#define VC4_DIRTY_UBO_1_SIZE    (1 << 27)
 
 struct vc4_sampler_view {
         struct pipe_sampler_view base;
index be80a851d2a88ba9a40f234d622fa82af54166db..2ec6aa471d48d3d424cdbdb14f53718a31592255 100644 (file)
@@ -137,6 +137,32 @@ indirect_uniform_load(struct vc4_compile *c, nir_intrinsic_instr *intr)
         return qir_TEX_RESULT(c);
 }
 
+static struct qreg
+vc4_ubo_load(struct vc4_compile *c, nir_intrinsic_instr *intr)
+{
+        nir_const_value *buffer_index =
+                nir_src_as_const_value(intr->src[0]);
+        assert(buffer_index->u32[0] == 1);
+        assert(c->stage == QSTAGE_FRAG);
+
+        struct qreg offset = ntq_get_src(c, intr->src[1], 0);
+
+        /* Clamp to [0, array size).  Note that MIN/MAX are signed. */
+        offset = qir_MAX(c, offset, qir_uniform_ui(c, 0));
+        offset = qir_MIN_NOIMM(c, offset,
+                               qir_uniform_ui(c, c->fs_key->ubo_1_size - 4));
+
+        qir_ADD_dest(c, qir_reg(QFILE_TEX_S_DIRECT, 0),
+                     offset,
+                     qir_uniform(c, QUNIFORM_UBO_ADDR, buffer_index->u32[0]));
+
+        c->num_texture_samples++;
+
+        ntq_emit_thrsw(c);
+
+        return qir_TEX_RESULT(c);
+}
+
 nir_ssa_def *
 vc4_nir_get_swizzled_channel(nir_builder *b, nir_ssa_def **srcs, int swiz)
 {
@@ -1775,6 +1801,11 @@ ntq_emit_intrinsic(struct vc4_compile *c, nir_intrinsic_instr *instr)
                 }
                 break;
 
+        case nir_intrinsic_load_ubo:
+                assert(instr->num_components == 1);
+                ntq_store_dest(c, &instr->dest, 0, vc4_ubo_load(c, instr));
+                break;
+
         case nir_intrinsic_load_user_clip_plane:
                 for (int i = 0; i < instr->num_components; i++) {
                         ntq_store_dest(c, &instr->dest, i,
@@ -2726,7 +2757,8 @@ vc4_update_compiled_fs(struct vc4_context *vc4, uint8_t prim_mode)
                             VC4_DIRTY_RASTERIZER |
                             VC4_DIRTY_SAMPLE_MASK |
                             VC4_DIRTY_FRAGTEX |
-                            VC4_DIRTY_UNCOMPILED_FS))) {
+                            VC4_DIRTY_UNCOMPILED_FS |
+                            VC4_DIRTY_UBO_1_SIZE))) {
                 return;
         }
 
@@ -2770,6 +2802,7 @@ vc4_update_compiled_fs(struct vc4_context *vc4, uint8_t prim_mode)
                          PIPE_SPRITE_COORD_UPPER_LEFT);
         }
 
+        key->ubo_1_size = vc4->constbuf[PIPE_SHADER_FRAGMENT].cb[1].buffer_size;
         key->light_twoside = vc4->rasterizer->base.light_twoside;
 
         struct vc4_compiled_shader *old_fs = vc4->prog.fs;
index 90acaef2898913c94d02cb91fbd02c6460ec4aa0..3afa98a66af1b4e735a1c9295835f76b00e6196f 100644 (file)
@@ -363,6 +363,7 @@ struct vc4_fs_key {
         uint8_t alpha_test_func;
         uint8_t logicop_func;
         uint32_t point_sprite_mask;
+        uint32_t ubo_1_size;
 
         struct pipe_rt_blend_state blend;
 };
index c85618789a6dee7ba5f9ae6509de15a445a9fdae..f8c378184998d42ef05d7f0acae82a410113a12b 100644 (file)
@@ -386,8 +386,6 @@ vc4_set_constant_buffer(struct pipe_context *pctx,
         struct vc4_context *vc4 = vc4_context(pctx);
         struct vc4_constbuf_stateobj *so = &vc4->constbuf[shader];
 
-        assert(index == 0);
-
         /* Note that the state tracker can unbind constant buffers by
          * passing NULL here.
          */
@@ -397,7 +395,10 @@ vc4_set_constant_buffer(struct pipe_context *pctx,
                 return;
         }
 
-        assert(!cb->buffer);
+        if (index == 1 && so->cb[index].buffer_size != cb->buffer_size)
+                vc4->dirty |= VC4_DIRTY_UBO_1_SIZE;
+
+        pipe_resource_reference(&so->cb[index].buffer, cb->buffer);
         so->cb[index].buffer_offset = cb->buffer_offset;
         so->cb[index].buffer_size   = cb->buffer_size;
         so->cb[index].user_buffer   = cb->user_buffer;
index 12e6504bba0a7cff6c3145c0e4ca38874ac2cc40..8a435173b7e81e75a9be0b5fef702cadffe61782 100644 (file)
@@ -273,7 +273,19 @@ vc4_write_uniforms(struct vc4_context *vc4, struct vc4_compiled_shader *shader,
                         break;
 
                 case QUNIFORM_UBO_ADDR:
-                        cl_aligned_reloc(job, &job->uniforms, &uniforms, ubo, 0);
+                        if (uinfo->data[i] == 0) {
+                                cl_aligned_reloc(job, &job->uniforms,
+                                                 &uniforms, ubo, 0);
+                        } else {
+                                struct pipe_constant_buffer *c =
+                                        &cb->cb[uinfo->data[i]];
+                                struct vc4_resource *rsc =
+                                        vc4_resource(c->buffer);
+
+                                cl_aligned_reloc(job, &job->uniforms,
+                                                 &uniforms,
+                                                 rsc->bo, c->buffer_offset);
+                        }
                         break;
 
                 case QUNIFORM_TEXTURE_MSAA_ADDR: