microsoft/compiler: Pass an alignment to constant buffer load lowering
This means we can stop doing conditionals and shifts if we know the alignment of a load for a small amount of data. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21029>
This commit is contained in:
@@ -552,7 +552,7 @@ lower_instr(nir_intrinsic_instr *instr, nir_builder *b,
|
||||
nir_ssa_def *load =
|
||||
nir_load_ubo(b, instr->num_components, instr->dest.ssa.bit_size,
|
||||
ubo_idx, ubo_offset,
|
||||
.align_mul = instr->dest.ssa.bit_size / 8,
|
||||
.align_mul = 16,
|
||||
.align_offset = 0,
|
||||
.range_base = 0,
|
||||
.range = ~0,
|
||||
@@ -706,7 +706,8 @@ lower_load_ubo_packed_impl(nir_builder *b, nir_instr *instr,
|
||||
build_load_ubo_dxil(b, buffer,
|
||||
offset,
|
||||
nir_dest_num_components(intr->dest),
|
||||
nir_dest_bit_size(intr->dest));
|
||||
nir_dest_bit_size(intr->dest),
|
||||
nir_intrinsic_align(intr));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,8 @@ lower_load_base_global_invocation_id(nir_builder *b, nir_intrinsic_instr *intr,
|
||||
offsetof(struct clc_work_properties_data,
|
||||
global_offset_x)),
|
||||
nir_dest_num_components(intr->dest),
|
||||
nir_dest_bit_size(intr->dest));
|
||||
nir_dest_bit_size(intr->dest),
|
||||
sizeof(uint32_t) * 4);
|
||||
nir_ssa_def_rewrite_uses(&intr->dest.ssa, offset);
|
||||
nir_instr_remove(&intr->instr);
|
||||
return true;
|
||||
@@ -61,7 +62,8 @@ lower_load_work_dim(nir_builder *b, nir_intrinsic_instr *intr,
|
||||
offsetof(struct clc_work_properties_data,
|
||||
work_dim)),
|
||||
nir_dest_num_components(intr->dest),
|
||||
nir_dest_bit_size(intr->dest));
|
||||
nir_dest_bit_size(intr->dest),
|
||||
sizeof(uint32_t));
|
||||
nir_ssa_def_rewrite_uses(&intr->dest.ssa, dim);
|
||||
nir_instr_remove(&intr->instr);
|
||||
return true;
|
||||
@@ -79,7 +81,8 @@ lower_load_num_workgroups(nir_builder *b, nir_intrinsic_instr *intr,
|
||||
offsetof(struct clc_work_properties_data,
|
||||
group_count_total_x)),
|
||||
nir_dest_num_components(intr->dest),
|
||||
nir_dest_bit_size(intr->dest));
|
||||
nir_dest_bit_size(intr->dest),
|
||||
sizeof(uint32_t) * 4);
|
||||
nir_ssa_def_rewrite_uses(&intr->dest.ssa, count);
|
||||
nir_instr_remove(&intr->instr);
|
||||
return true;
|
||||
@@ -97,7 +100,8 @@ lower_load_base_workgroup_id(nir_builder *b, nir_intrinsic_instr *intr,
|
||||
offsetof(struct clc_work_properties_data,
|
||||
group_id_offset_x)),
|
||||
nir_dest_num_components(intr->dest),
|
||||
nir_dest_bit_size(intr->dest));
|
||||
nir_dest_bit_size(intr->dest),
|
||||
sizeof(uint32_t) * 4);
|
||||
nir_ssa_def_rewrite_uses(&intr->dest.ssa, offset);
|
||||
nir_instr_remove(&intr->instr);
|
||||
return true;
|
||||
|
||||
@@ -132,15 +132,14 @@ lower_load_deref(nir_builder *b, nir_intrinsic_instr *intr)
|
||||
|
||||
static nir_ssa_def *
|
||||
ubo_load_select_32b_comps(nir_builder *b, nir_ssa_def *vec32,
|
||||
nir_ssa_def *offset, unsigned num_bytes)
|
||||
nir_ssa_def *offset, unsigned alignment)
|
||||
{
|
||||
assert(num_bytes == 16 || num_bytes == 12 || num_bytes == 8 ||
|
||||
num_bytes == 4 || num_bytes == 3 || num_bytes == 2 ||
|
||||
num_bytes == 1);
|
||||
assert(alignment >= 16 || alignment == 8 ||
|
||||
alignment == 4 || alignment == 2 ||
|
||||
alignment == 1);
|
||||
assert(vec32->num_components == 4);
|
||||
|
||||
/* 16 and 12 byte types are always aligned on 16 bytes. */
|
||||
if (num_bytes > 8)
|
||||
if (alignment > 8)
|
||||
return vec32;
|
||||
|
||||
nir_ssa_def *comps[4];
|
||||
@@ -149,7 +148,7 @@ ubo_load_select_32b_comps(nir_builder *b, nir_ssa_def *vec32,
|
||||
for (unsigned i = 0; i < 4; i++)
|
||||
comps[i] = nir_channel(b, vec32, i);
|
||||
|
||||
/* If we have 8bytes or less to load, select which half the vec4 should
|
||||
/* If we have 8bytes alignment or less, select which half the vec4 should
|
||||
* be used.
|
||||
*/
|
||||
cond = nir_ine(b, nir_iand(b, offset, nir_imm_int(b, 0x8)),
|
||||
@@ -158,13 +157,11 @@ ubo_load_select_32b_comps(nir_builder *b, nir_ssa_def *vec32,
|
||||
comps[0] = nir_bcsel(b, cond, comps[2], comps[0]);
|
||||
comps[1] = nir_bcsel(b, cond, comps[3], comps[1]);
|
||||
|
||||
/* Thanks to the CL alignment constraints, if we want 8 bytes we're done. */
|
||||
if (num_bytes == 8)
|
||||
if (alignment == 8)
|
||||
return nir_vec(b, comps, 2);
|
||||
|
||||
/* 4 bytes or less needed, select which of the 32bit component should be
|
||||
* used and return it. The sub-32bit split is handled in
|
||||
* extract_comps_from_vec32().
|
||||
/* 4 byte align or less needed, select which of the 32bit component should be
|
||||
* used and return it. The sub-32bit split is handled in nir_extract_bits().
|
||||
*/
|
||||
cond = nir_ine(b, nir_iand(b, offset, nir_imm_int(b, 0x4)),
|
||||
nir_imm_int(b, 0));
|
||||
@@ -174,7 +171,7 @@ ubo_load_select_32b_comps(nir_builder *b, nir_ssa_def *vec32,
|
||||
nir_ssa_def *
|
||||
build_load_ubo_dxil(nir_builder *b, nir_ssa_def *buffer,
|
||||
nir_ssa_def *offset, unsigned num_components,
|
||||
unsigned bit_size)
|
||||
unsigned bit_size, unsigned alignment)
|
||||
{
|
||||
nir_ssa_def *idx = nir_ushr(b, offset, nir_imm_int(b, 4));
|
||||
nir_ssa_def *comps[NIR_MAX_VEC_COMPONENTS];
|
||||
@@ -193,12 +190,13 @@ build_load_ubo_dxil(nir_builder *b, nir_ssa_def *buffer,
|
||||
nir_load_ubo_dxil(b, 4, 32, buffer, nir_iadd(b, idx, nir_imm_int(b, i / (16 * 8))));
|
||||
|
||||
/* First re-arrange the vec32 to account for intra 16-byte offset. */
|
||||
vec32 = ubo_load_select_32b_comps(b, vec32, offset, subload_num_bits / 8);
|
||||
assert(subload_num_bits / 8 <= alignment);
|
||||
vec32 = ubo_load_select_32b_comps(b, vec32, offset, alignment);
|
||||
|
||||
/* If we have 2 bytes or less to load we need to adjust the u32 value so
|
||||
* we can always extract the LSB.
|
||||
*/
|
||||
if (subload_num_bits <= 16) {
|
||||
if (alignment <= 2) {
|
||||
nir_ssa_def *shift = nir_imul(b, nir_iand(b, offset,
|
||||
nir_imm_int(b, 3)),
|
||||
nir_imm_int(b, 8));
|
||||
@@ -680,7 +678,8 @@ lower_load_ubo(nir_builder *b, nir_intrinsic_instr *intr)
|
||||
nir_ssa_def *result =
|
||||
build_load_ubo_dxil(b, intr->src[0].ssa, intr->src[1].ssa,
|
||||
nir_dest_num_components(intr->dest),
|
||||
nir_dest_bit_size(intr->dest));
|
||||
nir_dest_bit_size(intr->dest),
|
||||
nir_intrinsic_align(intr));
|
||||
|
||||
nir_ssa_def_rewrite_uses(&intr->dest.ssa, result);
|
||||
nir_instr_remove(&intr->instr);
|
||||
|
||||
@@ -55,7 +55,7 @@ bool dxil_nir_lower_vs_vertex_conversion(nir_shader *s, enum pipe_format target_
|
||||
nir_ssa_def *
|
||||
build_load_ubo_dxil(nir_builder *b, nir_ssa_def *buffer,
|
||||
nir_ssa_def *offset, unsigned num_components,
|
||||
unsigned bit_size);
|
||||
unsigned bit_size, unsigned alignment);
|
||||
|
||||
uint64_t
|
||||
dxil_sort_by_driver_location(nir_shader* s, nir_variable_mode modes);
|
||||
|
||||
@@ -212,10 +212,15 @@ lower_shader_system_values(struct nir_builder *builder, nir_instr *instr,
|
||||
nir_address_format_bit_size(ubo_format),
|
||||
index, .desc_type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
|
||||
unsigned num_components = nir_dest_num_components(intrin->dest);
|
||||
unsigned alignment = (num_components == 3 ? 4 : num_components) *
|
||||
nir_dest_bit_size(intrin->dest) / 8;
|
||||
assert(offset % alignment == 0);
|
||||
nir_ssa_def *load_data = build_load_ubo_dxil(
|
||||
builder, nir_channel(builder, load_desc, 0),
|
||||
nir_imm_int(builder, offset),
|
||||
nir_dest_num_components(intrin->dest), nir_dest_bit_size(intrin->dest));
|
||||
num_components, nir_dest_bit_size(intrin->dest),
|
||||
alignment);
|
||||
|
||||
nir_ssa_def_rewrite_uses(&intrin->dest.ssa, load_data);
|
||||
nir_instr_remove(instr);
|
||||
@@ -298,7 +303,8 @@ lower_load_push_constant(struct nir_builder *builder, nir_instr *instr,
|
||||
nir_ssa_def *load_data = build_load_ubo_dxil(
|
||||
builder, nir_channel(builder, load_desc, 0),
|
||||
nir_iadd_imm(builder, offset, base),
|
||||
nir_dest_num_components(intrin->dest), nir_dest_bit_size(intrin->dest));
|
||||
nir_dest_num_components(intrin->dest), nir_dest_bit_size(intrin->dest),
|
||||
nir_intrinsic_align(intrin));
|
||||
|
||||
nir_ssa_def_rewrite_uses(&intrin->dest.ssa, load_data);
|
||||
nir_instr_remove(instr);
|
||||
@@ -387,7 +393,7 @@ lower_yz_flip(struct nir_builder *builder, nir_instr *instr,
|
||||
dyn_yz_flip_mask =
|
||||
build_load_ubo_dxil(builder,
|
||||
nir_channel(builder, load_desc, 0),
|
||||
nir_imm_int(builder, offset), 1, 32);
|
||||
nir_imm_int(builder, offset), 1, 32, 4);
|
||||
*data->reads_sysval_ubo = true;
|
||||
}
|
||||
|
||||
@@ -684,7 +690,7 @@ write_pntc_with_pos(nir_builder *b, nir_instr *instr, void *_data)
|
||||
nir_ssa_def *transform = nir_channels(b,
|
||||
build_load_ubo_dxil(b,
|
||||
nir_channel(b, load_desc, 0),
|
||||
nir_imm_int(b, offset), 4, 32),
|
||||
nir_imm_int(b, offset), 4, 32, 16),
|
||||
0x6);
|
||||
nir_ssa_def *point_center_in_clip = nir_fmul(b, nir_channels(b, pos, 0x3), nir_frcp(b, nir_channel(b, pos, 3)));
|
||||
nir_ssa_def *point_center =
|
||||
|
||||
Reference in New Issue
Block a user