From 8772c693c5a0b94be7fd891c278e504dabc0ee54 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Sat, 13 Jun 2020 11:39:00 -0400 Subject: [PATCH] zink: adjust zink_shader struct to contain full streamout info move remapped register_index -> slot into a separate value on the struct in order to preserve the register_index value Reviewed-by: Erik Faye-Lund Part-of: --- .../drivers/zink/nir_to_spirv/nir_to_spirv.c | 44 ++++++++++--------- .../drivers/zink/nir_to_spirv/nir_to_spirv.h | 5 ++- src/gallium/drivers/zink/zink_compiler.c | 20 +++++---- src/gallium/drivers/zink/zink_compiler.h | 8 +++- src/gallium/drivers/zink/zink_draw.c | 2 +- 5 files changed, 45 insertions(+), 34 deletions(-) diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c index 68a5d00a350..a4106e7439c 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c +++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c @@ -889,11 +889,12 @@ get_output_type(struct ntv_context *ctx, unsigned register_index, unsigned num_c from complete outputs, so we just can't use the created packed outputs */ static void emit_so_info(struct ntv_context *ctx, unsigned max_output_location, - const struct pipe_stream_output_info *so_info, struct pipe_stream_output_info *local_so_info) + const struct zink_so_info *so_info) { - for (unsigned i = 0; i < local_so_info->num_outputs; i++) { - struct pipe_stream_output so_output = local_so_info->output[i]; - SpvId out_type = get_output_type(ctx, so_output.register_index, so_output.num_components); + 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]; + SpvId out_type = get_output_type(ctx, slot, so_output.num_components); SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder, SpvStorageClassOutput, out_type); @@ -905,7 +906,7 @@ emit_so_info(struct ntv_context *ctx, unsigned max_output_location, 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->stride[so_output.output_buffer] * 4); + spirv_builder_emit_xfb_stride(&ctx->builder, var_id, so_info->so_info.stride[so_output.output_buffer] * 4); /* 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 @@ -939,32 +940,33 @@ emit_so_info(struct ntv_context *ctx, unsigned max_output_location, static void emit_so_outputs(struct ntv_context *ctx, - const struct pipe_stream_output_info *so_info, struct pipe_stream_output_info *local_so_info) + const struct zink_so_info *so_info) { SpvId loaded_outputs[VARYING_SLOT_MAX] = {}; - for (unsigned i = 0; i < local_so_info->num_outputs; i++) { + for (unsigned i = 0; i < so_info->so_info.num_outputs; i++) { uint32_t components[NIR_MAX_VEC_COMPONENTS]; - struct pipe_stream_output so_output = local_so_info->output[i]; + 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; 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, so_output.register_index, so_output.num_components); - SpvId output = ctx->outputs[so_output.register_index]; - SpvId output_type = ctx->so_output_types[so_output.register_index]; - const struct glsl_type *out_type = ctx->so_output_gl_types[so_output.register_index]; + SpvId type = get_output_type(ctx, slot, so_output.num_components); + SpvId output = ctx->outputs[slot]; + SpvId output_type = ctx->so_output_types[slot]; + const struct glsl_type *out_type = ctx->so_output_gl_types[slot]; - if (!loaded_outputs[so_output.register_index]) - loaded_outputs[so_output.register_index] = spirv_builder_emit_load(&ctx->builder, output_type, output); - SpvId src = loaded_outputs[so_output.register_index]; + if (!loaded_outputs[slot]) + loaded_outputs[slot] = spirv_builder_emit_load(&ctx->builder, output_type, output); + SpvId src = loaded_outputs[slot]; SpvId result; 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 (ctx->stage == MESA_SHADER_VERTEX && so_output.register_index == VARYING_SLOT_CLIP_DIST1) + if (ctx->stage == MESA_SHADER_VERTEX && slot == VARYING_SLOT_CLIP_DIST1) components[c] += 4; } @@ -991,7 +993,7 @@ emit_so_outputs(struct ntv_context *ctx, uint32_t member[] = { so_output.start_component + c }; SpvId base_type = get_glsl_type(ctx, glsl_without_array(out_type)); - if (ctx->stage == MESA_SHADER_VERTEX && so_output.register_index == VARYING_SLOT_CLIP_DIST1) + if (ctx->stage == MESA_SHADER_VERTEX && slot == VARYING_SLOT_CLIP_DIST1) member[0] += 4; components[c] = spirv_builder_emit_composite_extract(&ctx->builder, base_type, src, member, 1); } @@ -2227,7 +2229,7 @@ emit_cf_list(struct ntv_context *ctx, struct exec_list *list) } struct spirv_shader * -nir_to_spirv(struct nir_shader *s, const struct pipe_stream_output_info *so_info, struct pipe_stream_output_info *local_so_info) +nir_to_spirv(struct nir_shader *s, const struct zink_so_info *so_info) { struct spirv_shader *ret = NULL; @@ -2312,7 +2314,7 @@ nir_to_spirv(struct nir_shader *s, const struct pipe_stream_output_info *so_info emit_output(&ctx, var); if (so_info) - emit_so_info(&ctx, util_last_bit64(s->info.outputs_written), so_info, local_so_info); + emit_so_info(&ctx, util_last_bit64(s->info.outputs_written), so_info); nir_foreach_variable_with_modes(var, s, nir_var_uniform | nir_var_mem_ubo | nir_var_mem_ssbo) @@ -2326,7 +2328,7 @@ nir_to_spirv(struct nir_shader *s, const struct pipe_stream_output_info *so_info SpvExecutionModeDepthReplacing); } - if (so_info && so_info->num_outputs) { + if (so_info && so_info->so_info.num_outputs) { spirv_builder_emit_cap(&ctx.builder, SpvCapabilityTransformFeedback); spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModeXfb); @@ -2379,7 +2381,7 @@ nir_to_spirv(struct nir_shader *s, const struct pipe_stream_output_info *so_info emit_cf_list(&ctx, &entry->body); if (so_info) - emit_so_outputs(&ctx, so_info, local_so_info); + emit_so_outputs(&ctx, so_info); spirv_builder_return(&ctx.builder); // doesn't belong here, but whatevz spirv_builder_function_end(&ctx.builder); diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.h b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.h index 5c4e5583107..77d77add4e4 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.h +++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.h @@ -29,6 +29,9 @@ #include #include "compiler/shader_enums.h" +#include "pipe/p_state.h" + +#include "zink_compiler.h" struct spirv_shader { uint32_t *words; @@ -39,7 +42,7 @@ struct nir_shader; struct pipe_stream_output_info; struct spirv_shader * -nir_to_spirv(struct nir_shader *s, const struct pipe_stream_output_info *so_info, struct pipe_stream_output_info *local_so_info); +nir_to_spirv(struct nir_shader *s, const struct zink_so_info *so_info); void spirv_shader_delete(struct spirv_shader *s); diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index 4154f79c40e..d42379e3ec0 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -194,7 +194,7 @@ check_psiz(struct nir_shader *s) /* semi-copied from iris */ static void -update_so_info(struct pipe_stream_output_info *so_info, +update_so_info(struct zink_shader *sh, uint64_t outputs_written, bool have_psiz) { uint8_t reverse_map[64] = {}; @@ -207,11 +207,10 @@ update_so_info(struct pipe_stream_output_info *so_info, reverse_map[slot++] = bit; } - for (unsigned i = 0; i < so_info->num_outputs; i++) { - struct pipe_stream_output *output = &so_info->output[i]; - + for (unsigned i = 0; i < sh->streamout.so_info.num_outputs; i++) { + struct pipe_stream_output *output = &sh->streamout.so_info.output[i]; /* Map Gallium's condensed "slots" back to real VARYING_SLOT_* enums */ - output->register_index = reverse_map[output->register_index]; + sh->streamout.so_info_slots[i] = reverse_map[output->register_index]; } } @@ -279,11 +278,13 @@ zink_compile_nir(struct zink_screen *screen, struct nir_shader *nir, ret->info = nir->info; if (so_info) { - memcpy(&ret->stream_output, so_info, sizeof(ret->stream_output)); - update_so_info(&ret->stream_output, nir->info.outputs_written, have_psiz); + memcpy(&ret->streamout.so_info, so_info, sizeof(struct pipe_stream_output_info)); + ret->streamout.so_info_slots = malloc(so_info->num_outputs * sizeof(unsigned int)); + assert(ret->streamout.so_info_slots); + update_so_info(ret, nir->info.outputs_written, have_psiz); } - struct spirv_shader *spirv = nir_to_spirv(nir, so_info, so_info ? &ret->stream_output : NULL); + struct spirv_shader *spirv = nir_to_spirv(nir, so_info ? &ret->streamout : NULL); assert(spirv); if (zink_debug & ZINK_DEBUG_SPIRV) { @@ -322,6 +323,7 @@ zink_shader_free(struct zink_context *ctx, struct zink_shader *shader) _mesa_hash_table_remove_key(ctx->program_cache, prog->stages); zink_destroy_gfx_program(screen, prog); } - _mesa_set_destroy(shader->programs, NULL); + _mesa_set_destroy(shader->programs, NULL + free(shader->streamout.so_info_slots); FREE(shader); } diff --git a/src/gallium/drivers/zink/zink_compiler.h b/src/gallium/drivers/zink/zink_compiler.h index ed22479ca20..50779d7c954 100644 --- a/src/gallium/drivers/zink/zink_compiler.h +++ b/src/gallium/drivers/zink/zink_compiler.h @@ -42,6 +42,11 @@ struct nir_shader; struct set; struct tgsi_token; +struct zink_so_info { + struct pipe_stream_output_info so_info; + unsigned *so_info_slots; +}; + const void * zink_get_compiler_options(struct pipe_screen *screen, @@ -55,8 +60,7 @@ struct zink_shader { VkShaderModule shader_module; shader_info info; - - struct pipe_stream_output_info stream_output; + struct zink_so_info streamout; struct { int index; diff --git a/src/gallium/drivers/zink/zink_draw.c b/src/gallium/drivers/zink/zink_draw.c index 7e038d1eb52..34953f66072 100644 --- a/src/gallium/drivers/zink/zink_draw.c +++ b/src/gallium/drivers/zink/zink_draw.c @@ -295,7 +295,7 @@ zink_draw_vbo(struct pipe_context *pctx, if (i == MESA_SHADER_VERTEX && ctx->num_so_targets) { for (unsigned i = 0; i < ctx->num_so_targets; i++) { struct zink_so_target *t = zink_so_target(ctx->so_targets[i]); - t->stride = shader->stream_output.stride[i] * sizeof(uint32_t); + t->stride = shader->streamout.so_info.stride[i] * sizeof(uint32_t); } } -- 2.30.2