mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 11:28:05 +02:00
zink: handle global and scratch vars
also delete cs pushconst since that was for clover and I don't care anymore Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19044>
This commit is contained in:
parent
19a74229c9
commit
ddc5c30489
2 changed files with 126 additions and 17 deletions
|
|
@ -89,6 +89,7 @@ struct ntv_context {
|
||||||
SpvId loop_break, loop_cont;
|
SpvId loop_break, loop_cont;
|
||||||
|
|
||||||
SpvId shared_block_var[5]; //8, 16, 32, unused, 64
|
SpvId shared_block_var[5]; //8, 16, 32, unused, 64
|
||||||
|
SpvId scratch_block_var[5]; //8, 16, 32, unused, 64
|
||||||
|
|
||||||
SpvId front_face_var, instance_id_var, vertex_id_var,
|
SpvId front_face_var, instance_id_var, vertex_id_var,
|
||||||
primitive_id_var, invocation_id_var, // geometry
|
primitive_id_var, invocation_id_var, // geometry
|
||||||
|
|
@ -500,6 +501,34 @@ get_glsl_type(struct ntv_context *ctx, const struct glsl_type *type)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
create_scratch_block(struct ntv_context *ctx, unsigned scratch_size, unsigned bit_size)
|
||||||
|
{
|
||||||
|
unsigned idx = bit_size >> 4;
|
||||||
|
SpvId type = spirv_builder_type_uint(&ctx->builder, bit_size);
|
||||||
|
unsigned block_size = scratch_size / (bit_size / 8);
|
||||||
|
assert(block_size);
|
||||||
|
SpvId array = spirv_builder_type_array(&ctx->builder, type, emit_uint_const(ctx, 32, block_size));
|
||||||
|
spirv_builder_emit_array_stride(&ctx->builder, array, bit_size / 8);
|
||||||
|
SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
|
||||||
|
SpvStorageClassPrivate,
|
||||||
|
array);
|
||||||
|
ctx->scratch_block_var[idx] = spirv_builder_emit_var(&ctx->builder, ptr_type, SpvStorageClassPrivate);
|
||||||
|
if (ctx->spirv_1_4_interfaces) {
|
||||||
|
assert(ctx->num_entry_ifaces < ARRAY_SIZE(ctx->entry_ifaces));
|
||||||
|
ctx->entry_ifaces[ctx->num_entry_ifaces++] = ctx->scratch_block_var[idx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static SpvId
|
||||||
|
get_scratch_block(struct ntv_context *ctx, unsigned bit_size)
|
||||||
|
{
|
||||||
|
unsigned idx = bit_size >> 4;
|
||||||
|
if (!ctx->scratch_block_var[idx])
|
||||||
|
create_scratch_block(ctx, ctx->nir->scratch_size, bit_size);
|
||||||
|
return ctx->scratch_block_var[idx];
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
create_shared_block(struct ntv_context *ctx, unsigned shared_size, unsigned bit_size)
|
create_shared_block(struct ntv_context *ctx, unsigned shared_size, unsigned bit_size)
|
||||||
{
|
{
|
||||||
|
|
@ -2519,6 +2548,59 @@ emit_store_shared(struct ntv_context *ctx, nir_intrinsic_instr *intr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emit_load_scratch(struct ntv_context *ctx, nir_intrinsic_instr *intr)
|
||||||
|
{
|
||||||
|
SpvId dest_type = get_dest_type(ctx, &intr->dest, nir_type_uint);
|
||||||
|
unsigned num_components = nir_dest_num_components(intr->dest);
|
||||||
|
unsigned bit_size = nir_dest_bit_size(intr->dest);
|
||||||
|
SpvId uint_type = get_uvec_type(ctx, bit_size, 1);
|
||||||
|
SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
|
||||||
|
SpvStorageClassPrivate,
|
||||||
|
uint_type);
|
||||||
|
SpvId offset = get_src(ctx, &intr->src[0]);
|
||||||
|
SpvId constituents[NIR_MAX_VEC_COMPONENTS];
|
||||||
|
SpvId scratch_block = get_scratch_block(ctx, bit_size);
|
||||||
|
/* need to convert array -> vec */
|
||||||
|
for (unsigned i = 0; i < num_components; i++) {
|
||||||
|
SpvId member = spirv_builder_emit_access_chain(&ctx->builder, ptr_type,
|
||||||
|
scratch_block, &offset, 1);
|
||||||
|
constituents[i] = spirv_builder_emit_load(&ctx->builder, uint_type, member);
|
||||||
|
offset = emit_binop(ctx, SpvOpIAdd, spirv_builder_type_uint(&ctx->builder, 32), offset, emit_uint_const(ctx, 32, 1));
|
||||||
|
}
|
||||||
|
SpvId result;
|
||||||
|
if (num_components > 1)
|
||||||
|
result = spirv_builder_emit_composite_construct(&ctx->builder, dest_type, constituents, num_components);
|
||||||
|
else
|
||||||
|
result = bitcast_to_uvec(ctx, constituents[0], bit_size, num_components);
|
||||||
|
store_dest(ctx, &intr->dest, result, nir_type_uint);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emit_store_scratch(struct ntv_context *ctx, nir_intrinsic_instr *intr)
|
||||||
|
{
|
||||||
|
SpvId src = get_src(ctx, &intr->src[0]);
|
||||||
|
|
||||||
|
unsigned wrmask = nir_intrinsic_write_mask(intr);
|
||||||
|
unsigned bit_size = nir_src_bit_size(intr->src[0]);
|
||||||
|
SpvId uint_type = get_uvec_type(ctx, bit_size, 1);
|
||||||
|
SpvId ptr_type = spirv_builder_type_pointer(&ctx->builder,
|
||||||
|
SpvStorageClassPrivate,
|
||||||
|
uint_type);
|
||||||
|
SpvId offset = get_src(ctx, &intr->src[1]);
|
||||||
|
SpvId scratch_block = get_scratch_block(ctx, bit_size);
|
||||||
|
/* this is a partial write, so we have to loop and do a per-component write */
|
||||||
|
u_foreach_bit(i, wrmask) {
|
||||||
|
SpvId scratch_offset = emit_binop(ctx, SpvOpIAdd, spirv_builder_type_uint(&ctx->builder, 32), offset, emit_uint_const(ctx, 32, i));
|
||||||
|
SpvId val = src;
|
||||||
|
if (nir_src_num_components(intr->src[0]) != 1)
|
||||||
|
val = spirv_builder_emit_composite_extract(&ctx->builder, uint_type, src, &i, 1);
|
||||||
|
SpvId member = spirv_builder_emit_access_chain(&ctx->builder, ptr_type,
|
||||||
|
scratch_block, &scratch_offset, 1);
|
||||||
|
spirv_builder_emit_store(&ctx->builder, member, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
emit_load_push_const(struct ntv_context *ctx, nir_intrinsic_instr *intr)
|
emit_load_push_const(struct ntv_context *ctx, nir_intrinsic_instr *intr)
|
||||||
{
|
{
|
||||||
|
|
@ -2572,6 +2654,33 @@ emit_load_push_const(struct ntv_context *ctx, nir_intrinsic_instr *intr)
|
||||||
store_dest(ctx, &intr->dest, result, nir_type_uint);
|
store_dest(ctx, &intr->dest, result, nir_type_uint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emit_load_global(struct ntv_context *ctx, nir_intrinsic_instr *intr)
|
||||||
|
{
|
||||||
|
spirv_builder_emit_cap(&ctx->builder, SpvCapabilityPhysicalStorageBufferAddresses);
|
||||||
|
SpvId dest_type = get_dest_type(ctx, &intr->dest, nir_type_uint);
|
||||||
|
SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
|
||||||
|
SpvStorageClassPhysicalStorageBuffer,
|
||||||
|
dest_type);
|
||||||
|
SpvId ptr = emit_bitcast(ctx, pointer_type, get_src(ctx, &intr->src[0]));
|
||||||
|
SpvId result = spirv_builder_emit_load(&ctx->builder, dest_type, ptr);
|
||||||
|
store_dest(ctx, &intr->dest, result, nir_type_uint);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emit_store_global(struct ntv_context *ctx, nir_intrinsic_instr *intr)
|
||||||
|
{
|
||||||
|
spirv_builder_emit_cap(&ctx->builder, SpvCapabilityPhysicalStorageBufferAddresses);
|
||||||
|
unsigned bit_size = nir_src_bit_size(intr->src[0]);
|
||||||
|
SpvId dest_type = get_uvec_type(ctx, bit_size, 1);
|
||||||
|
SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder,
|
||||||
|
SpvStorageClassPhysicalStorageBuffer,
|
||||||
|
dest_type);
|
||||||
|
SpvId param = get_src(ctx, &intr->src[0]);
|
||||||
|
SpvId ptr = emit_bitcast(ctx, pointer_type, get_src(ctx, &intr->src[1]));
|
||||||
|
spirv_builder_emit_store(&ctx->builder, ptr, param);
|
||||||
|
}
|
||||||
|
|
||||||
static SpvId
|
static SpvId
|
||||||
create_builtin_var(struct ntv_context *ctx, SpvId var_type,
|
create_builtin_var(struct ntv_context *ctx, SpvId var_type,
|
||||||
SpvStorageClass storage_class,
|
SpvStorageClass storage_class,
|
||||||
|
|
@ -3093,6 +3202,14 @@ emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
|
||||||
emit_load_push_const(ctx, intr);
|
emit_load_push_const(ctx, intr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case nir_intrinsic_load_global:
|
||||||
|
emit_load_global(ctx, intr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nir_intrinsic_store_global:
|
||||||
|
emit_store_global(ctx, intr);
|
||||||
|
break;
|
||||||
|
|
||||||
case nir_intrinsic_load_front_face:
|
case nir_intrinsic_load_front_face:
|
||||||
emit_load_front_face(ctx, intr);
|
emit_load_front_face(ctx, intr);
|
||||||
break;
|
break;
|
||||||
|
|
@ -3361,6 +3478,14 @@ emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
|
||||||
emit_store_shared(ctx, intr);
|
emit_store_shared(ctx, intr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case nir_intrinsic_load_scratch:
|
||||||
|
emit_load_scratch(ctx, intr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nir_intrinsic_store_scratch:
|
||||||
|
emit_store_scratch(ctx, intr);
|
||||||
|
break;
|
||||||
|
|
||||||
case nir_intrinsic_shader_clock:
|
case nir_intrinsic_shader_clock:
|
||||||
emit_shader_clock(ctx, intr);
|
emit_shader_clock(ctx, intr);
|
||||||
break;
|
break;
|
||||||
|
|
@ -4297,7 +4422,7 @@ nir_to_spirv(struct nir_shader *s, const struct zink_shader_info *sinfo, uint32_
|
||||||
if (s->info.cs.ptr_size == 32)
|
if (s->info.cs.ptr_size == 32)
|
||||||
model = SpvAddressingModelPhysical32;
|
model = SpvAddressingModelPhysical32;
|
||||||
else if (s->info.cs.ptr_size == 64)
|
else if (s->info.cs.ptr_size == 64)
|
||||||
model = SpvAddressingModelPhysical64;
|
model = SpvAddressingModelPhysicalStorageBuffer64;
|
||||||
else
|
else
|
||||||
model = SpvAddressingModelLogical;
|
model = SpvAddressingModelLogical;
|
||||||
spirv_builder_emit_mem_model(&ctx.builder, model,
|
spirv_builder_emit_mem_model(&ctx.builder, model,
|
||||||
|
|
|
||||||
|
|
@ -62,20 +62,6 @@ create_vs_pushconst(nir_shader *nir)
|
||||||
vs_pushconst->data.location = INT_MAX; //doesn't really matter
|
vs_pushconst->data.location = INT_MAX; //doesn't really matter
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
create_cs_pushconst(nir_shader *nir)
|
|
||||||
{
|
|
||||||
nir_variable *cs_pushconst;
|
|
||||||
/* create compatible layout for the ntv push constant loader */
|
|
||||||
struct glsl_struct_field *fields = rzalloc_size(nir, 1 * sizeof(struct glsl_struct_field));
|
|
||||||
fields[0].type = glsl_array_type(glsl_uint_type(), 1, 0);
|
|
||||||
fields[0].name = ralloc_asprintf(nir, "work_dim");
|
|
||||||
fields[0].offset = 0;
|
|
||||||
cs_pushconst = nir_variable_create(nir, nir_var_mem_push_const,
|
|
||||||
glsl_struct_type(fields, 1, "struct", false), "cs_pushconst");
|
|
||||||
cs_pushconst->data.location = INT_MAX; //doesn't really matter
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
reads_work_dim(nir_shader *shader)
|
reads_work_dim(nir_shader *shader)
|
||||||
{
|
{
|
||||||
|
|
@ -3155,8 +3141,6 @@ zink_shader_create(struct zink_screen *screen, struct nir_shader *nir,
|
||||||
else if (nir->info.stage == MESA_SHADER_TESS_CTRL ||
|
else if (nir->info.stage == MESA_SHADER_TESS_CTRL ||
|
||||||
nir->info.stage == MESA_SHADER_TESS_EVAL)
|
nir->info.stage == MESA_SHADER_TESS_EVAL)
|
||||||
NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, false);
|
NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, false);
|
||||||
else if (nir->info.stage == MESA_SHADER_KERNEL)
|
|
||||||
create_cs_pushconst(nir);
|
|
||||||
|
|
||||||
if (nir->info.stage < MESA_SHADER_FRAGMENT)
|
if (nir->info.stage < MESA_SHADER_FRAGMENT)
|
||||||
have_psiz = check_psiz(nir);
|
have_psiz = check_psiz(nir);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue