nir_ssa_def_rewrite_uses(&alu->dest.dest.ssa, nir_src_for_ssa(sum));
}
+/* TODO: ssbo_size */
static int
midgard_sysval_for_ssbo(nir_intrinsic_instr *instr)
{
- /* This is way too meta */
- bool is_store = instr->intrinsic == nir_intrinsic_store_ssbo;
- unsigned idx_idx = is_store ? 1 : 0;
-
- nir_src index = instr->src[idx_idx];
+ nir_src index = instr->src[0];
assert(nir_src_is_const(index));
uint32_t uindex = nir_src_as_uint(index);
return PAN_SYSVAL(SAMPLER, uindex);
}
-static int
+static unsigned
midgard_nir_sysval_for_intrinsic(nir_intrinsic_instr *instr)
{
switch (instr->intrinsic) {
return PAN_SYSVAL_VIEWPORT_OFFSET;
case nir_intrinsic_load_num_work_groups:
return PAN_SYSVAL_NUM_WORK_GROUPS;
- case nir_intrinsic_load_ssbo:
- case nir_intrinsic_store_ssbo:
+ case nir_intrinsic_load_ssbo_address:
return midgard_sysval_for_ssbo(instr);
case nir_intrinsic_load_sampler_lod_parameters_pan:
return midgard_sysval_for_sampler(instr);
nir_intrinsic_instr *intr;
nir_dest *dst = NULL;
nir_tex_instr *tex;
- int sysval = -1;
-
- bool is_store = false;
+ unsigned sysval = ~0;
switch (instr->type) {
case nir_instr_type_intrinsic:
intr = nir_instr_as_intrinsic(instr);
sysval = midgard_nir_sysval_for_intrinsic(intr);
dst = &intr->dest;
- is_store |= intr->intrinsic == nir_intrinsic_store_ssbo;
break;
case nir_instr_type_tex:
tex = nir_instr_as_tex(instr);
break;
}
- if (dest && dst && !is_store)
+ if (dest && dst)
*dest = nir_dest_index(ctx, dst);
return sysval;
/* SSBO reads are like UBO reads if you squint */
static void
-emit_ssbo_access(
+emit_global(
compiler_context *ctx,
nir_instr *instr,
bool is_read,
unsigned srcdest,
- unsigned offset,
- nir_src *indirect_offset,
- unsigned index)
+ nir_src *indirect_offset)
{
/* TODO: types */
midgard_instruction ins;
if (is_read)
- ins = m_ld_int4(srcdest, offset);
+ ins = m_ld_int4(srcdest, 0);
else
- ins = m_st_int4(srcdest, offset);
-
- /* SSBO reads use a generic memory read interface, so we need the
- * address of the SSBO as the first argument. This is a sysval. */
-
- unsigned addr = make_compiler_temp(ctx);
- emit_sysval_read(ctx, instr, addr, 2);
+ ins = m_st_int4(srcdest, 0);
/* The source array:
*
* arg_2 = the offset.
*/
- ins.src[1] = addr;
-
- /* TODO: What is this? It looks superficially like a shift << 5, but
- * arg_1 doesn't take a shift Should it be E0 or A0? We also need the
- * indirect offset. */
-
- if (indirect_offset) {
- ins.load_store.arg_1 |= 0xE0;
- ins.src[2] = nir_src_index(ctx, indirect_offset);
- } else {
- ins.load_store.arg_2 = 0x7E;
- }
-
- /* TODO: Bounds check */
-
- /* Finally, we emit the direct offset */
-
- ins.load_store.varying_parameters = (offset & 0x1FF) << 1;
- ins.load_store.address = (offset >> 9);
+ /* TODO: What is this? */
+ ins.load_store.arg_1 = 0x7E;
+ ins.src[2] = nir_src_index(ctx, indirect_offset);
mir_set_intr_mask(instr, &ins, is_read);
emit_mir_instruction(ctx, ins);
case nir_intrinsic_load_uniform:
case nir_intrinsic_load_ubo:
- case nir_intrinsic_load_ssbo:
+ case nir_intrinsic_load_global:
case nir_intrinsic_load_input:
case nir_intrinsic_load_interpolated_input: {
bool is_uniform = instr->intrinsic == nir_intrinsic_load_uniform;
bool is_ubo = instr->intrinsic == nir_intrinsic_load_ubo;
- bool is_ssbo = instr->intrinsic == nir_intrinsic_load_ssbo;
+ bool is_global = instr->intrinsic == nir_intrinsic_load_global;
bool is_flat = instr->intrinsic == nir_intrinsic_load_input;
bool is_interp = instr->intrinsic == nir_intrinsic_load_interpolated_input;
/* Get the base type of the intrinsic */
/* TODO: Infer type? Does it matter? */
nir_alu_type t =
- (is_ubo || is_ssbo) ? nir_type_uint :
+ (is_ubo || is_global) ? nir_type_uint :
(is_interp) ? nir_type_float :
nir_intrinsic_type(instr);
t = nir_alu_type_get_base_type(t);
- if (!(is_ubo || is_ssbo)) {
+ if (!(is_ubo || is_global)) {
offset = nir_intrinsic_base(instr);
}
uint32_t uindex = nir_src_as_uint(index) + 1;
emit_ubo_read(ctx, &instr->instr, reg, offset, indirect_offset, 0, uindex);
- } else if (is_ssbo) {
- nir_src index = instr->src[0];
- assert(nir_src_is_const(index));
- uint32_t uindex = nir_src_as_uint(index);
-
- emit_ssbo_access(ctx, &instr->instr, true, reg, offset, indirect_offset, uindex);
+ } else if (is_global) {
+ emit_global(ctx, &instr->instr, true, reg, indirect_offset);
} else if (ctx->stage == MESA_SHADER_FRAGMENT && !ctx->is_blend) {
emit_varying_read(ctx, reg, offset, nr_comp, component, indirect_offset, t, is_flat);
} else if (ctx->is_blend) {
break;
- case nir_intrinsic_store_ssbo:
- assert(nir_src_is_const(instr->src[1]));
-
- bool direct_offset = nir_src_is_const(instr->src[2]);
- offset = direct_offset ? nir_src_as_uint(instr->src[2]) : 0;
- nir_src *indirect_offset = direct_offset ? NULL : &instr->src[2];
+ case nir_intrinsic_store_global:
reg = nir_src_index(ctx, &instr->src[0]);
-
- uint32_t uindex = nir_src_as_uint(instr->src[1]);
-
emit_explicit_constant(ctx, reg, reg);
- emit_ssbo_access(ctx, &instr->instr, false, reg, offset, indirect_offset, uindex);
+ emit_global(ctx, &instr->instr, false, reg, &instr->src[1]);
break;
+ case nir_intrinsic_load_ssbo_address:
+ emit_sysval_read(ctx, &instr->instr, ~0, 1);
+ break;
+
case nir_intrinsic_load_viewport_scale:
case nir_intrinsic_load_viewport_offset:
case nir_intrinsic_load_num_work_groups:
NIR_PASS_V(nir, nir_lower_vars_to_ssa);
NIR_PASS_V(nir, nir_lower_io, nir_var_all, glsl_type_size, 0);
+ NIR_PASS_V(nir, nir_lower_ssbo);
NIR_PASS_V(nir, midgard_nir_lower_zs_store);
/* Optimisation passes */