aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/softpipe
diff options
context:
space:
mode:
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;
}