From: Zack Rusin Date: Thu, 14 Mar 2013 07:42:06 +0000 (-0700) Subject: draw/gs: Abstract the portions of GS that are tgsi specific X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=014c4d1cd7f147d5365302d15bdb35d9e4b040d0;p=mesa.git draw/gs: Abstract the portions of GS that are tgsi specific To be able to add llvm paths later on we need to have some common interface for them. Signed-off-by: Zack Rusin Reviewed-by: Brian Paul Reviewed-by: José Fonseca --- diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c index e605965fd87..81d9140d2f4 100644 --- a/src/gallium/auxiliary/draw/draw_gs.c +++ b/src/gallium/auxiliary/draw/draw_gs.c @@ -42,112 +42,6 @@ /* 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); +} diff --git a/src/gallium/auxiliary/draw/draw_gs.h b/src/gallium/auxiliary/draw/draw_gs.h index 5d10d0dcd41..b17a4485b16 100644 --- a/src/gallium/auxiliary/draw/draw_gs.h +++ b/src/gallium/auxiliary/draw/draw_gs.h @@ -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); }; /*