diff options
Diffstat (limited to 'lib/mesa/src/gallium/auxiliary/draw/draw_gs.c')
-rw-r--r-- | lib/mesa/src/gallium/auxiliary/draw/draw_gs.c | 181 |
1 files changed, 87 insertions, 94 deletions
diff --git a/lib/mesa/src/gallium/auxiliary/draw/draw_gs.c b/lib/mesa/src/gallium/auxiliary/draw/draw_gs.c index e2ffa1bdd..ed698e920 100644 --- a/lib/mesa/src/gallium/auxiliary/draw/draw_gs.c +++ b/lib/mesa/src/gallium/auxiliary/draw/draw_gs.c @@ -29,7 +29,7 @@ #include "draw_private.h" #include "draw_context.h" -#ifdef LLVM_AVAILABLE +#ifdef DRAW_LLVM_AVAILABLE #include "draw_llvm.h" #endif @@ -69,7 +69,7 @@ draw_gs_get_input_index(int semantic, int index, static inline boolean draw_gs_should_flush(struct draw_geometry_shader *shader) { - return (shader->fetched_prim_count == shader->vector_length); + return (shader->fetched_prim_count == shader->vector_length || shader->num_invocations > 1); } /*#define DEBUG_OUTPUTS 1*/ @@ -132,6 +132,12 @@ static void tgsi_fetch_gs_input(struct draw_geometry_shader *shader, unsigned input_vertex_stride = shader->input_vertex_stride; const float (*input_ptr)[4]; + int primid_sv = machine->SysSemanticToIndex[TGSI_SEMANTIC_PRIMID]; + if (primid_sv != -1) { + for (unsigned j = 0; j < TGSI_QUAD_SIZE; j++) + machine->SystemValue[primid_sv].xyzw[0].i[j] = shader->in_prim_idx; + } + input_ptr = shader->input; for (i = 0; i < num_vertices; ++i) { @@ -192,15 +198,8 @@ static void tgsi_gs_prepare(struct draw_geometry_shader *shader, const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS]) { struct tgsi_exec_machine *machine = shader->machine; - int j; tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS, constants, constants_size); - - if (shader->info.uses_invocationid) { - unsigned i = machine->SysSemanticToIndex[TGSI_SEMANTIC_INVOCATIONID]; - for (j = 0; j < TGSI_QUAD_SIZE; j++) - machine->SystemValue[i].xyzw[0].i[j] = shader->invocation_id; - } } static void tgsi_gs_run(struct draw_geometry_shader *shader, @@ -210,36 +209,20 @@ static void tgsi_gs_run(struct draw_geometry_shader *shader, struct tgsi_exec_machine *machine = shader->machine; int i; + if (shader->info.uses_invocationid) { + unsigned i = machine->SysSemanticToIndex[TGSI_SEMANTIC_INVOCATIONID]; + for (int j = 0; j < TGSI_QUAD_SIZE; j++) + machine->SystemValue[i].xyzw[0].i[j] = shader->invocation_id; + } + /* run interpreter */ tgsi_exec_machine_run(machine, 0); - for (i = 0; i < 4; i++) { - int prim_i; - int prim_c; - switch (i) { - case 0: - prim_i = TGSI_EXEC_TEMP_PRIMITIVE_I; - prim_c = TGSI_EXEC_TEMP_PRIMITIVE_C; - break; - case 1: - prim_i = TGSI_EXEC_TEMP_PRIMITIVE_S1_I; - prim_c = TGSI_EXEC_TEMP_PRIMITIVE_S1_C; - break; - case 2: - prim_i = TGSI_EXEC_TEMP_PRIMITIVE_S2_I; - prim_c = TGSI_EXEC_TEMP_PRIMITIVE_S2_C; - break; - case 3: - prim_i = TGSI_EXEC_TEMP_PRIMITIVE_S3_I; - prim_c = TGSI_EXEC_TEMP_PRIMITIVE_S3_C; - break; - }; - - out_prims[i] = machine->Temps[prim_i].xyzw[prim_c].u[0]; - } + for (i = 0; i < 4; i++) + out_prims[i] = machine->OutputPrimCount[i]; } -#ifdef LLVM_AVAILABLE +#ifdef DRAW_LLVM_AVAILABLE static void llvm_fetch_gs_input(struct draw_geometry_shader *shader, @@ -321,23 +304,23 @@ llvm_fetch_gs_outputs(struct draw_geometry_shader *shader, int vertex_count = 0; int total_prims = 0; int max_prims_per_invocation = 0; - char *output_ptr = (char*)shader->gs_output; + char *output_ptr = (char*)shader->gs_output[stream]; int i, j, prim_idx; unsigned next_prim_boundary = shader->primitive_boundary; for (i = 0; i < shader->vector_length; ++i) { - int prims = shader->llvm_emitted_primitives[i]; + int prims = shader->llvm_emitted_primitives[i + (stream * shader->vector_length)]; total_prims += prims; max_prims_per_invocation = MAX2(max_prims_per_invocation, prims); } for (i = 0; i < shader->vector_length; ++i) { - total_verts += shader->llvm_emitted_vertices[i]; + total_verts += shader->llvm_emitted_vertices[i + (stream * shader->vector_length)]; } - output_ptr += shader->stream[0].emitted_vertices * shader->vertex_size; + output_ptr += shader->stream[stream].emitted_vertices * shader->vertex_size; for (i = 0; i < shader->vector_length - 1; ++i) { - int current_verts = shader->llvm_emitted_vertices[i]; - int next_verts = shader->llvm_emitted_vertices[i + 1]; + int current_verts = shader->llvm_emitted_vertices[i + (stream * shader->vector_length)]; + int next_verts = shader->llvm_emitted_vertices[i + 1 + (stream * shader->vector_length)]; #if 0 int j; for (j = 0; j < current_verts; ++j) { @@ -377,18 +360,18 @@ llvm_fetch_gs_outputs(struct draw_geometry_shader *shader, prim_idx = 0; for (i = 0; i < shader->vector_length; ++i) { - int num_prims = shader->llvm_emitted_primitives[i]; + int num_prims = shader->llvm_emitted_primitives[i + (stream * shader->vector_length)]; for (j = 0; j < num_prims; ++j) { int prim_length = - shader->llvm_prim_lengths[j][i]; - shader->stream[0].primitive_lengths[shader->stream[0].emitted_primitives + prim_idx] = + shader->llvm_prim_lengths[j * shader->num_vertex_streams + stream][i]; + shader->stream[stream].primitive_lengths[shader->stream[stream].emitted_primitives + prim_idx] = prim_length; ++prim_idx; } } - shader->stream[0].emitted_primitives += total_prims; - shader->stream[0].emitted_vertices += total_verts; + shader->stream[stream].emitted_primitives += total_prims; + shader->stream[stream].emitted_vertices += total_verts; } static void @@ -402,20 +385,25 @@ static void llvm_gs_run(struct draw_geometry_shader *shader, unsigned input_primitives, unsigned *out_prims) { - unsigned ret; - char *input = (char*)shader->gs_output; - - input += (shader->stream[0].emitted_vertices * shader->vertex_size); + struct vertex_header *input[PIPE_MAX_VERTEX_STREAMS]; + for (unsigned i = 0; i < shader->num_vertex_streams; i++) { + char *tmp = (char *)shader->gs_output[i]; + tmp += shader->stream[i].emitted_vertices * shader->vertex_size; + input[i] = (struct vertex_header *)tmp; + } - ret = shader->current_variant->jit_func( + shader->current_variant->jit_func( shader->jit_context, shader->gs_input->data, - (struct vertex_header*)input, + input, input_primitives, shader->draw->instance_id, shader->llvm_prim_ids, - shader->invocation_id); + shader->invocation_id, + shader->draw->pt.user.viewid); - *out_prims = ret; + for (unsigned i = 0; i < shader->num_vertex_streams; i++) { + out_prims[i] = shader->jit_context->emitted_prims[i]; + } } #endif @@ -433,10 +421,13 @@ static void gs_flush(struct draw_geometry_shader *shader) debug_assert(input_primitives > 0 && input_primitives <= 4); - shader->run(shader, input_primitives, out_prim_count); - for (i = 0; i < shader->num_vertex_streams; i++) { - shader->fetch_outputs(shader, i, out_prim_count[i], - &shader->stream[i].tmp_output); + for (unsigned invocation = 0; invocation < shader->num_invocations; invocation++) { + shader->invocation_id = invocation; + shader->run(shader, input_primitives, out_prim_count); + for (i = 0; i < shader->num_vertex_streams; i++) { + shader->fetch_outputs(shader, i, out_prim_count[i], + &shader->stream[i].tmp_output); + } } #if 0 @@ -588,7 +579,6 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader, * overflown vertices into some area where they won't harm anyone */ unsigned total_verts_per_buffer = shader->primitive_boundary * num_in_primitives; - unsigned invocation; int i; //Assume at least one primitive max_out_prims = MAX2(max_out_prims, 1); @@ -599,16 +589,18 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader, output_verts[i].stride = output_verts[i].vertex_size; output_verts[i].verts = (struct vertex_header *)MALLOC(output_verts[i].vertex_size * - total_verts_per_buffer * shader->num_invocations); + total_verts_per_buffer * shader->num_invocations + + DRAW_EXTRA_VERTICES_PADDING); debug_assert(output_verts[i].verts); } #if 0 - debug_printf("%s count = %d (in prims # = %d)\n", - __FUNCTION__, num_input_verts, num_in_primitives); + debug_printf("%s count = %d (in prims # = %d, invocs = %d, streams = %d)\n", + __FUNCTION__, num_input_verts, num_in_primitives, + shader->num_invocations, shader->num_vertex_streams); debug_printf("\tlinear = %d, prim_info->count = %d\n", input_prim->linear, input_prim->count); - debug_printf("\tprim pipe = %s, shader in = %s, shader out = %s\n" + debug_printf("\tprim pipe = %s, shader in = %s, shader out = %s\n", u_prim_name(input_prim->prim), u_prim_name(shader->input_primitive), u_prim_name(shader->output_primitive)); @@ -632,20 +624,22 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader, shader->input = input; shader->input_info = input_info; -#ifdef LLVM_AVAILABLE +#ifdef DRAW_LLVM_AVAILABLE if (shader->draw->llvm) { - shader->gs_output = output_verts[0].verts; + for (i = 0; i < shader->num_vertex_streams; i++) { + shader->gs_output[i] = output_verts[i].verts; + } if (max_out_prims > shader->max_out_prims) { unsigned i; if (shader->llvm_prim_lengths) { - for (i = 0; i < shader->max_out_prims; ++i) { + for (i = 0; i < shader->num_vertex_streams * shader->max_out_prims; ++i) { align_free(shader->llvm_prim_lengths[i]); } FREE(shader->llvm_prim_lengths); } - shader->llvm_prim_lengths = MALLOC(max_out_prims * sizeof(unsigned*)); - for (i = 0; i < max_out_prims; ++i) { + shader->llvm_prim_lengths = MALLOC(shader->num_vertex_streams * max_out_prims * sizeof(unsigned*)); + for (i = 0; i < shader->num_vertex_streams * max_out_prims; ++i) { int vector_size = shader->vector_length * sizeof(unsigned); shader->llvm_prim_lengths[i] = align_malloc(vector_size, vector_size); @@ -659,26 +653,22 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader, } #endif - for (invocation = 0; invocation < shader->num_invocations; invocation++) { - shader->invocation_id = invocation; - - shader->prepare(shader, constants, constants_size); + shader->prepare(shader, constants, constants_size); - 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); + 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); - /* Flush the remaining primitives. Will happen if - * num_input_primitives % 4 != 0 - */ - if (shader->fetched_prim_count > 0) { - gs_flush(shader); - } - debug_assert(shader->fetched_prim_count == 0); + /* Flush the remaining primitives. Will happen if + * num_input_primitives % 4 != 0 + */ + if (shader->fetched_prim_count > 0) { + gs_flush(shader); } + debug_assert(shader->fetched_prim_count == 0); /* Update prim_info: */ @@ -765,14 +755,14 @@ struct draw_geometry_shader * draw_create_geometry_shader(struct draw_context *draw, const struct pipe_shader_state *state) { -#ifdef LLVM_AVAILABLE +#ifdef DRAW_LLVM_AVAILABLE boolean use_llvm = draw->llvm != NULL; struct llvm_geometry_shader *llvm_gs = NULL; #endif struct draw_geometry_shader *gs; unsigned i; -#ifdef LLVM_AVAILABLE +#ifdef DRAW_LLVM_AVAILABLE if (use_llvm) { llvm_gs = CALLOC_STRUCT(llvm_geometry_shader); @@ -808,7 +798,7 @@ draw_create_geometry_shader(struct draw_context *draw, /* setup the defaults */ gs->max_out_prims = 0; -#ifdef LLVM_AVAILABLE +#ifdef DRAW_LLVM_AVAILABLE if (use_llvm) { /* TODO: change the input array to handle the following vector length, instead of the currently hardcoded @@ -865,16 +855,16 @@ draw_create_geometry_shader(struct draw_context *draw, gs->num_vertex_streams = gs->state.stream_output.output[i].stream + 1; } -#ifdef LLVM_AVAILABLE +#ifdef DRAW_LLVM_AVAILABLE if (use_llvm) { int vector_size = gs->vector_length * sizeof(float); gs->gs_input = align_malloc(sizeof(struct draw_gs_inputs), 16); memset(gs->gs_input, 0, sizeof(struct draw_gs_inputs)); gs->llvm_prim_lengths = 0; - gs->llvm_emitted_primitives = align_malloc(vector_size, vector_size); - gs->llvm_emitted_vertices = align_malloc(vector_size, vector_size); - gs->llvm_prim_ids = align_malloc(vector_size, vector_size); + gs->llvm_emitted_primitives = align_malloc(vector_size * gs->num_vertex_streams, vector_size); + gs->llvm_emitted_vertices = align_malloc(vector_size * gs->num_vertex_streams, vector_size); + gs->llvm_prim_ids = align_calloc(vector_size, vector_size); gs->fetch_outputs = llvm_fetch_gs_outputs; gs->fetch_inputs = llvm_fetch_gs_input; @@ -925,7 +915,7 @@ void draw_delete_geometry_shader(struct draw_context *draw, if (!dgs) { return; } -#ifdef LLVM_AVAILABLE +#ifdef DRAW_LLVM_AVAILABLE if (draw->llvm) { struct llvm_geometry_shader *shader = llvm_geometry_shader(dgs); struct draw_gs_llvm_variant_list_item *li; @@ -941,7 +931,7 @@ void draw_delete_geometry_shader(struct draw_context *draw, if (dgs->llvm_prim_lengths) { unsigned i; - for (i = 0; i < dgs->max_out_prims; ++i) { + for (i = 0; i < dgs->num_vertex_streams * dgs->max_out_prims; ++i) { align_free(dgs->llvm_prim_lengths[i]); } FREE(dgs->llvm_prim_lengths); @@ -954,6 +944,9 @@ void draw_delete_geometry_shader(struct draw_context *draw, } #endif + if (draw->gs.tgsi.machine && draw->gs.tgsi.machine->Tokens == dgs->state.tokens) + draw->gs.tgsi.machine->Tokens = NULL; + for (i = 0; i < TGSI_MAX_VERTEX_STREAMS; i++) FREE(dgs->stream[i].primitive_lengths); @@ -964,7 +957,7 @@ void draw_delete_geometry_shader(struct draw_context *draw, } -#ifdef LLVM_AVAILABLE +#ifdef DRAW_LLVM_AVAILABLE void draw_gs_set_current_variant(struct draw_geometry_shader *shader, struct draw_gs_llvm_variant *variant) { |