From: Erik Faye-Lund Date: Mon, 8 Jul 2019 13:17:28 +0000 (+0200) Subject: zink: do not lower io X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=80673264cbb8acea304d112b9526b161c91a580b;p=mesa.git zink: do not lower io Acked-by: Jordan Justen --- 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 2989838919a..8534ed1300a 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 @@ -27,6 +27,7 @@ #include "nir.h" #include "pipe/p_state.h" #include "util/u_memory.h" +#include "util/hash_table.h" struct ntv_context { struct spirv_builder builder; @@ -34,10 +35,6 @@ struct ntv_context { SpvId GLSL_std_450; gl_shader_stage stage; - SpvId inputs[PIPE_MAX_SHADER_INPUTS][4]; - SpvId input_types[PIPE_MAX_SHADER_INPUTS][4]; - SpvId outputs[PIPE_MAX_SHADER_OUTPUTS][4]; - SpvId output_types[PIPE_MAX_SHADER_OUTPUTS][4]; int var_location; SpvId ubos[128]; @@ -53,6 +50,8 @@ struct ntv_context { SpvId *regs; size_t num_regs; + struct hash_table *vars; /* nir_variable -> SpvId */ + const SpvId *block_ids; size_t num_blocks; bool block_started; @@ -225,11 +224,7 @@ emit_input(struct ntv_context *ctx, struct nir_variable *var) if (var->data.interpolation == INTERP_MODE_FLAT) spirv_builder_emit_decoration(&ctx->builder, var_id, SpvDecorationFlat); - assert(var->data.driver_location < PIPE_MAX_SHADER_INPUTS); - assert(var->data.location_frac < 4); - assert(ctx->inputs[var->data.driver_location][var->data.location_frac] == 0); - ctx->inputs[var->data.driver_location][var->data.location_frac] = var_id; - ctx->input_types[var->data.driver_location][var->data.location_frac] = var_type; + _mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id); assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces)); ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id; @@ -284,11 +279,7 @@ emit_output(struct ntv_context *ctx, struct nir_variable *var) spirv_builder_emit_component(&ctx->builder, var_id, var->data.location_frac); - assert(var->data.driver_location < PIPE_MAX_SHADER_INPUTS); - assert(var->data.location_frac < 4); - assert(ctx->outputs[var->data.driver_location][var->data.location_frac] == 0); - ctx->outputs[var->data.driver_location][var->data.location_frac] = var_id; - ctx->output_types[var->data.driver_location][var->data.location_frac] = var_type; + _mesa_hash_table_insert(ctx->vars, var, (void *)(intptr_t)var_id); assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces)); ctx->entry_ifaces[ctx->num_entry_ifaces++] = var_id; @@ -929,31 +920,6 @@ emit_load_const(struct ntv_context *ctx, nir_load_const_instr *load_const) store_ssa_def_uint(ctx, &load_const->def, constant); } -static void -emit_load_input(struct ntv_context *ctx, nir_intrinsic_instr *intr) -{ - nir_const_value *const_offset = nir_src_as_const_value(intr->src[0]); - if (const_offset) { - int driver_location = (int)nir_intrinsic_base(intr) + const_offset->u32; - assert(driver_location < PIPE_MAX_SHADER_INPUTS); - int location_frac = nir_intrinsic_component(intr); - assert(location_frac < 4); - - SpvId ptr = ctx->inputs[driver_location][location_frac]; - SpvId type = ctx->input_types[driver_location][location_frac]; - assert(ptr && type); - - SpvId result = spirv_builder_emit_load(&ctx->builder, type, ptr); - - unsigned num_components = nir_dest_num_components(intr->dest); - unsigned bit_size = nir_dest_bit_size(intr->dest); - result = bitcast_to_uvec(ctx, result, bit_size, num_components); - - store_dest_uint(ctx, &intr->dest, result); - } else - unreachable("input-addressing not yet supported"); -} - static void emit_load_ubo(struct ntv_context *ctx, nir_intrinsic_instr *intr) { @@ -1005,27 +971,6 @@ emit_load_ubo(struct ntv_context *ctx, nir_intrinsic_instr *intr) unreachable("uniform-addressing not yet supported"); } -static void -emit_store_output(struct ntv_context *ctx, nir_intrinsic_instr *intr) -{ - nir_const_value *const_offset = nir_src_as_const_value(intr->src[1]); - if (const_offset) { - int driver_location = (int)nir_intrinsic_base(intr) + const_offset->u32; - assert(driver_location < PIPE_MAX_SHADER_OUTPUTS); - int location_frac = nir_intrinsic_component(intr); - assert(location_frac < 4); - - SpvId ptr = ctx->outputs[driver_location][location_frac]; - assert(ptr > 0); - - SpvId src = get_src_uint(ctx, &intr->src[0]); - SpvId spirv_type = ctx->output_types[driver_location][location_frac]; - SpvId result = emit_unop(ctx, SpvOpBitcast, spirv_type, src); - spirv_builder_emit_store(&ctx->builder, ptr, result); - } else - unreachable("output-addressing not yet supported"); -} - static void emit_discard(struct ntv_context *ctx, nir_intrinsic_instr *intr) { @@ -1036,26 +981,59 @@ emit_discard(struct ntv_context *ctx, nir_intrinsic_instr *intr) spirv_builder_label(&ctx->builder, spirv_builder_new_id(&ctx->builder)); } +static void +emit_load_deref(struct ntv_context *ctx, nir_intrinsic_instr *intr) +{ + nir_variable *var = nir_intrinsic_get_var(intr, 0); + struct hash_entry *he = _mesa_hash_table_search(ctx->vars, var); + assert(he); + SpvId ptr = (SpvId)(intptr_t)he->data; + + // SpvId ptr = get_src_uint(ctx, intr->src); /* uint is a bit of a lie here; it's really just a pointer */ + SpvId result = spirv_builder_emit_load(&ctx->builder, + get_glsl_type(ctx, var->type), + ptr); + unsigned num_components = nir_dest_num_components(intr->dest); + unsigned bit_size = nir_dest_bit_size(intr->dest); + result = bitcast_to_uvec(ctx, result, bit_size, num_components); + store_dest_uint(ctx, &intr->dest, result); +} + +static void +emit_store_deref(struct ntv_context *ctx, nir_intrinsic_instr *intr) +{ + nir_variable *var = nir_intrinsic_get_var(intr, 0); + struct hash_entry *he = _mesa_hash_table_search(ctx->vars, var); + assert(he); + SpvId ptr = (SpvId)(intptr_t)he->data; + // SpvId ptr = get_src_uint(ctx, &intr->src[0]); /* uint is a bit of a lie here; it's really just a pointer */ + + SpvId src = get_src_uint(ctx, &intr->src[1]); + SpvId result = emit_unop(ctx, SpvOpBitcast, get_glsl_type(ctx, var->type), + src); + spirv_builder_emit_store(&ctx->builder, ptr, result); +} + static void emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr) { switch (intr->intrinsic) { - case nir_intrinsic_load_input: - emit_load_input(ctx, intr); - break; - case nir_intrinsic_load_ubo: emit_load_ubo(ctx, intr); break; - case nir_intrinsic_store_output: - emit_store_output(ctx, intr); - break; - case nir_intrinsic_discard: emit_discard(ctx, intr); break; + case nir_intrinsic_load_deref: + emit_load_deref(ctx, intr); + break; + + case nir_intrinsic_store_deref: + emit_store_deref(ctx, intr); + break; + default: fprintf(stderr, "emit_intrinsic: not implemented (%s)\n", nir_intrinsic_infos[intr->intrinsic].name); @@ -1233,6 +1211,40 @@ emit_jump(struct ntv_context *ctx, nir_jump_instr *jump) } } +static void +emit_deref(struct ntv_context *ctx, nir_deref_instr *deref) +{ + assert(deref->deref_type == nir_deref_type_var); + + SpvStorageClass storage_class; + switch (deref->var->data.mode) { + case nir_var_shader_in: + storage_class = SpvStorageClassInput; + break; + + case nir_var_shader_out: + storage_class = SpvStorageClassOutput; + break; + + default: + unreachable("Unsupported nir_variable_mode\n"); + } + + struct hash_entry *he = _mesa_hash_table_search(ctx->vars, deref->var); + assert(he); + + SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder, + storage_class, + get_glsl_type(ctx, deref->type)); + + SpvId result = spirv_builder_emit_access_chain(&ctx->builder, + ptr_type, + (SpvId)(intptr_t)he->data, + NULL, 0); + /* uint is a bit of a lie here, it's really just an opaque type */ + store_dest_uint(ctx, &deref->dest, result); +} + static void emit_block(struct ntv_context *ctx, struct nir_block *block) { @@ -1267,7 +1279,8 @@ emit_block(struct ntv_context *ctx, struct nir_block *block) unreachable("nir_instr_type_parallel_copy not supported"); break; case nir_instr_type_deref: - unreachable("nir_instr_type_deref not supported"); + /* these are handled in emit_{load,store}_deref */ + /* emit_deref(ctx, nir_instr_as_deref(instr)); */ break; } } @@ -1437,6 +1450,9 @@ nir_to_spirv(struct nir_shader *s) SpvId entry_point = spirv_builder_new_id(&ctx.builder); spirv_builder_emit_name(&ctx.builder, entry_point, "main"); + ctx.vars = _mesa_hash_table_create(NULL, _mesa_hash_pointer, + _mesa_key_pointer_equal); + nir_foreach_variable(var, &s->inputs) emit_input(&ctx, var); @@ -1522,6 +1538,9 @@ fail: if (ret) spirv_shader_delete(ret); + if (ctx.vars) + _mesa_hash_table_destroy(ctx.vars, NULL); + return NULL; } diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index 1c3d5327321..afe93bff0ed 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -145,6 +145,37 @@ lower_store_output(nir_builder *b, nir_instr_rewrite_src(&intr->instr, &intr->src[0], nir_src_for_ssa(def)); } +static void +lower_store_deref(nir_builder *b, + struct nir_instr *instr) +{ + if (instr->type != nir_instr_type_intrinsic) + return; + + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); + if (intr->intrinsic != nir_intrinsic_store_deref) + return; + + nir_variable *var = nir_intrinsic_get_var(intr, 0); + if (var->data.mode != nir_var_shader_out || + var->data.location != VARYING_SLOT_POS) + return; + + b->cursor = nir_before_instr(&intr->instr); + + nir_ssa_def *src = nir_ssa_for_src(b, intr->src[1], 4); + nir_ssa_def *def = nir_vec4(b, + nir_channel(b, src, 0), + nir_channel(b, src, 1), + nir_fmul(b, + nir_fadd(b, + nir_channel(b, src, 2), + nir_channel(b, src, 3)), + nir_imm_float(b, 0.5)), + nir_channel(b, src, 3)); + nir_instr_rewrite_src(&intr->instr, &intr->src[1], nir_src_for_ssa(def)); +} + static void position_to_vulkan(nir_shader *s) { @@ -157,8 +188,10 @@ position_to_vulkan(nir_shader *s) nir_builder_init(&b, function->impl); nir_foreach_block(block, function->impl) { - nir_foreach_instr_safe(instr, block) + nir_foreach_instr_safe(instr, block) { lower_store_output(&b, instr); + lower_store_deref(&b, instr); + } } nir_metadata_preserve(function->impl, nir_metadata_block_index | @@ -260,12 +293,6 @@ optimize_nir(struct nir_shader *s) } while (progress); } -static int -glsl_type_size(const struct glsl_type *type, bool bindless) -{ - return glsl_count_attribute_slots(type, false); -} - static uint32_t zink_binding(enum pipe_shader_type stage, VkDescriptorType type, int index) { @@ -295,7 +322,6 @@ zink_compile_nir(struct zink_screen *screen, struct nir_shader *nir) { struct zink_shader *ret = CALLOC_STRUCT(zink_shader); - NIR_PASS_V(nir, nir_lower_io, nir_var_all, glsl_type_size, (nir_lower_io_options)0); NIR_PASS_V(nir, lower_uniforms_to_ubo); NIR_PASS_V(nir, position_to_vulkan); NIR_PASS_V(nir, nir_lower_regs_to_ssa);