draw/gs: Abstract the portions of GS that are tgsi specific
authorZack Rusin <zackr@vmware.com>
Thu, 14 Mar 2013 07:42:06 +0000 (00:42 -0700)
committerZack Rusin <zackr@vmware.com>
Wed, 27 Mar 2013 10:53:01 +0000 (03:53 -0700)
To be able to add llvm paths later on we need to have some common
interface for them.

Signed-off-by: Zack Rusin <zackr@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: José Fonseca <jfonseca@vmware.com>
src/gallium/auxiliary/draw/draw_gs.c
src/gallium/auxiliary/draw/draw_gs.h

index e605965fd87c4ba53f80f47f019ed11bf111c22d..81d9140d2f40587be464b2007a59e00985fd6206 100644 (file)
 /* fixme: move it from here */
 #define MAX_PRIMITIVES 64
 
-boolean
-draw_gs_init( struct draw_context *draw )
-{
-   draw->gs.tgsi.machine = tgsi_exec_machine_create();
-   if (!draw->gs.tgsi.machine)
-      return FALSE;
-
-   draw->gs.tgsi.machine->Primitives = align_malloc(
-      MAX_PRIMITIVES * sizeof(struct tgsi_exec_vector), 16);
-   if (!draw->gs.tgsi.machine->Primitives)
-      return FALSE;
-   memset(draw->gs.tgsi.machine->Primitives, 0,
-          MAX_PRIMITIVES * sizeof(struct tgsi_exec_vector));
-
-   return TRUE;
-}
-
-void draw_gs_destroy( struct draw_context *draw )
-{
-   if (!draw->gs.tgsi.machine)
-      return;
-
-   align_free(draw->gs.tgsi.machine->Primitives);
-
-   tgsi_exec_machine_destroy(draw->gs.tgsi.machine);
-}
-
-struct draw_geometry_shader *
-draw_create_geometry_shader(struct draw_context *draw,
-                            const struct pipe_shader_state *state)
-{
-   struct draw_geometry_shader *gs;
-   unsigned i;
-
-   gs = CALLOC_STRUCT(draw_geometry_shader);
-
-   if (!gs)
-      return NULL;
-
-   gs->draw = draw;
-   gs->state = *state;
-   gs->state.tokens = tgsi_dup_tokens(state->tokens);
-   if (!gs->state.tokens) {
-      FREE(gs);
-      return NULL;
-   }
-
-   tgsi_scan_shader(state->tokens, &gs->info);
-
-   /* setup the defaults */
-   gs->input_primitive = PIPE_PRIM_TRIANGLES;
-   gs->output_primitive = PIPE_PRIM_TRIANGLE_STRIP;
-   gs->max_output_vertices = 32;
-
-   for (i = 0; i < gs->info.num_properties; ++i) {
-      if (gs->info.properties[i].name ==
-          TGSI_PROPERTY_GS_INPUT_PRIM)
-         gs->input_primitive = gs->info.properties[i].data[0];
-      else if (gs->info.properties[i].name ==
-               TGSI_PROPERTY_GS_OUTPUT_PRIM)
-         gs->output_primitive = gs->info.properties[i].data[0];
-      else if (gs->info.properties[i].name ==
-               TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES)
-         gs->max_output_vertices = gs->info.properties[i].data[0];
-   }
-
-   gs->machine = draw->gs.tgsi.machine;
-
-   if (gs)
-   {
-      uint i;
-      for (i = 0; i < gs->info.num_outputs; i++) {
-         if (gs->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION &&
-             gs->info.output_semantic_index[i] == 0)
-            gs->position_output = i;
-      }
-   }
-
-   return gs;
-}
-
-void draw_bind_geometry_shader(struct draw_context *draw,
-                               struct draw_geometry_shader *dgs)
-{
-   draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
-
-   if (dgs) {
-      draw->gs.geometry_shader = dgs;
-      draw->gs.num_gs_outputs = dgs->info.num_outputs;
-      draw->gs.position_output = dgs->position_output;
-      draw_geometry_shader_prepare(dgs, draw);
-   }
-   else {
-      draw->gs.geometry_shader = NULL;
-      draw->gs.num_gs_outputs = 0;
-   }
-}
-
-void draw_delete_geometry_shader(struct draw_context *draw,
-                                 struct draw_geometry_shader *dgs)
-{
-   FREE(dgs->primitive_lengths);
-   FREE((void*) dgs->state.tokens);
-   FREE(dgs);
-}
-
 static INLINE int
 draw_gs_get_input_index(int semantic, int index,
                         const struct tgsi_shader_info *input_info)
@@ -165,10 +59,10 @@ draw_gs_get_input_index(int semantic, int index,
 }
 
 /*#define DEBUG_OUTPUTS 1*/
-static INLINE void
-draw_geometry_fetch_outputs(struct draw_geometry_shader *shader,
-                            unsigned num_primitives,
-                            float (**p_output)[4])
+static void
+tgsi_fetch_gs_outputs(struct draw_geometry_shader *shader,
+                      unsigned num_primitives,
+                      float (**p_output)[4])
 {
    struct tgsi_exec_machine *machine = shader->machine;
    unsigned prim_idx, j, slot;
@@ -212,7 +106,7 @@ draw_geometry_fetch_outputs(struct draw_geometry_shader *shader,
 }
 
 /*#define DEBUG_INPUTS 1*/
-static void draw_fetch_gs_input(struct draw_geometry_shader *shader,
+static void tgsi_fetch_gs_input(struct draw_geometry_shader *shader,
                                 unsigned *indices,
                                 unsigned num_vertices,
                                 unsigned prim_idx)
@@ -275,14 +169,20 @@ static void draw_fetch_gs_input(struct draw_geometry_shader *shader,
    }
 }
 
-static void gs_flush(struct draw_geometry_shader *shader,
-                     unsigned input_primitives)
+static void tgsi_gs_prepare(struct draw_geometry_shader *shader,
+                            const void *constants[PIPE_MAX_CONSTANT_BUFFERS], 
+                            const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS])
 {
-   unsigned out_prim_count;
    struct tgsi_exec_machine *machine = shader->machine;
 
-   debug_assert(input_primitives > 0 &&
-                input_primitives < 4);
+   tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS,
+                                  constants, constants_size);
+}
+
+static unsigned tgsi_gs_run(struct draw_geometry_shader *shader,
+                            unsigned input_primitives)
+{
+   struct tgsi_exec_machine *machine = shader->machine;
 
    tgsi_set_exec_mask(machine,
                       1,
@@ -293,16 +193,26 @@ static void gs_flush(struct draw_geometry_shader *shader,
    /* run interpreter */
    tgsi_exec_machine_run(machine);
 
-   out_prim_count =
+   return 
       machine->Temps[TGSI_EXEC_TEMP_PRIMITIVE_I].xyzw[TGSI_EXEC_TEMP_PRIMITIVE_C].u[0];
+}
+
+static void gs_flush(struct draw_geometry_shader *shader,
+                     unsigned input_primitives)
+{
+   unsigned out_prim_count;
+
+   debug_assert(input_primitives > 0 &&
+                input_primitives < 4);
 
+   out_prim_count = shader->run(shader, input_primitives);
 #if 0
    debug_printf("PRIM emitted prims = %d (verts=%d), cur prim count = %d\n",
                 shader->emitted_primitives, shader->emitted_vertices,
                 out_prim_count);
 #endif
-   draw_geometry_fetch_outputs(shader, out_prim_count,
-                               &shader->tmp_output);
+   shader->fetch_outputs(shader, out_prim_count,
+                         &shader->tmp_output);
 }
 
 static void gs_point(struct draw_geometry_shader *shader,
@@ -312,7 +222,7 @@ static void gs_point(struct draw_geometry_shader *shader,
 
    indices[0] = idx;
 
-   draw_fetch_gs_input(shader, indices, 1, 0);
+   shader->fetch_inputs(shader, indices, 1, 0);
    ++shader->in_prim_idx;
 
    gs_flush(shader, 1);
@@ -326,7 +236,7 @@ static void gs_line(struct draw_geometry_shader *shader,
    indices[0] = i0;
    indices[1] = i1;
 
-   draw_fetch_gs_input(shader, indices, 2, 0);
+   shader->fetch_inputs(shader, indices, 2, 0);
    ++shader->in_prim_idx;
 
    gs_flush(shader, 1);
@@ -342,7 +252,7 @@ static void gs_line_adj(struct draw_geometry_shader *shader,
    indices[2] = i2;
    indices[3] = i3;
 
-   draw_fetch_gs_input(shader, indices, 4, 0);
+   shader->fetch_inputs(shader, indices, 4, 0);
    ++shader->in_prim_idx;
 
    gs_flush(shader, 1);
@@ -357,7 +267,7 @@ static void gs_tri(struct draw_geometry_shader *shader,
    indices[1] = i1;
    indices[2] = i2;
 
-   draw_fetch_gs_input(shader, indices, 3, 0);
+   shader->fetch_inputs(shader, indices, 3, 0);
    ++shader->in_prim_idx;
 
    gs_flush(shader, 1);
@@ -376,7 +286,7 @@ static void gs_tri_adj(struct draw_geometry_shader *shader,
    indices[4] = i4;
    indices[5] = i5;
 
-   draw_fetch_gs_input(shader, indices, 6, 0);
+   shader->fetch_inputs(shader, indices, 6, 0);
    ++shader->in_prim_idx;
 
    gs_flush(shader, 1);
@@ -394,7 +304,7 @@ static void gs_tri_adj(struct draw_geometry_shader *shader,
 
 
 /**
- * Execute geometry shader using TGSI interpreter.
+ * Execute geometry shader.
  */
 int draw_geometry_shader_run(struct draw_geometry_shader *shader,
                              const void *constants[PIPE_MAX_CONSTANT_BUFFERS], 
@@ -409,7 +319,6 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
    unsigned input_stride = input_verts->vertex_size;
    unsigned num_outputs = shader->info.num_outputs;
    unsigned vertex_size = sizeof(struct vertex_header) + num_outputs * 4 * sizeof(float);
-   struct tgsi_exec_machine *machine = shader->machine;
    unsigned num_input_verts = input_prim->linear ?
                               input_verts->count :
                               input_prim->count;
@@ -451,8 +360,7 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader,
    FREE(shader->primitive_lengths);
    shader->primitive_lengths = MALLOC(max_out_prims * sizeof(unsigned));
 
-   tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS,
-                                  constants, constants_size);
+   shader->prepare(shader, constants, constants_size);
 
    if (input_prim->linear)
       gs_run(shader, input_prim, input_verts,
@@ -491,3 +399,109 @@ void draw_geometry_shader_prepare(struct draw_geometry_shader *shader,
                                     draw->gs.tgsi.sampler);
    }
 }
+
+
+boolean
+draw_gs_init( struct draw_context *draw )
+{
+   draw->gs.tgsi.machine = tgsi_exec_machine_create();
+   if (!draw->gs.tgsi.machine)
+      return FALSE;
+
+   draw->gs.tgsi.machine->Primitives = align_malloc(
+      MAX_PRIMITIVES * sizeof(struct tgsi_exec_vector), 16);
+   if (!draw->gs.tgsi.machine->Primitives)
+      return FALSE;
+   memset(draw->gs.tgsi.machine->Primitives, 0,
+          MAX_PRIMITIVES * sizeof(struct tgsi_exec_vector));
+
+   return TRUE;
+}
+
+void draw_gs_destroy( struct draw_context *draw )
+{
+   if (draw->gs.tgsi.machine) {
+      align_free(draw->gs.tgsi.machine->Primitives);
+      tgsi_exec_machine_destroy(draw->gs.tgsi.machine);
+   }
+}
+
+struct draw_geometry_shader *
+draw_create_geometry_shader(struct draw_context *draw,
+                            const struct pipe_shader_state *state)
+{
+   struct draw_geometry_shader *gs;
+   unsigned i;
+
+   gs = CALLOC_STRUCT(draw_geometry_shader);
+
+   if (!gs)
+      return NULL;
+
+   gs->draw = draw;
+   gs->state = *state;
+   gs->state.tokens = tgsi_dup_tokens(state->tokens);
+   if (!gs->state.tokens) {
+      FREE(gs);
+      return NULL;
+   }
+
+   tgsi_scan_shader(state->tokens, &gs->info);
+
+   /* setup the defaults */
+   gs->input_primitive = PIPE_PRIM_TRIANGLES;
+   gs->output_primitive = PIPE_PRIM_TRIANGLE_STRIP;
+   gs->max_output_vertices = 32;
+
+   for (i = 0; i < gs->info.num_properties; ++i) {
+      if (gs->info.properties[i].name ==
+          TGSI_PROPERTY_GS_INPUT_PRIM)
+         gs->input_primitive = gs->info.properties[i].data[0];
+      else if (gs->info.properties[i].name ==
+               TGSI_PROPERTY_GS_OUTPUT_PRIM)
+         gs->output_primitive = gs->info.properties[i].data[0];
+      else if (gs->info.properties[i].name ==
+               TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES)
+         gs->max_output_vertices = gs->info.properties[i].data[0];
+   }
+
+   for (i = 0; i < gs->info.num_outputs; i++) {
+      if (gs->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION &&
+          gs->info.output_semantic_index[i] == 0)
+         gs->position_output = i;
+   }
+
+   gs->machine = draw->gs.tgsi.machine;
+
+   gs->fetch_outputs = tgsi_fetch_gs_outputs;
+   gs->fetch_inputs = tgsi_fetch_gs_input;
+   gs->prepare = tgsi_gs_prepare;
+   gs->run = tgsi_gs_run;
+
+   return gs;
+}
+
+void draw_bind_geometry_shader(struct draw_context *draw,
+                               struct draw_geometry_shader *dgs)
+{
+   draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
+
+   if (dgs) {
+      draw->gs.geometry_shader = dgs;
+      draw->gs.num_gs_outputs = dgs->info.num_outputs;
+      draw->gs.position_output = dgs->position_output;
+      draw_geometry_shader_prepare(dgs, draw);
+   }
+   else {
+      draw->gs.geometry_shader = NULL;
+      draw->gs.num_gs_outputs = 0;
+   }
+}
+
+void draw_delete_geometry_shader(struct draw_context *draw,
+                                 struct draw_geometry_shader *dgs)
+{
+   FREE(dgs->primitive_lengths);
+   FREE((void*) dgs->state.tokens);
+   FREE(dgs);
+}
index 5d10d0dcd411fce151b1255b6dfcd4ad725edba4..b17a4485b16d5733bfd3ff7b586a870861a229b9 100644 (file)
@@ -65,6 +65,20 @@ struct draw_geometry_shader {
    unsigned input_vertex_stride;
    const float (*input)[4];
    const struct tgsi_shader_info *input_info;
+
+   void (*fetch_inputs)(struct draw_geometry_shader *shader,
+                        unsigned *indices,
+                        unsigned num_vertices,
+                        unsigned prim_idx);
+   void (*fetch_outputs)(struct draw_geometry_shader *shader,
+                         unsigned num_primitives,
+                         float (**p_output)[4]);
+
+   void     (*prepare)(struct draw_geometry_shader *shader,
+                       const void *constants[PIPE_MAX_CONSTANT_BUFFERS], 
+                       const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS]);
+   unsigned (*run)(struct draw_geometry_shader *shader,
+                   unsigned input_primitives);
 };
 
 /*