#include <inttypes.h>
#include "util/format/u_format.h"
+#include "util/u_helpers.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/ralloc.h"
}
}
-static bool
-var_needs_point_coord(struct v3d_compile *c, nir_variable *var)
-{
- return (var->data.location == VARYING_SLOT_PNTC ||
- (var->data.location >= VARYING_SLOT_VAR0 &&
- (c->fs_key->point_sprite_mask &
- (1 << (var->data.location - VARYING_SLOT_VAR0)))));
-}
-
static bool
program_reads_point_coord(struct v3d_compile *c)
{
nir_foreach_variable(var, &c->s->inputs) {
- if (var_needs_point_coord(c, var))
+ if (util_varying_is_point_coord(var->data.location,
+ c->fs_key->point_sprite_mask)) {
return true;
+ }
}
return false;
if (var->data.location == VARYING_SLOT_POS) {
emit_fragcoord_input(c, loc);
- } else if (var_needs_point_coord(c, var)) {
+ } else if (util_varying_is_point_coord(var->data.location,
+ c->fs_key->point_sprite_mask)) {
c->inputs[loc * 4 + 0] = c->point_x;
c->inputs[loc * 4 + 1] = c->point_y;
} else {
static void
ntq_emit_image_size(struct v3d_compile *c, nir_intrinsic_instr *instr)
{
- assert(instr->intrinsic == nir_intrinsic_image_deref_size);
- nir_variable *var = nir_intrinsic_get_var(instr, 0);
- unsigned image_index = var->data.driver_location;
- const struct glsl_type *sampler_type = glsl_without_array(var->type);
- bool is_array = glsl_sampler_type_is_array(sampler_type);
+ unsigned image_index = nir_src_as_uint(instr->src[0]);
+ bool is_array = nir_intrinsic_image_array(instr);
ntq_store_dest(c, &instr->dest, 0,
vir_uniform(c, QUNIFORM_IMAGE_WIDTH, image_index));
V3D_QPU_PF_PUSHZ);
}
- vir_VPM_WRITE_indirect(c, ntq_get_src(c, instr->src[0], 0), offset);
+ struct qreg val = ntq_get_src(c, instr->src[0], 0);
+
+ /* The offset isn’t necessarily dynamically uniform for a geometry
+ * shader. This can happen if the shader sometimes doesn’t emit one of
+ * the vertices. In that case subsequent vertices will be written to
+ * different offsets in the VPM and we need to use the scatter write
+ * instruction to have a different offset for each lane.
+ */
+ if (nir_src_is_dynamically_uniform(instr->src[1]))
+ vir_VPM_WRITE_indirect(c, val, offset);
+ else
+ vir_STVPMD(c, offset, val);
if (vir_in_nonuniform_control_flow(c)) {
struct qinst *last_inst =
ntq_emit_tmu_general(c, instr, true);
break;
- case nir_intrinsic_image_deref_load:
- case nir_intrinsic_image_deref_store:
- case nir_intrinsic_image_deref_atomic_add:
- case nir_intrinsic_image_deref_atomic_imin:
- case nir_intrinsic_image_deref_atomic_umin:
- case nir_intrinsic_image_deref_atomic_imax:
- case nir_intrinsic_image_deref_atomic_umax:
- case nir_intrinsic_image_deref_atomic_and:
- case nir_intrinsic_image_deref_atomic_or:
- case nir_intrinsic_image_deref_atomic_xor:
- case nir_intrinsic_image_deref_atomic_exchange:
- case nir_intrinsic_image_deref_atomic_comp_swap:
+ case nir_intrinsic_image_load:
+ case nir_intrinsic_image_store:
+ case nir_intrinsic_image_atomic_add:
+ case nir_intrinsic_image_atomic_imin:
+ case nir_intrinsic_image_atomic_umin:
+ case nir_intrinsic_image_atomic_imax:
+ case nir_intrinsic_image_atomic_umax:
+ case nir_intrinsic_image_atomic_and:
+ case nir_intrinsic_image_atomic_or:
+ case nir_intrinsic_image_atomic_xor:
+ case nir_intrinsic_image_atomic_exchange:
+ case nir_intrinsic_image_atomic_comp_swap:
v3d40_vir_emit_image_load_store(c, instr);
break;
break;
case nir_intrinsic_load_user_clip_plane:
- for (int i = 0; i < instr->num_components; i++) {
+ for (int i = 0; i < nir_intrinsic_dest_components(instr); i++) {
ntq_store_dest(c, &instr->dest, i,
vir_uniform(c, QUNIFORM_USER_CLIP_PLANE,
nir_intrinsic_ucp_id(instr) *
ntq_emit_store_output(c, instr);
break;
- case nir_intrinsic_image_deref_size:
+ case nir_intrinsic_image_size:
ntq_emit_image_size(c, instr);
break;
}
case nir_intrinsic_memory_barrier:
- case nir_intrinsic_memory_barrier_atomic_counter:
case nir_intrinsic_memory_barrier_buffer:
case nir_intrinsic_memory_barrier_image:
case nir_intrinsic_memory_barrier_shared:
ntq_emit_instr(struct v3d_compile *c, nir_instr *instr)
{
switch (instr->type) {
- case nir_instr_type_deref:
- /* ignored, will be walked by the intrinsic using it. */
- break;
-
case nir_instr_type_alu:
ntq_emit_alu(c, nir_instr_as_alu(instr));
break;