+}
+
+#ifdef HAVE_LLVM
+
+static void
+llvm_fetch_gs_input(struct draw_geometry_shader *shader,
+ unsigned *indices,
+ unsigned num_vertices,
+ unsigned prim_idx)
+{
+ unsigned slot, i;
+ int vs_slot;
+ unsigned input_vertex_stride = shader->input_vertex_stride;
+ const float (*input_ptr)[4];
+ float (*input_data)[6][PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS][TGSI_NUM_CHANNELS] = &shader->gs_input->data;
+
+ shader->llvm_prim_ids[shader->fetched_prim_count] = shader->in_prim_idx;
+
+ input_ptr = shader->input;
+
+ for (i = 0; i < num_vertices; ++i) {
+ const float (*input)[4];
+#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) {
+ if (shader->info.input_semantic_name[slot] == TGSI_SEMANTIC_PRIMID) {
+ /* skip. we handle system values through gallivm */
+ /* NOTE: If we hit this case here it's an ordinary input not a sv,
+ * even though it probably should be a sv.
+ * Not sure how to set it up as regular input however if that even,
+ * would make sense so hack around this later in gallivm.
+ */
+ } else {
+ vs_slot = draw_gs_get_input_index(
+ shader->info.input_semantic_name[slot],
+ shader->info.input_semantic_index[slot],
+ shader->input_info);
+ if (vs_slot < 0) {
+ debug_printf("VS/GS signature mismatch!\n");
+ (*input_data)[i][slot][0][prim_idx] = 0;
+ (*input_data)[i][slot][1][prim_idx] = 0;
+ (*input_data)[i][slot][2][prim_idx] = 0;
+ (*input_data)[i][slot][3][prim_idx] = 0;
+ } else {
+#if DEBUG_INPUTS
+ debug_printf("\tSlot = %d, vs_slot = %d, i = %d:\n",
+ slot, vs_slot, i);
+ assert(!util_is_inf_or_nan(input[vs_slot][0]));
+ assert(!util_is_inf_or_nan(input[vs_slot][1]));
+ assert(!util_is_inf_or_nan(input[vs_slot][2]));
+ assert(!util_is_inf_or_nan(input[vs_slot][3]));
+#endif
+ (*input_data)[i][slot][0][prim_idx] = input[vs_slot][0];
+ (*input_data)[i][slot][1][prim_idx] = input[vs_slot][1];
+ (*input_data)[i][slot][2][prim_idx] = input[vs_slot][2];
+ (*input_data)[i][slot][3][prim_idx] = input[vs_slot][3];
+#if DEBUG_INPUTS
+ debug_printf("\t\t%f %f %f %f\n",
+ (*input_data)[i][slot][0][prim_idx],
+ (*input_data)[i][slot][1][prim_idx],
+ (*input_data)[i][slot][2][prim_idx],
+ (*input_data)[i][slot][3][prim_idx]);
+#endif
+ ++vs_slot;
+ }
+ }
+ }
+ }
+}
+
+static void
+llvm_fetch_gs_outputs(struct draw_geometry_shader *shader,
+ unsigned num_primitives,
+ float (**p_output)[4])
+{
+ int total_verts = 0;
+ int vertex_count = 0;
+ int total_prims = 0;
+ int max_prims_per_invocation = 0;
+ char *output_ptr = (char*)shader->gs_output;
+ 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];
+ 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];
+ }
+
+ output_ptr += shader->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];
+#if 0
+ int j;
+ for (j = 0; j < current_verts; ++j) {
+ struct vertex_header *vh = (struct vertex_header *)
+ (output_ptr + shader->vertex_size * (i * next_prim_boundary + j));
+ debug_printf("--- %d) [%f, %f, %f, %f]\n", j + vertex_count,
+ vh->data[0][0], vh->data[0][1], vh->data[0][2], vh->data[0][3]);
+
+ }
+#endif
+ debug_assert(current_verts <= shader->max_output_vertices);
+ debug_assert(next_verts <= shader->max_output_vertices);
+ if (next_verts) {
+ memmove(output_ptr + (vertex_count + current_verts) * shader->vertex_size,
+ output_ptr + ((i + 1) * next_prim_boundary) * shader->vertex_size,
+ shader->vertex_size * next_verts);
+ }
+ vertex_count += current_verts;
+ }
+
+#if 0
+ {
+ int i;
+ for (i = 0; i < total_verts; ++i) {
+ struct vertex_header *vh = (struct vertex_header *)(output_ptr + shader->vertex_size * i);
+ debug_printf("%d) Vertex:\n", i);
+ for (j = 0; j < shader->info.num_outputs; ++j) {
+ unsigned *udata = (unsigned*)vh->data[j];
+ debug_printf(" %d) [%f, %f, %f, %f] [%d, %d, %d, %d]\n", j,
+ vh->data[j][0], vh->data[j][1], vh->data[j][2], vh->data[j][3],
+ udata[0], udata[1], udata[2], udata[3]);
+ }
+
+ }
+ }
+#endif
+
+ prim_idx = 0;
+ for (i = 0; i < shader->vector_length; ++i) {
+ int num_prims = shader->llvm_emitted_primitives[i];
+ for (j = 0; j < num_prims; ++j) {
+ int prim_length =
+ shader->llvm_prim_lengths[j][i];
+ shader->primitive_lengths[shader->emitted_primitives + prim_idx] =
+ prim_length;
+ ++prim_idx;
+ }
+ }
+
+ shader->emitted_primitives += total_prims;
+ shader->emitted_vertices += total_verts;
+}
+
+static void
+llvm_gs_prepare(struct draw_geometry_shader *shader,
+ const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
+ const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS])
+{
+}
+
+static unsigned
+llvm_gs_run(struct draw_geometry_shader *shader,
+ unsigned input_primitives)
+{
+ unsigned ret;
+ char *input = (char*)shader->gs_output;
+
+ input += (shader->emitted_vertices * shader->vertex_size);
+
+ ret = shader->current_variant->jit_func(
+ shader->jit_context, shader->gs_input->data,
+ (struct vertex_header*)input,
+ input_primitives,
+ shader->draw->instance_id,
+ shader->llvm_prim_ids,
+ shader->invocation_id);
+
+ return ret;
+}
+
+#endif
+
+static void gs_flush(struct draw_geometry_shader *shader)
+{
+ unsigned out_prim_count;
+
+ unsigned input_primitives = shader->fetched_prim_count;
+
+ if (shader->draw->collect_statistics) {
+ shader->draw->statistics.gs_invocations += input_primitives;
+ }
+
+ debug_assert(input_primitives > 0 &&
+ input_primitives <= 4);
+
+ out_prim_count = shader->run(shader, input_primitives);
+ shader->fetch_outputs(shader, out_prim_count,
+ &shader->tmp_output);