From 5e5c42ebb5e891833da3522d5493a7fe9c8d32f0 Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Mon, 28 Nov 2022 15:15:09 +0100 Subject: [PATCH] tu: Fix fault with variable-count inline uniform blocks This seems to have been triggered by some recent CTS changes which changed the random number generation. I'm seeing context faults in dEQP-VK.binding_model.descriptorset_random.sets4.dynindexed.ubolimitlow.sbolimitlow.sampledimghigh.lowimgnotex.iublimitlow.nouab.comp.noia.0 that are fixed by this. Fixes: 37cde2c6348 ("tu: Rewrite inline uniform implementation") Part-of: --- src/freedreno/vulkan/tu_cmd_buffer.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c index 0f062185747..bfddb9bdde9 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.c +++ b/src/freedreno/vulkan/tu_cmd_buffer.c @@ -4493,13 +4493,25 @@ tu6_emit_user_consts(struct tu_cs *cs, */ for (unsigned i = 0; i < link->tu_const_state.num_inline_ubos; i++) { const struct tu_inline_ubo *ubo = &link->tu_const_state.ubos[i]; - tu_cs_emit_pkt7(cs, tu6_stage2opcode(type), 3); - tu_cs_emit(cs, CP_LOAD_STATE6_0_DST_OFF(ubo->const_offset_vec4) | - CP_LOAD_STATE6_0_STATE_TYPE(ST6_CONSTANTS) | - CP_LOAD_STATE6_0_STATE_SRC(SS6_INDIRECT) | - CP_LOAD_STATE6_0_STATE_BLOCK(tu6_stage2shadersb(type)) | - CP_LOAD_STATE6_0_NUM_UNIT(ubo->size_vec4)); - tu_cs_emit_qw(cs, descriptors->sets[ubo->base]->va + ubo->offset); + + /* With variable-count inline uniform blocks, we allocate constant space + * based on the maximum size specified in the descriptor set layout, but + * the actual size may be smaller. In that case we have to avoid + * fetching out-of-bounds of the buffer that contains the descriptor + * set to avoid faults. + */ + unsigned num_units = MIN2(ubo->size_vec4, + (descriptors->sets[ubo->base]->size - ubo->offset) / 16); + + if (num_units > 0) { + tu_cs_emit_pkt7(cs, tu6_stage2opcode(type), 3); + tu_cs_emit(cs, CP_LOAD_STATE6_0_DST_OFF(ubo->const_offset_vec4) | + CP_LOAD_STATE6_0_STATE_TYPE(ST6_CONSTANTS) | + CP_LOAD_STATE6_0_STATE_SRC(SS6_INDIRECT) | + CP_LOAD_STATE6_0_STATE_BLOCK(tu6_stage2shadersb(type)) | + CP_LOAD_STATE6_0_NUM_UNIT(num_units)); + tu_cs_emit_qw(cs, descriptors->sets[ubo->base]->va + ubo->offset); + } } }