mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 21:50:12 +01:00
zink: delete all the extra gross xfb handling
xfb outputs should always be inlined into the base variables now, so there's no need for anything further here Reviewed-by: Dave Airlie <airlied@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24634>
This commit is contained in:
parent
01d3c691a5
commit
1abd507049
5 changed files with 6 additions and 431 deletions
|
|
@ -80,10 +80,7 @@ struct ntv_context {
|
|||
size_t num_defs;
|
||||
|
||||
struct hash_table *vars; /* nir_variable -> SpvId */
|
||||
struct hash_table *so_outputs; /* pipe_stream_output -> SpvId */
|
||||
unsigned outputs[VARYING_SLOT_MAX * 4];
|
||||
const struct glsl_type *so_output_gl_types[VARYING_SLOT_MAX * 4];
|
||||
SpvId so_output_types[VARYING_SLOT_MAX * 4];
|
||||
|
||||
const SpvId *block_ids;
|
||||
size_t num_blocks;
|
||||
|
|
@ -862,8 +859,6 @@ emit_output(struct ntv_context *ctx, struct nir_variable *var)
|
|||
if (ctx->stage != MESA_SHADER_TESS_CTRL && var->data.location >= 0) {
|
||||
unsigned idx = var->data.location << 2 | var->data.location_frac;
|
||||
ctx->outputs[idx] = var_id;
|
||||
ctx->so_output_gl_types[idx] = var->type;
|
||||
ctx->so_output_types[idx] = var_type;
|
||||
}
|
||||
emit_interpolation(ctx, var_id, var->data.interpolation);
|
||||
} else {
|
||||
|
|
@ -1543,396 +1538,6 @@ emit_unop(struct ntv_context *ctx, SpvOp op, SpvId type, SpvId src)
|
|||
return spirv_builder_emit_unop(&ctx->builder, op, type, src);
|
||||
}
|
||||
|
||||
/* return the intended xfb output vec type based on base type and vector size */
|
||||
static SpvId
|
||||
get_output_type(struct ntv_context *ctx, unsigned register_index, unsigned num_components)
|
||||
{
|
||||
const struct glsl_type *out_type = NULL;
|
||||
/* index is based on component, so we might have to go back a few slots to get to the base */
|
||||
while (!out_type)
|
||||
out_type = ctx->so_output_gl_types[register_index--];
|
||||
const struct glsl_type *bare_type = glsl_without_array(out_type);
|
||||
enum glsl_base_type base_type;
|
||||
if (glsl_type_is_struct_or_ifc(bare_type))
|
||||
base_type = GLSL_TYPE_UINT;
|
||||
else
|
||||
base_type = glsl_get_base_type(bare_type);
|
||||
|
||||
|
||||
switch (base_type) {
|
||||
case GLSL_TYPE_BOOL:
|
||||
return get_bvec_type(ctx, num_components);
|
||||
|
||||
case GLSL_TYPE_DOUBLE: //this case is misleading, as so outputs are always 32bit floats
|
||||
case GLSL_TYPE_FLOAT:
|
||||
return get_fvec_type(ctx, 32, num_components);
|
||||
|
||||
case GLSL_TYPE_INT:
|
||||
return get_ivec_type(ctx, 32, num_components);
|
||||
|
||||
case GLSL_TYPE_UINT:
|
||||
return get_uvec_type(ctx, 32, num_components);
|
||||
|
||||
default:
|
||||
unreachable("unknown type");
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static nir_variable *
|
||||
find_propagate_var(nir_shader *nir, unsigned slot)
|
||||
{
|
||||
nir_foreach_shader_out_variable(var, nir) {
|
||||
if (var->data.location == slot && glsl_type_is_array(var->type))
|
||||
return var;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* for streamout create new outputs, as streamout can be done on individual components,
|
||||
from complete outputs, so we just can't use the created packed outputs */
|
||||
static void
|
||||
emit_so_info(struct ntv_context *ctx, const struct zink_shader_info *so_info,
|
||||
unsigned first_so)
|
||||
{
|
||||
unsigned output = 0;
|
||||
for (unsigned i = 0; i < so_info->so_info.num_outputs; i++) {
|
||||
struct pipe_stream_output so_output = so_info->so_info.output[i];
|
||||
unsigned slot = so_info->so_info_slots[i] << 2 | so_output.start_component;
|
||||
SpvId out_type = get_output_type(ctx, slot, so_output.num_components);
|
||||
SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
|
||||
SpvStorageClassOutput,
|
||||
out_type);
|
||||
SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
|
||||
SpvStorageClassOutput);
|
||||
char name[10];
|
||||
|
||||
snprintf(name, 10, "xfb%d", output);
|
||||
spirv_builder_emit_name(&ctx->builder, var_id, name);
|
||||
spirv_builder_emit_offset(&ctx->builder, var_id, (so_output.dst_offset * 4));
|
||||
spirv_builder_emit_xfb_buffer(&ctx->builder, var_id, so_output.output_buffer);
|
||||
spirv_builder_emit_xfb_stride(&ctx->builder, var_id, so_info->so_info.stride[so_output.output_buffer] * 4);
|
||||
if (so_output.stream)
|
||||
spirv_builder_emit_stream(&ctx->builder, var_id, so_output.stream);
|
||||
|
||||
/* output location is incremented by VARYING_SLOT_VAR0 for non-builtins in vtn,
|
||||
* so we need to ensure that the new xfb location slot doesn't conflict with any previously-emitted
|
||||
* outputs.
|
||||
*/
|
||||
uint32_t location = first_so + i;
|
||||
assert(location < VARYING_SLOT_VAR0);
|
||||
spirv_builder_emit_location(&ctx->builder, var_id, location);
|
||||
|
||||
/* note: gl_ClipDistance[4] can the 0-indexed member of VARYING_SLOT_CLIP_DIST1 here,
|
||||
* so this is still the 0 component
|
||||
*/
|
||||
if (so_output.start_component)
|
||||
spirv_builder_emit_component(&ctx->builder, var_id, so_output.start_component);
|
||||
|
||||
uint32_t *key = ralloc_size(ctx->mem_ctx, sizeof(uint32_t));
|
||||
*key = (uint32_t)so_output.register_index << 2 | so_output.start_component;
|
||||
_mesa_hash_table_insert(ctx->so_outputs, key, (void *)(intptr_t)var_id);
|
||||
|
||||
assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
|
||||
ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
|
||||
output += align(so_output.num_components, 4) / 4;
|
||||
}
|
||||
|
||||
/* these are interface block arrays which need to be split
|
||||
* across N buffers due to GL spec requirements
|
||||
*/
|
||||
u_foreach_bit(bit, so_info->so_propagate) {
|
||||
unsigned slot = bit + VARYING_SLOT_VAR0;
|
||||
nir_variable *var = find_propagate_var(ctx->nir, slot);
|
||||
assert(var);
|
||||
const struct glsl_type *bare_type = glsl_without_array(var->type);
|
||||
SpvId base_type = get_glsl_type(ctx, bare_type);
|
||||
for (unsigned i = 0; i < glsl_array_size(var->type); i++) {
|
||||
SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
|
||||
SpvStorageClassOutput,
|
||||
base_type);
|
||||
SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type,
|
||||
SpvStorageClassOutput);
|
||||
char name[1024];
|
||||
if (var->name)
|
||||
snprintf(name, sizeof(name), "xfb_%s[%d]", var->name, i);
|
||||
else
|
||||
snprintf(name, sizeof(name), "xfb_slot%u[%d]", slot, i);
|
||||
spirv_builder_emit_name(&ctx->builder, var_id, name);
|
||||
spirv_builder_emit_offset(&ctx->builder, var_id, var->data.offset);
|
||||
spirv_builder_emit_xfb_buffer(&ctx->builder, var_id, var->data.xfb.buffer + i);
|
||||
spirv_builder_emit_xfb_stride(&ctx->builder, var_id, var->data.xfb.stride);
|
||||
if (var->data.stream)
|
||||
spirv_builder_emit_stream(&ctx->builder, var_id, var->data.stream);
|
||||
|
||||
uint32_t location = first_so + so_info->so_info.num_outputs + i;
|
||||
assert(location < VARYING_SLOT_VAR0);
|
||||
spirv_builder_emit_location(&ctx->builder, var_id, location);
|
||||
|
||||
uint32_t *key = ralloc_size(ctx->mem_ctx, sizeof(uint32_t));
|
||||
*key = (uint32_t)(slot + i) << 2;
|
||||
_mesa_hash_table_insert(ctx->so_outputs, key, (void *)(intptr_t)var_id);
|
||||
|
||||
assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
|
||||
ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct glsl_type *
|
||||
unroll_struct_type(struct ntv_context *ctx, const struct glsl_type *slot_type, unsigned *slot_idx, SpvId *deref, const struct glsl_type **arraytype)
|
||||
{
|
||||
const struct glsl_type *type = slot_type;
|
||||
unsigned slot_count = 0;
|
||||
unsigned cur_slot = 0;
|
||||
unsigned idx = 0;
|
||||
/* iterate over all the members in the struct, stopping once the slot idx is reached */
|
||||
for (unsigned i = 0; i < glsl_get_length(slot_type) && cur_slot <= *slot_idx; i++, cur_slot += slot_count) {
|
||||
/* use array type for slot counting but return array member type for unroll */
|
||||
*arraytype = glsl_get_struct_field(slot_type, i);
|
||||
type = glsl_without_array(*arraytype);
|
||||
slot_count = glsl_count_vec4_slots(*arraytype, false, false);
|
||||
idx = i;
|
||||
}
|
||||
*deref = spirv_builder_emit_composite_extract(&ctx->builder, get_glsl_type(ctx, glsl_get_struct_field(slot_type, idx)), *deref, &idx, 1);
|
||||
*slot_idx -= (cur_slot - slot_count);
|
||||
return type;
|
||||
}
|
||||
|
||||
static void
|
||||
emit_so_outputs(struct ntv_context *ctx,
|
||||
const struct zink_shader_info *so_info)
|
||||
{
|
||||
for (unsigned i = 0; i < so_info->so_info.num_outputs; i++) {
|
||||
uint32_t components[NIR_MAX_VEC_COMPONENTS];
|
||||
unsigned slot = so_info->so_info_slots[i];
|
||||
struct pipe_stream_output so_output = so_info->so_info.output[i];
|
||||
uint32_t so_key = (uint32_t) so_output.register_index << 2 | so_output.start_component;
|
||||
uint32_t output_location = (uint32_t) slot << 2 | so_output.start_component;
|
||||
uint32_t location = output_location;
|
||||
struct hash_entry *he = _mesa_hash_table_search(ctx->so_outputs, &so_key);
|
||||
assert(he);
|
||||
SpvId so_output_var_id = (SpvId)(intptr_t)he->data;
|
||||
|
||||
SpvId type = get_output_type(ctx, location, so_output.num_components);
|
||||
SpvId output = 0;
|
||||
/* index is based on component, so we might have to go back a few slots to get to the base */
|
||||
UNUSED uint32_t orig_location = location;
|
||||
while (!output)
|
||||
output = ctx->outputs[location--];
|
||||
location++;
|
||||
SpvId output_type = ctx->so_output_types[location];
|
||||
const struct glsl_type *out_type = ctx->so_output_gl_types[location];
|
||||
|
||||
SpvId src = spirv_builder_emit_load(&ctx->builder, output_type, output);
|
||||
|
||||
SpvId result;
|
||||
|
||||
/* this is the type being indexed into */
|
||||
const struct glsl_type *bare_type = glsl_without_array(out_type);
|
||||
/* 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)) {
|
||||
bool first = true;
|
||||
slot_idx %= glsl_count_vec4_slots(bare_type, false, false);
|
||||
if (glsl_type_is_array(out_type))
|
||||
src = spirv_builder_emit_composite_extract(&ctx->builder, get_glsl_type(ctx, bare_type), src, &array_idx, 1);
|
||||
/* need to find the vec4 that's being exported by this slot */
|
||||
while (glsl_type_is_struct_or_ifc(bare_type)) {
|
||||
/* a struct may have nested arrays of structs: handle them inline here */
|
||||
if (!first && glsl_type_is_array(out_type)) {
|
||||
struct_slots = glsl_count_vec4_slots(bare_type, false, false);
|
||||
array_idx = slot_idx / struct_slots;
|
||||
src = spirv_builder_emit_composite_extract(&ctx->builder, get_glsl_type(ctx, bare_type), src, &array_idx, 1);
|
||||
slot_idx -= array_idx * struct_slots;
|
||||
}
|
||||
/* unroll this level of struct:
|
||||
* - slot_idx is incremented to reflect the current value
|
||||
* - unwrap src
|
||||
* - out_type is the array type if src is an array
|
||||
*/
|
||||
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!");
|
||||
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));
|
||||
|
||||
if (!glsl_type_is_64bit(out_type) &&
|
||||
(glsl_type_is_scalar(out_type) ||
|
||||
(type == output_type &&
|
||||
(glsl_type_is_vector(out_type) && glsl_get_vector_elements(out_type) == so_output.num_components))))
|
||||
/* if we're emitting a scalar or the type we're emitting matches the output's original type and we're
|
||||
* emitting the same number of components, then we can skip any sort of conversion here
|
||||
*/
|
||||
result = src;
|
||||
else {
|
||||
/* OpCompositeExtract can only extract scalars for our use here,
|
||||
* but not from arrays since they have different packing rules
|
||||
*/
|
||||
if (so_output.num_components == 1 && !glsl_type_is_array(out_type)) {
|
||||
unsigned component = so_output.start_component;
|
||||
result = spirv_builder_emit_composite_extract(&ctx->builder, type, src, &component, so_output.num_components);
|
||||
} else if (glsl_type_is_vector(out_type)) {
|
||||
if (glsl_type_is_64bit(out_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 = so_output.start_component + (matrix_offset * 2) + c;
|
||||
SpvId base_type = get_glsl_basetype(ctx, glsl_get_base_type(out_type));
|
||||
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, get_uvec_type(ctx, 32, so_output.num_components), components, so_output.num_components);
|
||||
} else {
|
||||
for (unsigned c = 0; c < so_output.num_components; c++) {
|
||||
components[c] = so_output.start_component + c;
|
||||
/* this is the second half of a 2 * vec4 array */
|
||||
if (slot == VARYING_SLOT_CLIP_DIST1 || slot == VARYING_SLOT_CULL_DIST1)
|
||||
components[c] += 4;
|
||||
}
|
||||
/* OpVectorShuffle can select vector members into a differently-sized vector */
|
||||
result = spirv_builder_emit_vector_shuffle(&ctx->builder, type,
|
||||
src, src,
|
||||
components, so_output.num_components);
|
||||
}
|
||||
} else {
|
||||
assert(glsl_type_is_array_or_matrix(out_type));
|
||||
const struct glsl_type *bare_type = glsl_without_array(out_type);
|
||||
assert(!glsl_type_is_struct_or_ifc(bare_type));
|
||||
if (glsl_type_is_matrix(out_type)) {
|
||||
/* for matrices, the xfb output will never be more than one vec4 from a single row */
|
||||
unsigned vec_size = glsl_get_vector_elements(out_type);
|
||||
SpvId vec_type = get_fvec_type(ctx, glsl_get_bit_size(out_type), vec_size);
|
||||
if (glsl_type_is_64bit(out_type) && vec_size > 2) {
|
||||
/* dvec3/dvec4 uses 2 slots per row: normalize matrix offset */
|
||||
matrix_offset /= 2;
|
||||
}
|
||||
src = spirv_builder_emit_composite_extract(&ctx->builder, vec_type, src, &matrix_offset, 1);
|
||||
out_type = glsl_vector_type(glsl_get_base_type(out_type), glsl_get_vector_elements(out_type));
|
||||
}
|
||||
/* for arrays (or matrix rows), we need to manually extract each desired member
|
||||
* and re-pack them into the desired output type
|
||||
*/
|
||||
unsigned idx = 0;
|
||||
for (unsigned c = 0; idx < so_output.num_components; c++) {
|
||||
uint32_t member = so_output.start_component + c;
|
||||
SpvId base_type = get_glsl_basetype(ctx, glsl_get_base_type(bare_type));
|
||||
|
||||
if (slot == VARYING_SLOT_CLIP_DIST1 || slot == VARYING_SLOT_CULL_DIST1)
|
||||
member += 4;
|
||||
components[idx] = spirv_builder_emit_composite_extract(&ctx->builder, base_type, src, &member, 1);
|
||||
if (glsl_type_is_64bit(bare_type)) {
|
||||
/* 64bit components count as 2 so outputs: bitcast to vec2 and extract */
|
||||
SpvId val = emit_bitcast(ctx, get_uvec_type(ctx, 32, 2), components[idx]);
|
||||
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);
|
||||
} else {
|
||||
components[idx] = emit_bitcast(ctx, spirv_builder_type_uint(&ctx->builder, 32), components[idx]);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
if (so_output.num_components > 1)
|
||||
result = spirv_builder_emit_composite_construct(&ctx->builder, get_uvec_type(ctx, 32, so_output.num_components), components, so_output.num_components);
|
||||
else
|
||||
result = components[0];
|
||||
}
|
||||
}
|
||||
|
||||
result = emit_bitcast(ctx, type, result);
|
||||
spirv_builder_emit_store(&ctx->builder, so_output_var_id, result);
|
||||
}
|
||||
|
||||
u_foreach_bit(bit, so_info->so_propagate) {
|
||||
unsigned slot = bit + VARYING_SLOT_VAR0;
|
||||
nir_variable *var = find_propagate_var(ctx->nir, slot);
|
||||
assert(var);
|
||||
|
||||
const struct glsl_type *bare_type = glsl_without_array(var->type);
|
||||
SpvId base_type = get_glsl_type(ctx, bare_type);
|
||||
SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
|
||||
SpvStorageClassOutput,
|
||||
base_type);
|
||||
SpvId output = ctx->outputs[slot << 2];
|
||||
assert(output);
|
||||
for (unsigned i = 0; i < glsl_array_size(var->type); i++) {
|
||||
uint32_t so_key = (uint32_t) (slot + i) << 2;
|
||||
struct hash_entry *he = _mesa_hash_table_search(ctx->so_outputs, &so_key);
|
||||
assert(he);
|
||||
SpvId so_output_var_id = (SpvId)(intptr_t)he->data;
|
||||
|
||||
SpvId idx = emit_uint_const(ctx, 32, i);
|
||||
SpvId deref = spirv_builder_emit_access_chain(&ctx->builder, pointer_type, output, &idx, 1);
|
||||
SpvId load = spirv_builder_emit_load(&ctx->builder, base_type, deref);
|
||||
spirv_builder_emit_store(&ctx->builder, so_output_var_id, load);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SpvId
|
||||
emit_atomic(struct ntv_context *ctx, SpvId op, SpvId type, SpvId src0, SpvId src1, SpvId src2)
|
||||
{
|
||||
|
|
@ -3635,11 +3240,6 @@ emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
|
|||
break;
|
||||
|
||||
case nir_intrinsic_emit_vertex:
|
||||
/* geometry shader emits copied xfb outputs just prior to EmitVertex(),
|
||||
* since that's the end of the shader
|
||||
*/
|
||||
if (ctx->sinfo)
|
||||
emit_so_outputs(ctx, ctx->sinfo);
|
||||
if (ctx->nir->info.gs.vertices_out) //skip vertex emission if !vertices_out
|
||||
spirv_builder_emit_vertex(&ctx->builder, nir_intrinsic_stream_id(intr),
|
||||
ctx->nir->info.stage == MESA_SHADER_GEOMETRY && util_bitcount(ctx->nir->info.gs.active_stream_mask) > 1);
|
||||
|
|
@ -4804,9 +4404,6 @@ nir_to_spirv(struct nir_shader *s, const struct zink_shader_info *sinfo, uint32_
|
|||
ctx.vars = _mesa_hash_table_create(ctx.mem_ctx, _mesa_hash_pointer,
|
||||
_mesa_key_pointer_equal);
|
||||
|
||||
ctx.so_outputs = _mesa_hash_table_create(ctx.mem_ctx, _mesa_hash_u32,
|
||||
_mesa_key_u32_equal);
|
||||
|
||||
nir_foreach_variable_with_modes(var, s, nir_var_mem_push_const)
|
||||
input_var_init(&ctx, var);
|
||||
|
||||
|
|
@ -4824,8 +4421,6 @@ nir_to_spirv(struct nir_shader *s, const struct zink_shader_info *sinfo, uint32_
|
|||
emit_output(&ctx, var);
|
||||
}
|
||||
|
||||
if (sinfo->last_vertex)
|
||||
emit_so_info(&ctx, sinfo, max_output);
|
||||
uint32_t tcs_vertices_out_word = 0;
|
||||
|
||||
unsigned ubo_counter[2] = {0};
|
||||
|
|
@ -5059,10 +4654,6 @@ nir_to_spirv(struct nir_shader *s, const struct zink_shader_info *sinfo, uint32_
|
|||
|
||||
emit_cf_list(&ctx, &entry->body);
|
||||
|
||||
/* vertex/tess shader emits copied xfb outputs at the end of the shader */
|
||||
if (sinfo->last_vertex && (ctx.stage == MESA_SHADER_VERTEX || ctx.stage == MESA_SHADER_TESS_EVAL))
|
||||
emit_so_outputs(&ctx, sinfo);
|
||||
|
||||
spirv_builder_return(&ctx.builder); // doesn't belong here, but whatevz
|
||||
spirv_builder_function_end(&ctx.builder);
|
||||
|
||||
|
|
|
|||
|
|
@ -1831,7 +1831,7 @@ update_so_info(struct zink_shader *zs, nir_shader *nir, const struct pipe_stream
|
|||
for (unsigned i = 0; i < so_info->num_outputs; i++) {
|
||||
const struct pipe_stream_output *output = &so_info->output[i];
|
||||
/* always set stride to be used during draw */
|
||||
zs->sinfo.so_info.stride[output->output_buffer] = so_info->stride[output->output_buffer];
|
||||
zs->sinfo.stride[output->output_buffer] = so_info->stride[output->output_buffer];
|
||||
if (zs->info.stage != MESA_SHADER_GEOMETRY || util_bitcount(zs->info.gs.active_stream_mask) == 1) {
|
||||
for (unsigned c = 0; !is_inlined(inlined[reverse_map[output->register_index]], output) && c < output->num_components; c++) {
|
||||
unsigned slot = reverse_map[output->register_index];
|
||||
|
|
@ -1944,9 +1944,6 @@ update_so_info(struct zink_shader *zs, nir_shader *nir, const struct pipe_stream
|
|||
var->data.xfb.stride = so_info->stride[output->output_buffer] * 4;
|
||||
var->data.offset = output->dst_offset * 4;
|
||||
var->data.stream = output->stream;
|
||||
/* GLSL specifies that interface blocks are split per-buffer in XFB */
|
||||
if (glsl_type_is_array(var->type) && glsl_array_size(var->type) > 1 && glsl_type_is_interface(glsl_without_array(var->type)))
|
||||
zs->sinfo.so_propagate |= BITFIELD_BIT(var->data.location - VARYING_SLOT_VAR0);
|
||||
/* mark all slot components inlined to skip subsequent loop iterations */
|
||||
for (unsigned j = 0; j < num_slots; j++) {
|
||||
slot = var->data.location + j;
|
||||
|
|
@ -1957,12 +1954,8 @@ update_so_info(struct zink_shader *zs, nir_shader *nir, const struct pipe_stream
|
|||
continue;
|
||||
}
|
||||
out:
|
||||
/* these are packed/explicit varyings which can't be exported with normal output */
|
||||
zs->sinfo.so_info.output[zs->sinfo.so_info.num_outputs] = *output;
|
||||
/* Map Gallium's condensed "slots" back to real VARYING_SLOT_* enums */
|
||||
zs->sinfo.so_info_slots[zs->sinfo.so_info.num_outputs++] = reverse_map[output->register_index];
|
||||
unreachable("xfb should be inlined by now!");
|
||||
}
|
||||
zs->sinfo.have_xfb = zs->sinfo.so_info.num_outputs || zs->sinfo.so_propagate;
|
||||
/* ensure this doesn't get output in the shader by unsetting location */
|
||||
if (have_fake_psiz && psiz)
|
||||
update_psiz_location(nir, psiz);
|
||||
|
|
@ -3637,7 +3630,6 @@ struct zink_shader_object
|
|||
zink_shader_compile(struct zink_screen *screen, bool can_shobj, struct zink_shader *zs,
|
||||
nir_shader *nir, const struct zink_shader_key *key, const void *extra_data, struct zink_program *pg)
|
||||
{
|
||||
struct zink_shader_info *sinfo = &zs->sinfo;
|
||||
bool need_optimize = true;
|
||||
bool inlined_uniforms = false;
|
||||
|
||||
|
|
@ -3714,9 +3706,6 @@ zink_shader_compile(struct zink_screen *screen, bool can_shobj, struct zink_shad
|
|||
case MESA_SHADER_TESS_EVAL:
|
||||
case MESA_SHADER_GEOMETRY:
|
||||
if (zink_vs_key_base(key)->last_vertex_stage) {
|
||||
if (zs->sinfo.have_xfb)
|
||||
sinfo->last_vertex = true;
|
||||
|
||||
if (!zink_vs_key_base(key)->clip_halfz && !screen->info.have_EXT_depth_clip_control) {
|
||||
NIR_PASS_V(nir, nir_lower_clip_halfz);
|
||||
}
|
||||
|
|
@ -3871,7 +3860,6 @@ zink_shader_compile_separate(struct zink_screen *screen, struct zink_shader *zs)
|
|||
}
|
||||
optimize_nir(nir, zs);
|
||||
zink_descriptor_shader_init(screen, zs);
|
||||
zs->sinfo.last_vertex = zs->sinfo.have_xfb;
|
||||
nir_shader *nir_clone = NULL;
|
||||
if (screen->info.have_EXT_shader_object)
|
||||
nir_clone = nir_shader_clone(nir, nir);
|
||||
|
|
|
|||
|
|
@ -991,7 +991,7 @@ zink_draw(struct pipe_context *pctx,
|
|||
counter_buffers[i] = VK_NULL_HANDLE;
|
||||
if (t) {
|
||||
struct zink_resource *res = zink_resource(t->counter_buffer);
|
||||
t->stride = ctx->last_vertex_stage->sinfo.so_info.stride[i] * sizeof(uint32_t);
|
||||
t->stride = ctx->last_vertex_stage->sinfo.stride[i] * sizeof(uint32_t);
|
||||
zink_batch_reference_resource_rw(batch, res, true);
|
||||
if (!ctx->unordered_blitting)
|
||||
res->obj->unordered_read = res->obj->unordered_write = false;
|
||||
|
|
|
|||
|
|
@ -2466,13 +2466,13 @@ zink_set_primitive_emulation_keys(struct zink_context *ctx)
|
|||
zink_add_inline_uniform(nir, ZINK_INLINE_VAL_FLAT_MASK);
|
||||
zink_add_inline_uniform(nir, ZINK_INLINE_VAL_PV_LAST_VERT);
|
||||
ralloc_free(prev_stage);
|
||||
struct zink_shader *shader = zink_shader_create(screen, nir, &ctx->gfx_stages[prev_vertex_stage]->sinfo.so_info);
|
||||
struct zink_shader *shader = zink_shader_create(screen, nir, NULL);
|
||||
shader->needs_inlining = true;
|
||||
ctx->gfx_stages[prev_vertex_stage]->non_fs.generated_gs[ctx->gfx_pipeline_state.gfx_prim_mode][zink_prim_type] = shader;
|
||||
shader->non_fs.is_generated = true;
|
||||
shader->non_fs.parent = ctx->gfx_stages[prev_vertex_stage];
|
||||
shader->can_inline = true;
|
||||
shader->sinfo.so_info = ctx->gfx_stages[prev_vertex_stage]->sinfo.so_info;
|
||||
memcpy(shader->sinfo.stride, ctx->gfx_stages[prev_vertex_stage]->sinfo.stride, sizeof(shader->sinfo.stride));
|
||||
}
|
||||
|
||||
ctx->base.bind_gs_state(&ctx->base,
|
||||
|
|
|
|||
|
|
@ -756,12 +756,8 @@ struct zink_framebuffer_clear {
|
|||
|
||||
/** compiler types */
|
||||
struct zink_shader_info {
|
||||
struct pipe_stream_output_info so_info;
|
||||
unsigned so_info_slots[PIPE_MAX_SO_OUTPUTS];
|
||||
uint32_t so_propagate; //left shifted by 32
|
||||
uint16_t stride[PIPE_MAX_SO_BUFFERS];
|
||||
uint32_t sampler_mask;
|
||||
bool last_vertex;
|
||||
bool have_xfb;
|
||||
bool have_sparse;
|
||||
bool have_vulkan_memory_model;
|
||||
bool have_workgroup_memory_explicit_layout;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue