Commit 7720ce32 authored by Dave Airlie's avatar Dave Airlie Committed by Dave Airlie

draw: add support to tgsi paths for geometry streams. (v2)

This hooks up the geometry shader processing to the TGSI
support added in the previous commits.

It doesn't change the llvm interface other than to
keep things building.

v2: fix some regressions caused by primitiveoffsets
Reviewed-by: default avatarRoland Scheidegger <sroland@vmware.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent ddb9ad36
This diff is collapsed.
......@@ -57,6 +57,13 @@ struct draw_gs_inputs {
/**
* Private version of the compiled geometry shader
*/
struct draw_vertex_stream {
unsigned *primitive_lengths;
unsigned emitted_vertices;
unsigned emitted_primitives;
float (*tmp_output)[4];
};
struct draw_geometry_shader {
struct draw_context *draw;
......@@ -74,14 +81,11 @@ struct draw_geometry_shader {
unsigned primitive_boundary;
unsigned input_primitive;
unsigned output_primitive;
unsigned *primitive_lengths;
unsigned emitted_vertices;
unsigned emitted_primitives;
float (*tmp_output)[4];
unsigned vertex_size;
struct draw_vertex_stream stream[TGSI_MAX_VERTEX_STREAMS];
unsigned num_vertex_streams;
unsigned in_prim_idx;
unsigned input_vertex_stride;
unsigned fetched_prim_count;
......@@ -109,14 +113,15 @@ struct draw_geometry_shader {
unsigned num_vertices,
unsigned prim_idx);
void (*fetch_outputs)(struct draw_geometry_shader *shader,
unsigned vertex_stream,
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);
void (*run)(struct draw_geometry_shader *shader,
unsigned input_primitives, unsigned *out_prims);
};
void draw_geometry_shader_new_instance(struct draw_geometry_shader *gs);
......
......@@ -188,6 +188,7 @@ struct pt_so_emit;
void draw_pt_so_emit_prepare(struct pt_so_emit *emit, boolean use_pre_clip_pos);
void draw_pt_so_emit( struct pt_so_emit *emit,
int num_vertex_streams,
const struct draw_vertex_info *vert_info,
const struct draw_prim_info *prim_info );
......
......@@ -237,16 +237,17 @@ fetch_pipeline_generic(struct draw_pt_middle_end *middle,
struct draw_context *draw = fpme->draw;
struct draw_vertex_shader *vshader = draw->vs.vertex_shader;
struct draw_geometry_shader *gshader = draw->gs.geometry_shader;
struct draw_prim_info gs_prim_info;
struct draw_prim_info gs_prim_info[TGSI_MAX_VERTEX_STREAMS];
struct draw_vertex_info fetched_vert_info;
struct draw_vertex_info vs_vert_info;
struct draw_vertex_info gs_vert_info;
struct draw_vertex_info gs_vert_info[TGSI_MAX_VERTEX_STREAMS];
struct draw_vertex_info *vert_info;
struct draw_prim_info ia_prim_info;
struct draw_vertex_info ia_vert_info;
const struct draw_prim_info *prim_info = in_prim_info;
boolean free_prim_info = FALSE;
unsigned opt = fpme->opt;
int num_vertex_streams = 1;
fetched_vert_info.count = fetch_info->count;
fetched_vert_info.vertex_size = fpme->vertex_size;
......@@ -298,12 +299,13 @@ fetch_pipeline_generic(struct draw_pt_middle_end *middle,
vert_info,
prim_info,
&vshader->info,
&gs_vert_info,
&gs_prim_info);
gs_vert_info,
gs_prim_info);
FREE(vert_info->verts);
vert_info = &gs_vert_info;
prim_info = &gs_prim_info;
vert_info = &gs_vert_info[0];
prim_info = &gs_prim_info[0];
num_vertex_streams = gshader->num_vertex_streams;
/*
* pt emit can only handle ushort number of vertices (see
......@@ -343,7 +345,7 @@ fetch_pipeline_generic(struct draw_pt_middle_end *middle,
* XXX: Stream output surely needs to respect the prim_info->elt
* lists.
*/
draw_pt_so_emit( fpme->so_emit, vert_info, prim_info );
draw_pt_so_emit( fpme->so_emit, num_vertex_streams, vert_info, prim_info );
draw_stats_clipper_primitives(draw, prim_info);
......
......@@ -355,9 +355,9 @@ llvm_pipeline_generic(struct draw_pt_middle_end *middle,
struct llvm_middle_end *fpme = llvm_middle_end(middle);
struct draw_context *draw = fpme->draw;
struct draw_geometry_shader *gshader = draw->gs.geometry_shader;
struct draw_prim_info gs_prim_info;
struct draw_prim_info gs_prim_info[TGSI_MAX_VERTEX_STREAMS];
struct draw_vertex_info llvm_vert_info;
struct draw_vertex_info gs_vert_info;
struct draw_vertex_info gs_vert_info[TGSI_MAX_VERTEX_STREAMS];
struct draw_vertex_info *vert_info;
struct draw_prim_info ia_prim_info;
struct draw_vertex_info ia_vert_info;
......@@ -422,12 +422,12 @@ llvm_pipeline_generic(struct draw_pt_middle_end *middle,
vert_info,
prim_info,
&vshader->info,
&gs_vert_info,
&gs_prim_info);
gs_vert_info,
gs_prim_info);
FREE(vert_info->verts);
vert_info = &gs_vert_info;
prim_info = &gs_prim_info;
vert_info = &gs_vert_info[0];
prim_info = &gs_prim_info[0];
/*
* pt emit can only handle ushort number of vertices (see
* render->allocate_vertices).
......@@ -461,7 +461,7 @@ llvm_pipeline_generic(struct draw_pt_middle_end *middle,
}
/* stream output needs to be done before clipping */
draw_pt_so_emit( fpme->so_emit, vert_info, prim_info );
draw_pt_so_emit( fpme->so_emit, 1, vert_info, prim_info );
draw_stats_clipper_primitives(draw, prim_info);
......
......@@ -49,6 +49,7 @@ struct pt_so_emit {
int pos_idx;
unsigned emitted_primitives;
unsigned generated_primitives;
unsigned stream;
};
static const struct pipe_stream_output_info *
......@@ -144,6 +145,9 @@ static void so_emit_prim(struct pt_so_emit *so,
int ob = state->output[slot].output_buffer;
unsigned dst_offset = state->output[slot].dst_offset * sizeof(float);
unsigned write_size = num_comps * sizeof(float);
if (state->output[slot].stream != so->stream)
continue;
/* If a buffer is missing then that's equivalent to
* an overflow */
if (!draw->so.targets[ob]) {
......@@ -175,7 +179,10 @@ static void so_emit_prim(struct pt_so_emit *so,
unsigned idx = state->output[slot].register_index;
unsigned start_comp = state->output[slot].start_component;
unsigned num_comps = state->output[slot].num_components;
unsigned stream = state->output[slot].stream;
if (stream != so->stream)
continue;
ob = state->output[slot].output_buffer;
buffer_written[ob] = TRUE;
......@@ -184,7 +191,7 @@ static void so_emit_prim(struct pt_so_emit *so,
draw->so.targets[ob]->internal_offset) +
state->output[slot].dst_offset;
if (idx == so->pos_idx && pcp_ptr)
if (idx == so->pos_idx && pcp_ptr && so->stream == 0)
memcpy(buffer, &pre_clip_pos[start_comp],
num_comps * sizeof(float));
else
......@@ -193,8 +200,8 @@ static void so_emit_prim(struct pt_so_emit *so,
#if 0
{
int j;
debug_printf("VERT[%d], offset = %d, slot[%d] sc = %d, num_c = %d, idx = %d = [",
i,
debug_printf("VERT[%d], stream = %d, offset = %d, slot[%d] sc = %d, num_c = %d, idx = %d = [",
i, stream,
draw->so.targets[ob]->internal_offset,
slot, start_comp, num_comps, idx);
for (j = 0; j < num_comps; ++j) {
......@@ -258,12 +265,13 @@ static void so_tri(struct pt_so_emit *so, int i0, int i1, int i2)
void draw_pt_so_emit( struct pt_so_emit *emit,
int num_vertex_streams,
const struct draw_vertex_info *input_verts,
const struct draw_prim_info *input_prims )
{
struct draw_context *draw = emit->draw;
struct vbuf_render *render = draw->render;
unsigned start, i;
unsigned start, i, stream;
if (!emit->has_so)
return;
......@@ -271,34 +279,36 @@ void draw_pt_so_emit( struct pt_so_emit *emit,
if (!draw->so.num_targets)
return;
emit->emitted_primitives = 0;
emit->generated_primitives = 0;
emit->input_vertex_stride = input_verts->stride;
if (emit->use_pre_clip_pos)
emit->pre_clip_pos = input_verts->verts->clip_pos;
emit->inputs = (const float (*)[4])input_verts->verts->data;
/* XXX: need to flush to get prim_vbuf.c to release its allocation??*/
draw_do_flush( draw, DRAW_FLUSH_BACKEND );
for (start = i = 0; i < input_prims->primitive_count;
start += input_prims->primitive_lengths[i], i++)
{
unsigned count = input_prims->primitive_lengths[i];
if (input_prims->linear) {
so_run_linear(emit, input_prims, input_verts,
start, count);
} else {
so_run_elts(emit, input_prims, input_verts,
start, count);
for (stream = 0; stream < num_vertex_streams; stream++) {
emit->emitted_primitives = 0;
emit->generated_primitives = 0;
if (emit->use_pre_clip_pos)
emit->pre_clip_pos = input_verts[stream].verts->clip_pos;
emit->input_vertex_stride = input_verts[stream].stride;
emit->inputs = (const float (*)[4])input_verts[stream].verts->data;
emit->stream = stream;
for (start = i = 0; i < input_prims[stream].primitive_count;
start += input_prims[stream].primitive_lengths[i], i++)
{
unsigned count = input_prims[stream].primitive_lengths[i];
if (input_prims->linear) {
so_run_linear(emit, &input_prims[stream], &input_verts[stream],
start, count);
} else {
so_run_elts(emit, &input_prims[stream], &input_verts[stream],
start, count);
}
}
render->set_stream_output_info(render,
stream,
emit->emitted_primitives,
emit->generated_primitives);
}
render->set_stream_output_info(render, 0,
emit->emitted_primitives,
emit->generated_primitives);
}
......
......@@ -107,8 +107,8 @@ softpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q)
break;
case PIPE_QUERY_SO_OVERFLOW_PREDICATE:
case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE:
sq->so.num_primitives_written = softpipe->so_stats.num_primitives_written;
sq->so.primitives_storage_needed = softpipe->so_stats.primitives_storage_needed;
sq->so.num_primitives_written = softpipe->so_stats[sq->index].num_primitives_written;
sq->so.primitives_storage_needed = softpipe->so_stats[sq->index].primitives_storage_needed;
break;
case PIPE_QUERY_PRIMITIVES_EMITTED:
sq->so.num_primitives_written = softpipe->so_stats[sq->index].num_primitives_written;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment