spirv: Use deref instructions for most variables
The only thing still using old-school drefs are function calls. Acked-by: Rob Clark <robdclark@gmail.com> Acked-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Acked-by: Dave Airlie <airlied@redhat.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
#include "nir/nir_vla.h"
|
||||
#include "nir/nir_control_flow.h"
|
||||
#include "nir/nir_constant_expressions.h"
|
||||
#include "nir/nir_deref.h"
|
||||
#include "spirv_info.h"
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -1792,7 +1793,7 @@ vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode,
|
||||
struct vtn_value *arg = vtn_untyped_value(b, arg_id);
|
||||
if (arg->value_type == vtn_value_type_pointer &&
|
||||
arg->pointer->ptr_type->type == NULL) {
|
||||
nir_deref_var *d = vtn_pointer_to_deref(b, arg->pointer);
|
||||
nir_deref_var *d = vtn_pointer_to_deref_var(b, arg->pointer);
|
||||
call->params[i] = nir_deref_var_clone(d, call);
|
||||
} else {
|
||||
struct vtn_ssa_value *arg_ssa = vtn_ssa_value(b, arg_id);
|
||||
@@ -1802,7 +1803,8 @@ vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode,
|
||||
nir_local_variable_create(b->nb.impl, arg_ssa->type, "arg_tmp");
|
||||
call->params[i] = nir_deref_var_create(call, tmp);
|
||||
|
||||
vtn_local_store(b, arg_ssa, call->params[i]);
|
||||
vtn_local_store(b, arg_ssa,
|
||||
nir_build_deref_for_chain(&b->nb, call->params[i]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1819,7 +1821,9 @@ vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode,
|
||||
if (glsl_type_is_void(callee->return_type)) {
|
||||
vtn_push_value(b, w[2], vtn_value_type_undef);
|
||||
} else {
|
||||
vtn_push_ssa(b, w[2], res_type, vtn_local_load(b, call->return_deref));
|
||||
nir_deref_instr *return_deref =
|
||||
nir_build_deref_for_chain(&b->nb, call->return_deref);
|
||||
vtn_push_ssa(b, w[2], res_type, vtn_local_load(b, return_deref));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1972,9 +1976,41 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
|
||||
vtn_fail("Unhandled opcode");
|
||||
}
|
||||
|
||||
nir_tex_src srcs[8]; /* 8 should be enough */
|
||||
nir_tex_src srcs[10]; /* 10 should be enough */
|
||||
nir_tex_src *p = srcs;
|
||||
|
||||
nir_deref_instr *sampler = vtn_pointer_to_deref(b, sampled.sampler);
|
||||
nir_deref_instr *texture =
|
||||
sampled.image ? vtn_pointer_to_deref(b, sampled.image) : sampler;
|
||||
|
||||
p->src = nir_src_for_ssa(&texture->dest.ssa);
|
||||
p->src_type = nir_tex_src_texture_deref;
|
||||
p++;
|
||||
|
||||
switch (texop) {
|
||||
case nir_texop_tex:
|
||||
case nir_texop_txb:
|
||||
case nir_texop_txl:
|
||||
case nir_texop_txd:
|
||||
case nir_texop_tg4:
|
||||
/* These operations require a sampler */
|
||||
p->src = nir_src_for_ssa(&sampler->dest.ssa);
|
||||
p->src_type = nir_tex_src_sampler_deref;
|
||||
p++;
|
||||
break;
|
||||
case nir_texop_txf:
|
||||
case nir_texop_txf_ms:
|
||||
case nir_texop_txs:
|
||||
case nir_texop_lod:
|
||||
case nir_texop_query_levels:
|
||||
case nir_texop_texture_samples:
|
||||
case nir_texop_samples_identical:
|
||||
/* These don't */
|
||||
break;
|
||||
case nir_texop_txf_ms_mcs:
|
||||
vtn_fail("unexpected nir_texop_txf_ms_mcs");
|
||||
}
|
||||
|
||||
unsigned idx = 4;
|
||||
|
||||
struct nir_ssa_def *coord;
|
||||
@@ -2135,40 +2171,6 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
|
||||
vtn_fail("Invalid base type for sampler result");
|
||||
}
|
||||
|
||||
nir_deref_var *sampler = vtn_pointer_to_deref(b, sampled.sampler);
|
||||
nir_deref_var *texture;
|
||||
if (sampled.image) {
|
||||
nir_deref_var *image = vtn_pointer_to_deref(b, sampled.image);
|
||||
texture = image;
|
||||
} else {
|
||||
texture = sampler;
|
||||
}
|
||||
|
||||
instr->texture = nir_deref_var_clone(texture, instr);
|
||||
|
||||
switch (instr->op) {
|
||||
case nir_texop_tex:
|
||||
case nir_texop_txb:
|
||||
case nir_texop_txl:
|
||||
case nir_texop_txd:
|
||||
case nir_texop_tg4:
|
||||
/* These operations require a sampler */
|
||||
instr->sampler = nir_deref_var_clone(sampler, instr);
|
||||
break;
|
||||
case nir_texop_txf:
|
||||
case nir_texop_txf_ms:
|
||||
case nir_texop_txs:
|
||||
case nir_texop_lod:
|
||||
case nir_texop_query_levels:
|
||||
case nir_texop_texture_samples:
|
||||
case nir_texop_samples_identical:
|
||||
/* These don't */
|
||||
instr->sampler = NULL;
|
||||
break;
|
||||
case nir_texop_txf_ms_mcs:
|
||||
vtn_fail("unexpected nir_texop_txf_ms_mcs");
|
||||
}
|
||||
|
||||
nir_ssa_dest_init(&instr->instr, &instr->dest,
|
||||
nir_tex_instr_dest_size(instr), 32, NULL);
|
||||
|
||||
@@ -2193,8 +2195,6 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
|
||||
instrs[i]->is_new_style_shadow = instr->is_new_style_shadow;
|
||||
instrs[i]->component = instr->component;
|
||||
instrs[i]->dest_type = instr->dest_type;
|
||||
instrs[i]->texture = nir_deref_var_clone(texture, instrs[i]);
|
||||
instrs[i]->sampler = NULL;
|
||||
|
||||
memcpy(instrs[i]->src, srcs, instr->num_srcs * sizeof(*instr->src));
|
||||
|
||||
@@ -2369,7 +2369,7 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
|
||||
|
||||
nir_intrinsic_op op;
|
||||
switch (opcode) {
|
||||
#define OP(S, N) case SpvOp##S: op = nir_intrinsic_image_var_##N; break;
|
||||
#define OP(S, N) case SpvOp##S: op = nir_intrinsic_image_deref_##N; break;
|
||||
OP(ImageQuerySize, size)
|
||||
OP(ImageRead, load)
|
||||
OP(ImageWrite, store)
|
||||
@@ -2395,8 +2395,8 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
|
||||
|
||||
nir_intrinsic_instr *intrin = nir_intrinsic_instr_create(b->shader, op);
|
||||
|
||||
nir_deref_var *image_deref = vtn_pointer_to_deref(b, image.image);
|
||||
intrin->variables[0] = nir_deref_var_clone(image_deref, intrin);
|
||||
nir_deref_instr *image_deref = vtn_pointer_to_deref(b, image.image);
|
||||
intrin->src[0] = nir_src_for_ssa(&image_deref->dest.ssa);
|
||||
|
||||
/* ImageQuerySize doesn't take any extra parameters */
|
||||
if (opcode != SpvOpImageQuerySize) {
|
||||
@@ -2406,9 +2406,9 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
|
||||
unsigned swiz[4];
|
||||
for (unsigned i = 0; i < 4; i++)
|
||||
swiz[i] = i < image.coord->num_components ? i : 0;
|
||||
intrin->src[0] = nir_src_for_ssa(nir_swizzle(&b->nb, image.coord,
|
||||
intrin->src[1] = nir_src_for_ssa(nir_swizzle(&b->nb, image.coord,
|
||||
swiz, 4, false));
|
||||
intrin->src[1] = nir_src_for_ssa(image.sample);
|
||||
intrin->src[2] = nir_src_for_ssa(image.sample);
|
||||
}
|
||||
|
||||
switch (opcode) {
|
||||
@@ -2417,10 +2417,10 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
|
||||
case SpvOpImageRead:
|
||||
break;
|
||||
case SpvOpAtomicStore:
|
||||
intrin->src[2] = nir_src_for_ssa(vtn_ssa_value(b, w[4])->def);
|
||||
intrin->src[3] = nir_src_for_ssa(vtn_ssa_value(b, w[4])->def);
|
||||
break;
|
||||
case SpvOpImageWrite:
|
||||
intrin->src[2] = nir_src_for_ssa(vtn_ssa_value(b, w[3])->def);
|
||||
intrin->src[3] = nir_src_for_ssa(vtn_ssa_value(b, w[3])->def);
|
||||
break;
|
||||
|
||||
case SpvOpAtomicCompareExchange:
|
||||
@@ -2436,7 +2436,7 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
|
||||
case SpvOpAtomicAnd:
|
||||
case SpvOpAtomicOr:
|
||||
case SpvOpAtomicXor:
|
||||
fill_common_atomic_sources(b, opcode, w, &intrin->src[2]);
|
||||
fill_common_atomic_sources(b, opcode, w, &intrin->src[3]);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -2448,7 +2448,7 @@ vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
|
||||
struct vtn_type *type = vtn_value(b, w[1], vtn_value_type_type)->type;
|
||||
|
||||
unsigned dest_components = nir_intrinsic_dest_components(intrin);
|
||||
if (intrin->intrinsic == nir_intrinsic_image_var_size) {
|
||||
if (intrin->intrinsic == nir_intrinsic_image_deref_size) {
|
||||
dest_components = intrin->num_components =
|
||||
glsl_get_vector_elements(type->type);
|
||||
}
|
||||
@@ -2518,12 +2518,12 @@ get_shared_nir_atomic_op(struct vtn_builder *b, SpvOp opcode)
|
||||
}
|
||||
|
||||
static nir_intrinsic_op
|
||||
get_var_nir_atomic_op(struct vtn_builder *b, SpvOp opcode)
|
||||
get_deref_nir_atomic_op(struct vtn_builder *b, SpvOp opcode)
|
||||
{
|
||||
switch (opcode) {
|
||||
case SpvOpAtomicLoad: return nir_intrinsic_load_var;
|
||||
case SpvOpAtomicStore: return nir_intrinsic_store_var;
|
||||
#define OP(S, N) case SpvOp##S: return nir_intrinsic_var_##N;
|
||||
case SpvOpAtomicLoad: return nir_intrinsic_load_deref;
|
||||
case SpvOpAtomicStore: return nir_intrinsic_store_deref;
|
||||
#define OP(S, N) case SpvOp##S: return nir_intrinsic_deref_##N;
|
||||
OP(AtomicExchange, atomic_exchange)
|
||||
OP(AtomicCompareExchange, atomic_comp_swap)
|
||||
OP(AtomicIIncrement, atomic_add)
|
||||
@@ -2584,11 +2584,11 @@ vtn_handle_ssbo_or_shared_atomic(struct vtn_builder *b, SpvOp opcode,
|
||||
|
||||
if (ptr->mode == vtn_variable_mode_workgroup &&
|
||||
!b->options->lower_workgroup_access_to_offsets) {
|
||||
nir_deref_var *deref = vtn_pointer_to_deref(b, ptr);
|
||||
const struct glsl_type *deref_type = nir_deref_tail(&deref->deref)->type;
|
||||
nir_intrinsic_op op = get_var_nir_atomic_op(b, opcode);
|
||||
nir_deref_instr *deref = vtn_pointer_to_deref(b, ptr);
|
||||
const struct glsl_type *deref_type = deref->type;
|
||||
nir_intrinsic_op op = get_deref_nir_atomic_op(b, opcode);
|
||||
atomic = nir_intrinsic_instr_create(b->nb.shader, op);
|
||||
atomic->variables[0] = nir_deref_var_clone(deref, atomic);
|
||||
atomic->src[0] = nir_src_for_ssa(&deref->dest.ssa);
|
||||
|
||||
switch (opcode) {
|
||||
case SpvOpAtomicLoad:
|
||||
@@ -2598,7 +2598,7 @@ vtn_handle_ssbo_or_shared_atomic(struct vtn_builder *b, SpvOp opcode,
|
||||
case SpvOpAtomicStore:
|
||||
atomic->num_components = glsl_get_vector_elements(deref_type);
|
||||
nir_intrinsic_set_write_mask(atomic, (1 << atomic->num_components) - 1);
|
||||
atomic->src[0] = nir_src_for_ssa(vtn_ssa_value(b, w[4])->def);
|
||||
atomic->src[1] = nir_src_for_ssa(vtn_ssa_value(b, w[4])->def);
|
||||
break;
|
||||
|
||||
case SpvOpAtomicExchange:
|
||||
@@ -2615,7 +2615,7 @@ vtn_handle_ssbo_or_shared_atomic(struct vtn_builder *b, SpvOp opcode,
|
||||
case SpvOpAtomicAnd:
|
||||
case SpvOpAtomicOr:
|
||||
case SpvOpAtomicXor:
|
||||
fill_common_atomic_sources(b, opcode, w, &atomic->src[0]);
|
||||
fill_common_atomic_sources(b, opcode, w, &atomic->src[1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -4137,6 +4137,11 @@ spirv_to_nir(const uint32_t *words, size_t word_count,
|
||||
}
|
||||
} while (progress);
|
||||
|
||||
/* We sometimes generate bogus derefs that, while never used, give the
|
||||
* validator a bit of heartburn. Run dead code to get rid of them.
|
||||
*/
|
||||
nir_opt_dce(b->shader);
|
||||
|
||||
vtn_assert(b->entry_point->value_type == vtn_value_type_function);
|
||||
nir_function *entry_point = b->entry_point->func->impl->function;
|
||||
vtn_assert(entry_point);
|
||||
|
Reference in New Issue
Block a user