summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/softpipe
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2012-01-04 17:38:55 +0000
committerDave Airlie <[email protected]>2012-01-10 12:07:51 +0000
commitec8cbd79ac4065111365a6720c9564de56855cc8 (patch)
tree741b04a8e779a4ce401f59bbe505fbd1e55e78ab /src/gallium/drivers/softpipe
parent67e3cbf1632e361220234013147331e4618b70cb (diff)
draw/softpipe: EXT_transform_feedback support (v2)
This replaces the current code with an implementation compatible with the new gallium interface. I've left some of the remains of the interface intact so llvmpipe keeps building correctly, and I'll take a look at fixing llvmpipe up later. v2: fixup as per Brian's review Signed-off-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/gallium/drivers/softpipe')
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c1
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h12
-rw-r--r--src/gallium/drivers/softpipe/sp_draw_arrays.c62
-rw-r--r--src/gallium/drivers/softpipe/sp_prim_vbuf.c11
-rw-r--r--src/gallium/drivers/softpipe/sp_query.c25
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c5
-rw-r--r--src/gallium/drivers/softpipe/sp_setup.c6
-rw-r--r--src/gallium/drivers/softpipe/sp_state.h3
-rw-r--r--src/gallium/drivers/softpipe/sp_state_so.c115
9 files changed, 80 insertions, 160 deletions
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index 324d9fd67c6..e533e5a8243 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -257,7 +257,6 @@ softpipe_create_context( struct pipe_screen *screen,
softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
softpipe->pipe.draw_vbo = softpipe_draw_vbo;
- /* XXX softpipe->pipe.draw_stream_output = softpipe_draw_stream_output; */
softpipe->pipe.clear = softpipe_clear;
softpipe->pipe.flush = softpipe_flush_wrapped;
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 5442aba9019..c657bd61fcf 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -55,7 +55,6 @@ struct sp_vertex_shader;
struct sp_velems_state;
struct sp_so_state;
-
struct softpipe_context {
struct pipe_context pipe; /**< base class */
@@ -88,13 +87,12 @@ struct softpipe_context {
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
struct pipe_index_buffer index_buffer;
- struct {
- struct softpipe_resource *buffer[PIPE_MAX_SO_BUFFERS];
- int offset[PIPE_MAX_SO_BUFFERS];
- int so_count[PIPE_MAX_SO_BUFFERS];
- int num_buffers;
- } so_target;
+
+ struct draw_so_target *so_targets[PIPE_MAX_SO_BUFFERS];
+ int num_so_targets;
+
struct pipe_query_data_so_statistics so_stats;
+ unsigned num_primitives_generated;
unsigned num_fragment_samplers;
unsigned num_fragment_sampler_views;
diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c
index 69b5b96b4fd..27004071f02 100644
--- a/src/gallium/drivers/softpipe/sp_draw_arrays.c
+++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c
@@ -43,58 +43,6 @@
#include "draw/draw_context.h"
-
-
-
-
-void
-softpipe_draw_stream_output(struct pipe_context *pipe, unsigned mode)
-{
- struct softpipe_context *sp = softpipe_context(pipe);
- struct draw_context *draw = sp->draw;
- const unsigned start = 0;
- const unsigned count = sp->so_target.so_count[0];
- void *buf = sp->so_target.buffer[0]->data;
- int offset = sp->so_target.offset[0];
-
- if (!softpipe_check_render_cond(sp) ||
- sp->so_target.num_buffers != 1)
- return;
-
- sp->reduced_api_prim = u_reduced_prim(mode);
-
- if (sp->dirty) {
- softpipe_update_derived(sp, sp->reduced_api_prim);
- }
-
- softpipe_map_transfers(sp);
-
- /* Map so buffers */
- if (offset < 0) /* we were appending so start from beginning */
- offset = 0;
- buf = (void*)((int32_t*)buf + offset);
- draw_set_mapped_vertex_buffer(draw, 0, buf);
-
- draw_set_mapped_index_buffer(draw, NULL);
-
- /* draw! */
- draw_arrays(draw, mode, start, count);
-
- /* unmap vertex/index buffers - will cause draw module to flush */
- draw_set_mapped_vertex_buffer(draw, 0, NULL);
-
- /*
- * TODO: Flush only when a user vertex/index buffer is present
- * (or even better, modify draw module to do this
- * internally when this condition is seen?)
- */
- draw_flush(draw);
-
- /* Note: leave drawing surfaces mapped */
- sp->dirty_render_cache = TRUE;
-}
-
-
/**
* This function handles drawing indexed and non-indexed prims,
* instanced and non-instanced drawing, with or without min/max element
@@ -139,6 +87,14 @@ softpipe_draw_vbo(struct pipe_context *pipe,
draw_set_mapped_index_buffer(draw, mapped_indices);
+ for (i = 0; i < sp->num_so_targets; i++) {
+ void *buf = softpipe_resource(sp->so_targets[i]->target.buffer)->data;
+ sp->so_targets[i]->mapping = buf;
+ }
+
+ draw_set_mapped_so_targets(draw, sp->num_so_targets,
+ sp->so_targets);
+
/* draw! */
draw_vbo(draw, info);
@@ -150,6 +106,8 @@ softpipe_draw_vbo(struct pipe_context *pipe,
draw_set_mapped_index_buffer(draw, NULL);
}
+ draw_set_mapped_so_targets(draw, 0, NULL);
+
/*
* TODO: Flush only when a user vertex/index buffer is present
* (or even better, modify draw module to do this
diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
index 54a6542bdcd..a142118f31e 100644
--- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c
+++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
@@ -542,19 +542,16 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
}
static void
-sp_vbuf_so_info(struct vbuf_render *vbr, uint primitives, uint vertices)
+sp_vbuf_so_info(struct vbuf_render *vbr, uint primitives, uint vertices,
+ uint prim_generated)
{
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
struct softpipe_context *softpipe = cvbr->softpipe;
- unsigned i;
-
- for (i = 0; i < softpipe->so_target.num_buffers; ++i) {
- softpipe->so_target.so_count[i] += vertices;
- }
- softpipe->so_stats.num_primitives_written = primitives;
+ softpipe->so_stats.num_primitives_written += primitives;
softpipe->so_stats.primitives_storage_needed =
vertices * 4 /*sizeof(float|int32)*/ * 4 /*x,y,z,w*/;
+ softpipe->num_primitives_generated += prim_generated;
}
diff --git a/src/gallium/drivers/softpipe/sp_query.c b/src/gallium/drivers/softpipe/sp_query.c
index c2c48e8ecb3..2e54e023091 100644
--- a/src/gallium/drivers/softpipe/sp_query.c
+++ b/src/gallium/drivers/softpipe/sp_query.c
@@ -42,6 +42,7 @@ struct softpipe_query {
uint64_t start;
uint64_t end;
struct pipe_query_data_so_statistics so;
+ unsigned num_primitives_generated;
};
@@ -59,6 +60,8 @@ softpipe_create_query(struct pipe_context *pipe,
assert(type == PIPE_QUERY_OCCLUSION_COUNTER ||
type == PIPE_QUERY_TIME_ELAPSED ||
type == PIPE_QUERY_SO_STATISTICS ||
+ type == PIPE_QUERY_PRIMITIVES_EMITTED ||
+ type == PIPE_QUERY_PRIMITIVES_GENERATED ||
type == PIPE_QUERY_GPU_FINISHED ||
type == PIPE_QUERY_TIMESTAMP ||
type == PIPE_QUERY_TIMESTAMP_DISJOINT);
@@ -91,8 +94,14 @@ softpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q)
sq->start = 1000*os_time_get();
break;
case PIPE_QUERY_SO_STATISTICS:
- sq->so.num_primitives_written = 0;
sq->so.primitives_storage_needed = 0;
+ case PIPE_QUERY_PRIMITIVES_EMITTED:
+ sq->so.num_primitives_written = 0;
+ softpipe->so_stats.num_primitives_written = 0;
+ break;
+ case PIPE_QUERY_PRIMITIVES_GENERATED:
+ sq->num_primitives_generated = 0;
+ softpipe->num_primitives_generated = 0;
break;
case PIPE_QUERY_TIMESTAMP:
case PIPE_QUERY_GPU_FINISHED:
@@ -125,10 +134,14 @@ softpipe_end_query(struct pipe_context *pipe, struct pipe_query *q)
sq->end = 1000*os_time_get();
break;
case PIPE_QUERY_SO_STATISTICS:
- sq->so.num_primitives_written =
- softpipe->so_stats.num_primitives_written;
sq->so.primitives_storage_needed =
softpipe->so_stats.primitives_storage_needed;
+ case PIPE_QUERY_PRIMITIVES_EMITTED:
+ sq->so.num_primitives_written =
+ softpipe->so_stats.num_primitives_written;
+ break;
+ case PIPE_QUERY_PRIMITIVES_GENERATED:
+ sq->num_primitives_generated = softpipe->num_primitives_generated;
break;
case PIPE_QUERY_GPU_FINISHED:
break;
@@ -166,6 +179,12 @@ softpipe_get_query_result(struct pipe_context *pipe,
sizeof(struct pipe_query_data_timestamp_disjoint));
}
break;
+ case PIPE_QUERY_PRIMITIVES_EMITTED:
+ *result = sq->so.num_primitives_written;
+ break;
+ case PIPE_QUERY_PRIMITIVES_GENERATED:
+ *result = sq->num_primitives_generated;
+ break;
default:
*result = sq->end - sq->start;
break;
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 07f1970b385..982af6b3808 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -106,7 +106,10 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 1;
case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
- return 0;
+ return PIPE_MAX_SO_BUFFERS;
+ case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
+ case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
+ return 16*4;
case PIPE_CAP_PRIMITIVE_RESTART:
return 1;
case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c
index 656d001809f..0d67af3eb74 100644
--- a/src/gallium/drivers/softpipe/sp_setup.c
+++ b/src/gallium/drivers/softpipe/sp_setup.c
@@ -807,7 +807,7 @@ sp_setup_tri(struct setup_context *setup,
print_vertex(setup, v2);
#endif
- if (setup->softpipe->no_rast)
+ if (setup->softpipe->no_rast || setup->softpipe->rasterizer->rasterizer_discard)
return;
det = calc_det(v0, v1, v2);
@@ -1073,7 +1073,7 @@ sp_setup_line(struct setup_context *setup,
print_vertex(setup, v1);
#endif
- if (setup->softpipe->no_rast)
+ if (setup->softpipe->no_rast || setup->softpipe->rasterizer->rasterizer_discard)
return;
if (dx == 0 && dy == 0)
@@ -1206,7 +1206,7 @@ sp_setup_point(struct setup_context *setup,
print_vertex(setup, v0);
#endif
- if (softpipe->no_rast)
+ if (setup->softpipe->no_rast || setup->softpipe->rasterizer->rasterizer_discard)
return;
assert(setup->softpipe->reduced_prim == PIPE_PRIM_POINTS);
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index bdda29495b2..6df40c66394 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -159,9 +159,6 @@ softpipe_draw_vbo(struct pipe_context *pipe,
const struct pipe_draw_info *info);
void
-softpipe_draw_stream_output(struct pipe_context *pipe, unsigned mode);
-
-void
softpipe_map_transfers(struct softpipe_context *sp);
void
diff --git a/src/gallium/drivers/softpipe/sp_state_so.c b/src/gallium/drivers/softpipe/sp_state_so.c
index 31ef3841294..2b5893906c8 100644
--- a/src/gallium/drivers/softpipe/sp_state_so.c
+++ b/src/gallium/drivers/softpipe/sp_state_so.c
@@ -32,109 +32,58 @@
#include "util/u_format.h"
#include "util/u_memory.h"
#include "draw/draw_context.h"
+#include "pipebuffer/pb_buffer.h"
-
-static void *
-softpipe_create_stream_output_state(struct pipe_context *pipe,
- const struct pipe_stream_output_info *templ)
+static struct pipe_stream_output_target *
+softpipe_create_so_target(struct pipe_context *pipe,
+ struct pipe_resource *buffer,
+ unsigned buffer_offset,
+ unsigned buffer_size)
{
- struct sp_so_state *so;
- so = (struct sp_so_state *) CALLOC_STRUCT(sp_so_state);
-
- if (so) {
- so->base.num_outputs = templ->num_outputs;
- so->base.stride = templ->stride;
- memcpy(so->base.output, templ->output,
- templ->num_outputs * sizeof(templ->output[0]));
- }
- return so;
-}
-
-
-static void
-softpipe_bind_stream_output_state(struct pipe_context *pipe,
- void *so)
-{
- struct softpipe_context *softpipe = softpipe_context(pipe);
- struct sp_so_state *sp_so = (struct sp_so_state *) so;
-
- softpipe->so = sp_so;
-
- softpipe->dirty |= SP_NEW_SO;
-
- if (sp_so)
- draw_set_so_state(softpipe->draw, &sp_so->base);
+ struct draw_so_target *t;
+
+ t = CALLOC_STRUCT(draw_so_target);
+ t->target.context = pipe;
+ t->target.reference.count = 1;
+ pipe_resource_reference(&t->target.buffer, buffer);
+ t->target.buffer_offset = buffer_offset;
+ t->target.buffer_size = buffer_size;
+ return &t->target;
}
-
static void
-softpipe_delete_stream_output_state(struct pipe_context *pipe, void *so)
+softpipe_so_target_destroy(struct pipe_context *pipe,
+ struct pipe_stream_output_target *target)
{
- FREE( so );
+ pipe_resource_reference(&target->buffer, NULL);
+ FREE(target);
}
-
static void
-softpipe_set_stream_output_buffers(struct pipe_context *pipe,
- struct pipe_resource **buffers,
- int *offsets,
- int num_buffers)
+softpipe_set_so_targets(struct pipe_context *pipe,
+ unsigned num_targets,
+ struct pipe_stream_output_target **targets,
+ unsigned append_bitmask)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
int i;
- void *map_buffers[PIPE_MAX_SO_BUFFERS];
-
- assert(num_buffers <= PIPE_MAX_SO_BUFFERS);
- if (num_buffers > PIPE_MAX_SO_BUFFERS)
- num_buffers = PIPE_MAX_SO_BUFFERS;
-
- softpipe->dirty |= SP_NEW_SO_BUFFERS;
-
- for (i = 0; i < num_buffers; ++i) {
- void *mapped;
- struct softpipe_resource *res = softpipe_resource(buffers[i]);
- if (!res) {
- /* the whole call is invalid, bail out */
- softpipe->so_target.num_buffers = 0;
- draw_set_mapped_so_buffers(softpipe->draw, 0, 0);
- return;
- }
-
- softpipe->so_target.buffer[i] = res;
- softpipe->so_target.offset[i] = offsets[i];
- softpipe->so_target.so_count[i] = 0;
+ for (i = 0; i < num_targets; i++) {
+ pipe_so_target_reference((struct pipe_stream_output_target **)&softpipe->so_targets[i], targets[i]);
+ }
- mapped = res->data;
- if (offsets[i] >= 0)
- map_buffers[i] = ((char*)mapped) + offsets[i];
- else {
- /* this is a buffer append */
- assert(!"appending not implemented");
- map_buffers[i] = mapped;
- }
+ for (; i < softpipe->num_so_targets; i++) {
+ pipe_so_target_reference((struct pipe_stream_output_target **)&softpipe->so_targets[i], NULL);
}
- softpipe->so_target.num_buffers = num_buffers;
- draw_set_mapped_so_buffers(softpipe->draw, map_buffers, num_buffers);
+ softpipe->num_so_targets = num_targets;
}
-
-
void
softpipe_init_streamout_funcs(struct pipe_context *pipe)
{
-#if 0
- pipe->create_stream_output_state = softpipe_create_stream_output_state;
- pipe->bind_stream_output_state = softpipe_bind_stream_output_state;
- pipe->delete_stream_output_state = softpipe_delete_stream_output_state;
-
- pipe->set_stream_output_buffers = softpipe_set_stream_output_buffers;
-#else
- (void) softpipe_create_stream_output_state;
- (void) softpipe_bind_stream_output_state;
- (void) softpipe_delete_stream_output_state;
- (void) softpipe_set_stream_output_buffers;
-#endif
+ pipe->create_stream_output_target = softpipe_create_so_target;
+ pipe->stream_output_target_destroy = softpipe_so_target_destroy;
+ pipe->set_stream_output_targets = softpipe_set_so_targets;
}