From: Eric Anholt Date: Wed, 7 Feb 2018 15:22:19 +0000 (+0000) Subject: broadcom/vc4: Allow binding non-zero constant buffers. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=46a32e3d2e84bd4dfff9e76f0f1f21613e1bc5a9;p=mesa.git broadcom/vc4: Allow binding non-zero constant buffers. We're going to use UBO loads for implementing YUV linear-to-T-format blits. --- diff --git a/src/gallium/drivers/vc4/vc4_context.h b/src/gallium/drivers/vc4/vc4_context.h index e0317a0e0c0..d92fcba42c6 100644 --- a/src/gallium/drivers/vc4/vc4_context.h +++ b/src/gallium/drivers/vc4/vc4_context.h @@ -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; diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c index be80a851d2a..2ec6aa471d4 100644 --- a/src/gallium/drivers/vc4/vc4_program.c +++ b/src/gallium/drivers/vc4/vc4_program.c @@ -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; diff --git a/src/gallium/drivers/vc4/vc4_qir.h b/src/gallium/drivers/vc4/vc4_qir.h index 90acaef2898..3afa98a66af 100644 --- a/src/gallium/drivers/vc4/vc4_qir.h +++ b/src/gallium/drivers/vc4/vc4_qir.h @@ -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; }; diff --git a/src/gallium/drivers/vc4/vc4_state.c b/src/gallium/drivers/vc4/vc4_state.c index c85618789a6..f8c37818499 100644 --- a/src/gallium/drivers/vc4/vc4_state.c +++ b/src/gallium/drivers/vc4/vc4_state.c @@ -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; diff --git a/src/gallium/drivers/vc4/vc4_uniforms.c b/src/gallium/drivers/vc4/vc4_uniforms.c index 12e6504bba0..8a435173b7e 100644 --- a/src/gallium/drivers/vc4/vc4_uniforms.c +++ b/src/gallium/drivers/vc4/vc4_uniforms.c @@ -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: