diff options
Diffstat (limited to 'src/gallium/auxiliary/draw/draw_gs.c')
-rw-r--r-- | src/gallium/auxiliary/draw/draw_gs.c | 200 |
1 files changed, 141 insertions, 59 deletions
diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c index a1ca7071e3..79a57a67f3 100644 --- a/src/gallium/auxiliary/draw/draw_gs.c +++ b/src/gallium/auxiliary/draw/draw_gs.c @@ -39,7 +39,6 @@ #include "util/u_memory.h" #include "util/u_prim.h" -#define MAX_PRIM_VERTICES 6 /* fixme: move it from here */ #define MAX_PRIMITIVES 64 @@ -76,6 +75,7 @@ draw_gs_set_constants(struct draw_context *draw, const void *constants, unsigned size) { + /* noop */ } @@ -171,9 +171,10 @@ draw_geometry_fetch_outputs(struct draw_geometry_shader *shader, /* Unswizzle all output results. */ - shader->emitted_primitives += num_primitives; for (prim_idx = 0; prim_idx < num_primitives; ++prim_idx) { unsigned num_verts_per_prim = machine->Primitives[prim_idx]; + shader->primitive_lengths[prim_idx + shader->emitted_primitives] = + machine->Primitives[prim_idx]; shader->emitted_vertices += num_verts_per_prim; for (j = 0; j < num_verts_per_prim; j++) { int idx = (prim_idx * num_verts_per_prim + j) * @@ -199,9 +200,10 @@ draw_geometry_fetch_outputs(struct draw_geometry_shader *shader, } } *p_output = output; + shader->emitted_primitives += num_primitives; } - +/*#define DEBUG_INPUTS 1*/ static void draw_fetch_gs_input(struct draw_geometry_shader *shader, unsigned *indices, unsigned num_vertices, @@ -216,19 +218,28 @@ static void draw_fetch_gs_input(struct draw_geometry_shader *shader, for (i = 0; i < num_vertices; ++i) { const float (*input)[4]; - /*debug_printf("%d) vertex index = %d (prim idx = %d)\n", i, indices[i], prim_idx);*/ +#if DEBUG_INPUTS + debug_printf("%d) vertex index = %d (prim idx = %d)\n", + i, indices[i], prim_idx); +#endif input = (const float (*)[4])( (const char *)input_ptr + (indices[i] * input_vertex_stride)); for (slot = 0, vs_slot = 0; slot < shader->info.num_inputs; ++slot) { unsigned idx = i * TGSI_EXEC_MAX_INPUT_ATTRIBS + slot; if (shader->info.input_semantic_name[slot] == TGSI_SEMANTIC_PRIMID) { - machine->Inputs[idx].xyzw[0].f[prim_idx] = (float)shader->in_prim_idx; - machine->Inputs[idx].xyzw[1].f[prim_idx] = (float)shader->in_prim_idx; - machine->Inputs[idx].xyzw[2].f[prim_idx] = (float)shader->in_prim_idx; - machine->Inputs[idx].xyzw[3].f[prim_idx] = (float)shader->in_prim_idx; + machine->Inputs[idx].xyzw[0].f[prim_idx] = + (float)shader->in_prim_idx; + machine->Inputs[idx].xyzw[1].f[prim_idx] = + (float)shader->in_prim_idx; + machine->Inputs[idx].xyzw[2].f[prim_idx] = + (float)shader->in_prim_idx; + machine->Inputs[idx].xyzw[3].f[prim_idx] = + (float)shader->in_prim_idx; } else { - /*debug_printf("\tSlot = %d, vs_slot = %d, idx = %d:\n", - slot, vs_slot, idx);*/ +#if DEBUG_INPUTS + debug_printf("\tSlot = %d, vs_slot = %d, idx = %d:\n", + slot, vs_slot, idx); +#endif #if 1 assert(!util_is_inf_or_nan(input[vs_slot][0])); assert(!util_is_inf_or_nan(input[vs_slot][1])); @@ -239,7 +250,7 @@ static void draw_fetch_gs_input(struct draw_geometry_shader *shader, machine->Inputs[idx].xyzw[1].f[prim_idx] = input[vs_slot][1]; machine->Inputs[idx].xyzw[2].f[prim_idx] = input[vs_slot][2]; machine->Inputs[idx].xyzw[3].f[prim_idx] = input[vs_slot][3]; -#if 0 +#if DEBUG_INPUTS debug_printf("\t\t%f %f %f %f\n", machine->Inputs[idx].xyzw[0].f[prim_idx], machine->Inputs[idx].xyzw[1].f[prim_idx], @@ -252,7 +263,6 @@ static void draw_fetch_gs_input(struct draw_geometry_shader *shader, } } - static void gs_flush(struct draw_geometry_shader *shader, unsigned input_primitives) { @@ -274,6 +284,11 @@ static void gs_flush(struct draw_geometry_shader *shader, out_prim_count = machine->Temps[TGSI_EXEC_TEMP_PRIMITIVE_I].xyzw[TGSI_EXEC_TEMP_PRIMITIVE_C].u[0]; +#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); } @@ -305,6 +320,22 @@ static void gs_line(struct draw_geometry_shader *shader, gs_flush(shader, 1); } +static void gs_line_adj(struct draw_geometry_shader *shader, + int i0, int i1, int i2, int i3) +{ + unsigned indices[4]; + + indices[0] = i0; + indices[1] = i1; + indices[2] = i2; + indices[3] = i3; + + draw_fetch_gs_input(shader, indices, 4, 0); + ++shader->in_prim_idx; + + gs_flush(shader, 1); +} + static void gs_tri(struct draw_geometry_shader *shader, int i0, int i1, int i2) { @@ -320,58 +351,130 @@ static void gs_tri(struct draw_geometry_shader *shader, gs_flush(shader, 1); } +static void gs_tri_adj(struct draw_geometry_shader *shader, + int i0, int i1, int i2, + int i3, int i4, int i5) +{ + unsigned indices[6]; + + indices[0] = i0; + indices[1] = i1; + indices[2] = i2; + indices[3] = i3; + indices[4] = i4; + indices[5] = i5; + + draw_fetch_gs_input(shader, indices, 6, 0); + ++shader->in_prim_idx; + + gs_flush(shader, 1); +} + #define TRIANGLE(gs,i0,i1,i2) gs_tri(gs,i0,i1,i2) -#define LINE(gs,i0,i1) gs_line(gs,i0,i1) +#define TRI_ADJ(gs,i0,i1,i2,i3,i4,i5) gs_tri_adj(gs,i0,i1,i2,i3,i4,i5) +#define LINE(gs,i0,i1) gs_line(gs,i0,i1) +#define LINE_ADJ(gs,i0,i1,i2,i3) gs_line_adj(gs,i0,i1,i2,i3) #define POINT(gs,i0) gs_point(gs,i0) #define FUNC gs_run +#define LOCAL_VARS +#include "draw_gs_tmp.h" + + +#define TRIANGLE(gs,i0,i1,i2) gs_tri(gs,elts[i0],elts[i1],elts[i2]) +#define TRI_ADJ(gs,i0,i1,i2,i3,i4,i5) \ + gs_tri_adj(gs,elts[i0],elts[i1],elts[i2],elts[i3], \ + elts[i4],elts[i5]) +#define LINE(gs,i0,i1) gs_line(gs,elts[i0],elts[i1]) +#define LINE_ADJ(gs,i0,i1,i2,i3) gs_line_adj(gs,elts[i0], \ + elts[i1], \ + elts[i2],elts[i3]) +#define POINT(gs,i0) gs_point(gs,elts[i0]) +#define FUNC gs_run_elts +#define LOCAL_VARS \ + const ushort *elts = input_prims->elts; #include "draw_gs_tmp.h" int draw_geometry_shader_run(struct draw_geometry_shader *shader, - unsigned pipe_prim, - const float (*input)[4], - float (*output)[4], - const void *constants[PIPE_MAX_CONSTANT_BUFFERS], - unsigned count, - unsigned input_stride, - unsigned vertex_size) + const void *constants[PIPE_MAX_CONSTANT_BUFFERS], + const struct draw_vertex_info *input_verts, + const struct draw_prim_info *input_prim, + struct draw_vertex_info *output_verts, + struct draw_prim_info *output_prims ) { + const float (*input)[4] = (const float (*)[4])input_verts->verts->data; + unsigned input_stride = input_verts->vertex_size; + unsigned vertex_size = input_verts->vertex_size; struct tgsi_exec_machine *machine = shader->machine; unsigned int i; + unsigned num_input_verts = input_prim->linear ? + input_verts->count : + input_prim->count; unsigned num_in_primitives = - u_gs_prims_for_vertices(pipe_prim, count); - unsigned alloc_count = draw_max_output_vertices(shader->draw, - pipe_prim, - count); - /* this is bad, but we can't be overwriting the output array - * because it's the same as input array here */ - struct vertex_header *pipeline_verts = - (struct vertex_header *)MALLOC(vertex_size * alloc_count); + MAX2(u_gs_prims_for_vertices(input_prim->prim, num_input_verts), + u_gs_prims_for_vertices(shader->input_primitive, num_input_verts)); + unsigned max_out_prims = u_gs_prims_for_vertices(shader->output_primitive, + shader->max_output_vertices) + * num_in_primitives; + + output_verts->vertex_size = input_verts->vertex_size; + output_verts->stride = input_verts->vertex_size; + output_verts->verts = + (struct vertex_header *)MALLOC(input_verts->vertex_size * + num_in_primitives * + shader->max_output_vertices); - if (!pipeline_verts) - return 0; - if (0) debug_printf("%s count = %d (prims = %d)\n", __FUNCTION__, - count, num_in_primitives); +#if 0 + debug_printf("%s count = %d (in prims # = %d)\n", + __FUNCTION__, num_input_verts, num_in_primitives); + debug_printf("\tlinear = %d, prim_info->count = %d\n", + input_prim->linear, input_prim->count); + debug_printf("\tprimt pipe = %d, shader in = %d, shader out = %d, max out = %d\n", + input_prim->prim, shader->input_primitive, + shader->output_primitive, + shader->max_output_vertices); +#endif shader->emitted_vertices = 0; shader->emitted_primitives = 0; shader->vertex_size = vertex_size; - shader->tmp_output = ( float (*)[4])pipeline_verts->data; + shader->tmp_output = (float (*)[4])output_verts->verts->data; shader->in_prim_idx = 0; shader->input_vertex_stride = input_stride; shader->input = input; + if (shader->primitive_lengths) { + FREE(shader->primitive_lengths); + } + shader->primitive_lengths = MALLOC(max_out_prims * sizeof(unsigned)); for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { machine->Consts[i] = constants[i]; } - gs_run(shader, pipe_prim, count); + if (input_prim->linear) + gs_run(shader, input_prim, input_verts, + output_prims, output_verts); + else + gs_run_elts(shader, input_prim, input_verts, + output_prims, output_verts); - memcpy(output, pipeline_verts->data, - shader->info.num_outputs * 4 * sizeof(float) + - vertex_size * (shader->emitted_vertices -1)); + /* Update prim_info: + */ + output_prims->linear = TRUE; + output_prims->elts = NULL; + output_prims->start = 0; + output_prims->count = shader->emitted_vertices; + output_prims->prim = shader->output_primitive; + output_prims->primitive_lengths = shader->primitive_lengths; + output_prims->primitive_count = shader->emitted_primitives; + output_verts->count = shader->emitted_vertices; + +#if 0 + debug_printf("GS finished, prims = %d, verts = %d\n", + output_prims->primitive_count, + output_verts->count); +#endif - FREE(pipeline_verts); return shader->emitted_vertices; } @@ -391,24 +494,3 @@ void draw_geometry_shader_prepare(struct draw_geometry_shader *shader, draw->gs.samplers); } } - -int draw_max_output_vertices(struct draw_context *draw, - unsigned pipe_prim, - unsigned count) -{ - unsigned alloc_count = align( count, 4 ); - - if (draw->gs.geometry_shader) { - unsigned input_primitives = u_gs_prims_for_vertices(pipe_prim, - count); - /* max GS output is number of input primitives * max output - * vertices per each invocation */ - unsigned gs_max_verts = input_primitives * - draw->gs.geometry_shader->max_output_vertices; - if (gs_max_verts > count) - alloc_count = align(gs_max_verts, 4); - } - /*debug_printf("------- alloc count = %d (input = %d)\n", - alloc_count, count);*/ - return alloc_count; -} |