zink: handle direct xfb output from output variables
if an entire variable is being dumped into an xfb buffer, there's no need to create an explicit xfb variable to copy the value into, and instead the xfb attributes can just be set normally on the variable this doesn't work for geometry shaders because outputs are per-vertex fixes all KHR-GL46.enhanced_layouts xfb tests Reviewed-by: Dave Airlie <airlied@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9271>
This commit is contained in:

committed by
Marge Bot

parent
7cef91dd43
commit
6d40db84c9
@@ -621,6 +621,14 @@ emit_output(struct ntv_context *ctx, struct nir_variable *var)
|
||||
if (var->data.patch)
|
||||
spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationPatch);
|
||||
|
||||
if (var->data.explicit_xfb_buffer) {
|
||||
spirv_builder_emit_offset(&ctx->builder, var_id, var->data.offset);
|
||||
spirv_builder_emit_xfb_buffer(&ctx->builder, var_id, var->data.xfb.buffer);
|
||||
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);
|
||||
}
|
||||
|
||||
_mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id);
|
||||
|
||||
assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
|
||||
@@ -1252,6 +1260,8 @@ emit_so_info(struct ntv_context *ctx, const struct zink_so_info *so_info)
|
||||
{
|
||||
unsigned output = 0;
|
||||
for (unsigned i = 0; i < so_info->so_info.num_outputs; i++) {
|
||||
if (so_info->skip[i])
|
||||
continue;
|
||||
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);
|
||||
@@ -1299,6 +1309,8 @@ emit_so_outputs(struct ntv_context *ctx,
|
||||
const struct zink_so_info *so_info)
|
||||
{
|
||||
for (unsigned i = 0; i < so_info->so_info.num_outputs; i++) {
|
||||
if (so_info->skip[i])
|
||||
continue;
|
||||
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];
|
||||
|
@@ -402,13 +402,13 @@ check_psiz(struct nir_shader *s)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* semi-copied from iris */
|
||||
static void
|
||||
update_so_info(struct zink_shader *sh,
|
||||
uint64_t outputs_written, bool have_psiz)
|
||||
{
|
||||
uint8_t reverse_map[64] = {};
|
||||
unsigned slot = 0;
|
||||
/* semi-copied from iris */
|
||||
while (outputs_written) {
|
||||
int bit = u_bit_scan64(&outputs_written);
|
||||
/* PSIZ from nir_lower_point_size_mov breaks stream output, so always skip it */
|
||||
@@ -417,8 +417,36 @@ update_so_info(struct zink_shader *sh,
|
||||
reverse_map[slot++] = bit;
|
||||
}
|
||||
|
||||
nir_foreach_shader_out_variable(var, sh->nir)
|
||||
var->data.explicit_xfb_buffer = 0;
|
||||
|
||||
bool inlined[64] = {0};
|
||||
for (unsigned i = 0; i < sh->streamout.so_info.num_outputs; i++) {
|
||||
struct pipe_stream_output *output = &sh->streamout.so_info.output[i];
|
||||
unsigned slot = reverse_map[output->register_index];
|
||||
if ((sh->nir->info.stage != MESA_SHADER_GEOMETRY || util_bitcount(sh->nir->info.gs.active_stream_mask) == 1) &&
|
||||
!output->start_component) {
|
||||
nir_variable *var = NULL;
|
||||
while (!var)
|
||||
var = nir_find_variable_with_location(sh->nir, nir_var_shader_out, slot--);
|
||||
slot++;
|
||||
if (inlined[slot]) {
|
||||
sh->streamout.skip[i] = true;
|
||||
continue;
|
||||
}
|
||||
assert(var && var->data.location == slot);
|
||||
/* if this is the entire variable, try to blast it out during the initial declaration */
|
||||
if (glsl_get_components(var->type) == output->num_components) {
|
||||
var->data.explicit_xfb_buffer = 1;
|
||||
var->data.xfb.buffer = output->output_buffer;
|
||||
var->data.xfb.stride = sh->streamout.so_info.stride[output->output_buffer] * 4;
|
||||
var->data.offset = output->dst_offset * 4;
|
||||
var->data.stream = output->stream;
|
||||
sh->streamout.skip[i] = true;
|
||||
inlined[slot] = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/* Map Gallium's condensed "slots" back to real VARYING_SLOT_* enums */
|
||||
sh->streamout.so_info_slots[i] = reverse_map[output->register_index];
|
||||
}
|
||||
|
@@ -51,6 +51,7 @@ struct tgsi_token;
|
||||
struct zink_so_info {
|
||||
struct pipe_stream_output_info so_info;
|
||||
unsigned so_info_slots[PIPE_MAX_SO_OUTPUTS];
|
||||
bool skip[PIPE_MAX_SO_OUTPUTS];
|
||||
bool have_xfb;
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user