mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 08:50:13 +01:00
zink: split xfb block emission from array/matrix handling
these are not necessarily the same case even if in glsl they are the same, and by splitting it out a bunch of redundant array[scalar] code can be deleted Reviewed-by: Dave Airlie <airlied@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17404>
This commit is contained in:
parent
76cc519866
commit
042cc6e6e6
1 changed files with 55 additions and 78 deletions
|
|
@ -1493,12 +1493,12 @@ emit_so_outputs(struct ntv_context *ctx,
|
|||
/* this is the array index into matrix types */
|
||||
unsigned matrix_offset = glsl_type_is_matrix(bare_type) ? 0 : so_output.register_index;
|
||||
do {
|
||||
uint32_t base_slot = (location & ~so_output.start_component) / 4;
|
||||
/* this is the slot index into the "current" value */
|
||||
unsigned slot_idx = slot - base_slot;
|
||||
unsigned struct_slots = glsl_count_vec4_slots(bare_type, false, false);
|
||||
unsigned array_idx = slot_idx / struct_slots;
|
||||
if (glsl_type_is_struct_or_ifc(bare_type)) {
|
||||
uint32_t base_slot = (location & ~so_output.start_component) / 4;
|
||||
/* this is the slot index into the "current" value */
|
||||
unsigned slot_idx = slot - base_slot;
|
||||
unsigned struct_slots = glsl_count_vec4_slots(bare_type, false, false);
|
||||
unsigned array_idx = slot_idx / struct_slots;
|
||||
bool first = true;
|
||||
slot_idx %= glsl_count_vec4_slots(bare_type, false, false);
|
||||
if (glsl_type_is_array(out_type))
|
||||
|
|
@ -1520,80 +1520,57 @@ emit_so_outputs(struct ntv_context *ctx,
|
|||
bare_type = unroll_struct_type(ctx, bare_type, &slot_idx, &src, &out_type);
|
||||
first = false;
|
||||
}
|
||||
/* update to the matrix row index */
|
||||
matrix_offset = slot_idx;
|
||||
output_type = get_glsl_type(ctx, out_type);
|
||||
if (glsl_type_is_vector_or_scalar(out_type)) {
|
||||
/* this is a simple case: handle below */
|
||||
if (glsl_get_vector_elements(out_type) * glsl_get_bit_size(out_type) == so_output.num_components * 32) {
|
||||
src = emit_bitcast(ctx, type, src);
|
||||
out_type = glsl_vector_type(GLSL_TYPE_UINT, so_output.num_components);
|
||||
output_type = get_glsl_type(ctx, out_type);
|
||||
}
|
||||
} else if (glsl_type_is_array(out_type)) {
|
||||
/* this should be impossible */
|
||||
if (glsl_type_is_struct(bare_type))
|
||||
unreachable("zink: gross nested struct array struct arrays in xfb!");
|
||||
SpvId base_type = get_glsl_basetype(ctx, glsl_get_base_type(bare_type));
|
||||
if (glsl_type_is_scalar(bare_type)) {
|
||||
/* this wouldn't make sense */
|
||||
assert(so_output.start_component == 0);
|
||||
|
||||
if (glsl_type_is_64bit(bare_type)) {
|
||||
/* 64bit components count as 2 so outputs: bitcast to vec2 and extract */
|
||||
unsigned idx = 0;
|
||||
for (unsigned c = 0; idx < so_output.num_components; c++) {
|
||||
uint32_t member = slot_idx + c;
|
||||
SpvId conv = spirv_builder_emit_composite_extract(&ctx->builder, base_type, src, &member, 1);
|
||||
SpvId val = emit_bitcast(ctx, get_uvec_type(ctx, 32, 2), conv);
|
||||
unsigned v = 0;
|
||||
components[idx++] = spirv_builder_emit_composite_extract(&ctx->builder, get_uvec_type(ctx, 32, 1), val, &v, 1);
|
||||
v = 1;
|
||||
components[idx++] = spirv_builder_emit_composite_extract(&ctx->builder, get_uvec_type(ctx, 32, 1), val, &v, 1);
|
||||
}
|
||||
result = spirv_builder_emit_composite_construct(&ctx->builder, type, components, so_output.num_components);
|
||||
} else {
|
||||
/* array of scalars: each one is its own slot */
|
||||
for (unsigned c = 0; c < so_output.num_components; c++) {
|
||||
uint32_t member = slot_idx + c;
|
||||
components[c] = spirv_builder_emit_composite_extract(&ctx->builder, base_type, src, &member, 1);
|
||||
}
|
||||
}
|
||||
} else if (glsl_type_is_matrix(bare_type)) {
|
||||
/* nested matrix type: unwrap, update matrix offset, select a vec, handle below */
|
||||
unsigned mat_slots = glsl_count_attribute_slots(bare_type, false);
|
||||
array_idx = matrix_offset / mat_slots;
|
||||
output_type = get_glsl_type(ctx, bare_type);
|
||||
out_type = bare_type;
|
||||
src = spirv_builder_emit_composite_extract(&ctx->builder, output_type, src, &array_idx, 1);
|
||||
matrix_offset %= mat_slots;
|
||||
unsigned real_offset = glsl_type_is_64bit(bare_type) ? matrix_offset / 2 : matrix_offset;
|
||||
/* store for later */
|
||||
if (glsl_type_is_64bit(bare_type))
|
||||
matrix_offset %= 2;
|
||||
assert(real_offset < glsl_get_matrix_columns(bare_type));
|
||||
out_type = glsl_without_array_or_matrix(out_type);
|
||||
output_type = get_glsl_type(ctx, out_type);
|
||||
src = spirv_builder_emit_composite_extract(&ctx->builder, output_type, src, &real_offset, 1);
|
||||
break;
|
||||
} else {
|
||||
assert(glsl_type_is_vector(bare_type));
|
||||
/* just extract the right vec and let it be handled below */
|
||||
unsigned vec_slots = glsl_count_attribute_slots(bare_type, false);
|
||||
unsigned idx = matrix_offset / vec_slots;
|
||||
matrix_offset %= vec_slots;
|
||||
output_type = get_glsl_type(ctx, bare_type);
|
||||
out_type = bare_type;
|
||||
src = spirv_builder_emit_composite_extract(&ctx->builder, output_type, src, &idx, 1);
|
||||
break;
|
||||
}
|
||||
if (so_output.num_components > 1)
|
||||
src = spirv_builder_emit_composite_construct(&ctx->builder, type, components, so_output.num_components);
|
||||
else
|
||||
src = components[0];
|
||||
out_type = glsl_vector_type(GLSL_TYPE_UINT, so_output.num_components);
|
||||
output_type = type;
|
||||
}
|
||||
/* update to the matrix row index */
|
||||
matrix_offset = slot_idx;
|
||||
output_type = get_glsl_type(ctx, out_type);
|
||||
if (glsl_type_is_vector_or_scalar(out_type)) {
|
||||
/* this is a simple case: handle below */
|
||||
if (glsl_get_vector_elements(out_type) * glsl_get_bit_size(out_type) == so_output.num_components * 32) {
|
||||
src = emit_bitcast(ctx, type, src);
|
||||
out_type = glsl_vector_type(GLSL_TYPE_UINT, so_output.num_components);
|
||||
output_type = get_glsl_type(ctx, out_type);
|
||||
}
|
||||
} else if (glsl_type_is_array(out_type)) {
|
||||
/* this should be impossible */
|
||||
if (glsl_type_is_struct(bare_type))
|
||||
unreachable("zink: gross nested struct array struct arrays in xfb!");
|
||||
if (glsl_type_is_matrix(bare_type)) {
|
||||
/* nested matrix type: unwrap, update matrix offset, select a vec, handle below */
|
||||
unsigned mat_slots = glsl_count_attribute_slots(bare_type, false);
|
||||
array_idx = matrix_offset / mat_slots;
|
||||
output_type = get_glsl_type(ctx, bare_type);
|
||||
out_type = bare_type;
|
||||
src = spirv_builder_emit_composite_extract(&ctx->builder, output_type, src, &array_idx, 1);
|
||||
matrix_offset %= mat_slots;
|
||||
unsigned real_offset = glsl_type_is_64bit(bare_type) ? matrix_offset / 2 : matrix_offset;
|
||||
/* store for later */
|
||||
if (glsl_type_is_64bit(bare_type))
|
||||
matrix_offset %= 2;
|
||||
assert(real_offset < glsl_get_matrix_columns(bare_type));
|
||||
out_type = glsl_without_array_or_matrix(out_type);
|
||||
output_type = get_glsl_type(ctx, out_type);
|
||||
src = spirv_builder_emit_composite_extract(&ctx->builder, output_type, src, &real_offset, 1);
|
||||
break;
|
||||
} else if (glsl_type_is_vector(bare_type)) {
|
||||
/* just extract the right vec and let it be handled below */
|
||||
unsigned vec_slots = glsl_count_attribute_slots(bare_type, false);
|
||||
unsigned idx = matrix_offset / vec_slots;
|
||||
matrix_offset %= vec_slots;
|
||||
output_type = get_glsl_type(ctx, bare_type);
|
||||
out_type = bare_type;
|
||||
src = spirv_builder_emit_composite_extract(&ctx->builder, output_type, src, &idx, 1);
|
||||
break;
|
||||
} else {
|
||||
assert(glsl_type_is_scalar(bare_type));
|
||||
break;
|
||||
}
|
||||
if (so_output.num_components > 1)
|
||||
src = spirv_builder_emit_composite_construct(&ctx->builder, type, components, so_output.num_components);
|
||||
else
|
||||
src = components[0];
|
||||
out_type = glsl_vector_type(GLSL_TYPE_UINT, so_output.num_components);
|
||||
output_type = type;
|
||||
}
|
||||
} while (0);
|
||||
assert(!glsl_type_is_struct_or_ifc(out_type));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue