nir/gl_nir_lower_buffers: Set up align_mul/offset on UBOs.
nir_lower_to_explicit_io will give us good alignments if we have the cast's alignment information known, and it's trivial: Just the offset of the UBO variable that is at the base of the deref. Otherwise, explicit io assumes the load is aligned just to the size of a scalar value in it. The change in freedreno is in the noise. Reviewed-by: Rob Clark <robdclark@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6612>
This commit is contained in:
@@ -182,6 +182,7 @@ lower_buffer_interface_derefs_impl(nir_function_impl *impl,
|
|||||||
|
|
||||||
b.cursor = nir_before_instr(&deref->instr);
|
b.cursor = nir_before_instr(&deref->instr);
|
||||||
|
|
||||||
|
unsigned offset = 0;
|
||||||
nir_ssa_def *ptr;
|
nir_ssa_def *ptr;
|
||||||
if (deref->deref_type == nir_deref_type_var &&
|
if (deref->deref_type == nir_deref_type_var &&
|
||||||
!glsl_type_is_interface(glsl_without_array(deref->var->type))) {
|
!glsl_type_is_interface(glsl_without_array(deref->var->type))) {
|
||||||
@@ -189,7 +190,7 @@ lower_buffer_interface_derefs_impl(nir_function_impl *impl,
|
|||||||
* containing one. We need the block index and its offset
|
* containing one. We need the block index and its offset
|
||||||
* inside that block
|
* inside that block
|
||||||
*/
|
*/
|
||||||
unsigned index, offset;
|
unsigned index;
|
||||||
get_block_index_offset(deref->var, shader_program,
|
get_block_index_offset(deref->var, shader_program,
|
||||||
b.shader->info.stage,
|
b.shader->info.stage,
|
||||||
&index, &offset);
|
&index, &offset);
|
||||||
@@ -201,7 +202,7 @@ lower_buffer_interface_derefs_impl(nir_function_impl *impl,
|
|||||||
*/
|
*/
|
||||||
nir_ssa_def *index = get_block_array_index(&b, deref,
|
nir_ssa_def *index = get_block_array_index(&b, deref,
|
||||||
shader_program);
|
shader_program);
|
||||||
ptr = nir_vec2(&b, index, nir_imm_int(&b, 0));
|
ptr = nir_vec2(&b, index, nir_imm_int(&b, offset));
|
||||||
} else {
|
} else {
|
||||||
/* This will get handled by nir_lower_explicit_io(). */
|
/* This will get handled by nir_lower_explicit_io(). */
|
||||||
break;
|
break;
|
||||||
@@ -209,6 +210,14 @@ lower_buffer_interface_derefs_impl(nir_function_impl *impl,
|
|||||||
|
|
||||||
nir_deref_instr *cast = nir_build_deref_cast(&b, ptr, deref->mode,
|
nir_deref_instr *cast = nir_build_deref_cast(&b, ptr, deref->mode,
|
||||||
deref->type, 0);
|
deref->type, 0);
|
||||||
|
/* Set the alignment on the cast so that we get good alignment out
|
||||||
|
* of nir_lower_explicit_io. Our offset to the start of the UBO
|
||||||
|
* variable is always a constant, so we can use the maximum
|
||||||
|
* align_mul.
|
||||||
|
*/
|
||||||
|
cast->cast.align_mul = NIR_ALIGN_MUL_MAX;
|
||||||
|
cast->cast.align_offset = offset % NIR_ALIGN_MUL_MAX;
|
||||||
|
|
||||||
nir_ssa_def_rewrite_uses(&deref->dest.ssa,
|
nir_ssa_def_rewrite_uses(&deref->dest.ssa,
|
||||||
nir_src_for_ssa(&cast->dest.ssa));
|
nir_src_for_ssa(&cast->dest.ssa));
|
||||||
nir_deref_instr_remove_if_unused(deref);
|
nir_deref_instr_remove_if_unused(deref);
|
||||||
|
Reference in New Issue
Block a user