/* 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)
}
/*#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;
}
/*#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)
}
}
-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,
/* 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,
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);
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);
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);
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);
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);
/**
- * 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],
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;
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,
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);
+}