v3d: implement geometry shader instancing
authorIago Toral Quiroga <itoral@igalia.com>
Thu, 3 Oct 2019 15:08:47 +0000 (17:08 +0200)
committerIago Toral Quiroga <itoral@igalia.com>
Mon, 16 Dec 2019 07:42:37 +0000 (08:42 +0100)
v2:
 - Remove unused field uses_iid from v3d_gs_prog_data (Alejandro)

Reviewed-by: Alejandro PiƱeiro <apinheiro@igalia.com>
src/broadcom/compiler/nir_to_vir.c
src/broadcom/compiler/v3d_compiler.h
src/broadcom/compiler/vir.c
src/gallium/drivers/v3d/v3dx_draw.c

index d7bef12fef91320e5e55f1350e522ba22466db67..d49640bf62378b6435371ec80e77a4f8ed871e32 100644 (file)
@@ -2327,6 +2327,10 @@ ntq_emit_intrinsic(struct v3d_compile *c, nir_intrinsic_instr *instr)
                 break;
         }
 
+        case nir_intrinsic_load_invocation_id:
+                ntq_store_dest(c, &instr->dest, 0, vir_IID(c));
+                break;
+
         default:
                 fprintf(stderr, "Unknown intrinsic: ");
                 nir_print_instr(&instr->instr, stderr);
index 9b08e4a270e4678c0b310080ee3a3325336369f9..a5b4748aaf0c6751ad51d4aee3d75474c0dcf147 100644 (file)
@@ -718,6 +718,9 @@ struct v3d_gs_prog_data {
 
         /* Output primitive type */
         uint8_t out_prim_type;
+
+        /* Number of GS invocations */
+        uint8_t num_invocations;
 };
 
 struct v3d_fs_prog_data {
@@ -1037,6 +1040,7 @@ VIR_A_ALU2(LDVPMG_IN)
 VIR_A_ALU2(LDVPMG_OUT)
 VIR_A_ALU0(TMUWT)
 
+VIR_A_ALU0(IID)
 VIR_A_ALU0(FXCD)
 VIR_A_ALU0(XCD)
 VIR_A_ALU0(FYCD)
index dc966bc80ca3a8f655b266391bfea17c7a199406..4f88b86a5d20c224bfdd9d1649ca7bafddf54e72 100644 (file)
@@ -681,6 +681,7 @@ v3d_gs_set_prog_data(struct v3d_compile *c,
         prog_data->vpm_output_size = align(c->vpm_output_size, 8) / 8;
 
         prog_data->out_prim_type = c->s->info.gs.output_primitive;
+        prog_data->num_invocations = c->s->info.gs.invocations;
 }
 
 static void
index d582c6538191ebc45abb8c7559d181cbadd10716..07d2749a87a0ffeef63dd496e9c054b08e4981c4 100644 (file)
@@ -377,7 +377,8 @@ v3d_gs_output_primitive(uint32_t prim_type)
 
 static void
 v3d_emit_tes_gs_common_params(struct v3d_job *job,
-                              uint8_t gs_out_prim_type)
+                              uint8_t gs_out_prim_type,
+                              uint8_t gs_num_invocations)
 {
         /* This, and v3d_emit_tes_gs_shader_params below, fill in default
          * values for tessellation fields even though we don't support
@@ -393,7 +394,7 @@ v3d_emit_tes_gs_common_params(struct v3d_job *job,
 
                 shader.geometry_shader_output_format =
                         v3d_gs_output_primitive(gs_out_prim_type);
-                shader.geometry_shader_instances = 1; /* FIXME */
+                shader.geometry_shader_instances = gs_num_invocations & 0x1F;
         }
 }
 
@@ -506,7 +507,9 @@ v3d_emit_gl_shader_state(struct v3d_context *v3d,
             struct v3d_gs_prog_data *gs = v3d->prog.gs->prog_data.gs;
             struct v3d_gs_prog_data *gs_bin = v3d->prog.gs_bin->prog_data.gs;
 
-            v3d_emit_tes_gs_common_params(v3d->job, gs->out_prim_type);
+            v3d_emit_tes_gs_common_params(v3d->job,
+                                          gs->out_prim_type,
+                                          gs->num_invocations);
             v3d_emit_tes_gs_shader_params(v3d->job, gs_bin);
             v3d_emit_tes_gs_shader_params(v3d->job, gs);
         }