summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c21
-rw-r--r--src/gallium/auxiliary/draw/draw_context.h19
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h4
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_so_emit.c114
-rw-r--r--src/gallium/auxiliary/draw/draw_vbuf.h3
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_exec.c1
-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
15 files changed, 185 insertions, 217 deletions
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index f91e408cbf0..10a20f76178 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -725,16 +725,25 @@ draw_get_rasterizer_no_cull( struct draw_context *draw,
}
void
+draw_set_mapped_so_targets(struct draw_context *draw,
+ int num_targets,
+ struct draw_so_target *targets[PIPE_MAX_SO_BUFFERS])
+{
+ int i;
+
+ for (i = 0; i < num_targets; i++)
+ draw->so.targets[i] = targets[i];
+ for (i = num_targets; i < PIPE_MAX_SO_BUFFERS; i++)
+ draw->so.targets[i] = NULL;
+
+ draw->so.num_targets = num_targets;
+}
+
+void
draw_set_mapped_so_buffers(struct draw_context *draw,
void *buffers[PIPE_MAX_SO_BUFFERS],
unsigned num_buffers)
{
- int i;
-
- for (i = 0; i < num_buffers; ++i) {
- draw->so.buffers[i] = buffers[i];
- }
- draw->so.num_buffers = num_buffers;
}
void
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index 7655ad0a90d..02c176e8f4b 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -50,7 +50,18 @@ struct draw_fragment_shader;
struct tgsi_sampler;
struct gallivm_state;
-
+/*
+ * structure to contain driver internal information
+ * for stream out support. mapping stores the pointer
+ * to the buffer contents, and internal offset stores
+ * stores an internal counter to how much of the stream
+ * out buffer is used (in bytes).
+ */
+struct draw_so_target {
+ struct pipe_stream_output_target target;
+ void *mapping;
+ int internal_offset;
+};
struct draw_context *draw_create( struct pipe_context *pipe );
@@ -202,6 +213,12 @@ void
draw_set_mapped_so_buffers(struct draw_context *draw,
void *buffers[PIPE_MAX_SO_BUFFERS],
unsigned num_buffers);
+
+void
+draw_set_mapped_so_targets(struct draw_context *draw,
+ int num_targets,
+ struct draw_so_target *targets[PIPE_MAX_SO_BUFFERS]);
+
void
draw_set_so_state(struct draw_context *draw,
struct pipe_stream_output_info *state);
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index c0ef18e3ed2..91112eb96b4 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -271,8 +271,8 @@ struct draw_context
/** Stream output (vertex feedback) state */
struct {
struct pipe_stream_output_info state;
- void *buffers[PIPE_MAX_SO_BUFFERS];
- uint num_buffers;
+ struct draw_so_target *targets[PIPE_MAX_SO_BUFFERS];
+ uint num_targets;
} so;
/* Clip derived state:
diff --git a/src/gallium/auxiliary/draw/draw_pt_so_emit.c b/src/gallium/auxiliary/draw/draw_pt_so_emit.c
index 2dc9e299f56..d4182a843ca 100644
--- a/src/gallium/auxiliary/draw/draw_pt_so_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_so_emit.c
@@ -25,29 +25,29 @@
*
**************************************************************************/
-#include "draw/draw_context.h"
#include "draw/draw_private.h"
+#include "draw/draw_vs.h"
+#include "draw/draw_context.h"
#include "draw/draw_vbuf.h"
#include "draw/draw_vertex.h"
#include "draw/draw_pt.h"
+#include "pipe/p_state.h"
+
#include "util/u_math.h"
#include "util/u_memory.h"
struct pt_so_emit {
struct draw_context *draw;
- void *buffers[PIPE_MAX_SO_BUFFERS];
-
unsigned input_vertex_stride;
const float (*inputs)[4];
boolean has_so;
- boolean single_buffer;
-
unsigned emitted_primitives;
unsigned emitted_vertices;
+ unsigned generated_primitives;
};
@@ -55,15 +55,15 @@ void draw_pt_so_emit_prepare(struct pt_so_emit *emit)
{
struct draw_context *draw = emit->draw;
- emit->has_so = (draw->so.state.num_outputs > 0);
+ emit->has_so = (draw->vs.vertex_shader->state.stream_output.num_outputs > 0);
/* if we have a state with outputs make sure we have
* buffers to output to */
if (emit->has_so) {
boolean has_valid_buffer = FALSE;
unsigned i;
- for (i = 0; i < draw->so.num_buffers; ++i) {
- if (draw->so.buffers[i]) {
+ for (i = 0; i < draw->so.num_targets; ++i) {
+ if (draw->so.targets[i]) {
has_valid_buffer = TRUE;
break;
}
@@ -122,6 +122,29 @@ is_component_writable(unsigned mask,
}
}
+static INLINE int mask_num_comps(int register_mask)
+{
+ int comps = 0;
+ switch (register_mask) {
+ case TGSI_WRITEMASK_XYZW:
+ comps = 4;
+ break;
+ case TGSI_WRITEMASK_XYZ:
+ comps = 3;
+ break;
+ case TGSI_WRITEMASK_XY:
+ comps = 2;
+ break;
+ case TGSI_WRITEMASK_X:
+ comps = 1;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ return comps;
+}
+
static void so_emit_prim(struct pt_so_emit *so,
unsigned *indices,
unsigned num_vertices)
@@ -131,57 +154,58 @@ static void so_emit_prim(struct pt_so_emit *so,
struct draw_context *draw = so->draw;
const float (*input_ptr)[4];
const struct pipe_stream_output_info *state =
- &draw->so.state;
- float **buffer = 0;
+ &draw->vs.vertex_shader->state.stream_output;
+ float *buffer;
+ int buffer_total_bytes[PIPE_MAX_SO_BUFFERS];
input_ptr = so->inputs;
+ ++so->generated_primitives;
+
+ for (i = 0; i < draw->so.num_targets; i++) {
+ struct draw_so_target *target = draw->so.targets[i];
+ buffer_total_bytes[i] = target->internal_offset;
+ }
+
+ /* check have we space to emit prim first - if not don't do anything */
+ for (i = 0; i < num_vertices; ++i) {
+ for (slot = 0; slot < state->num_outputs; ++slot) {
+ unsigned writemask = state->output[slot].register_mask;
+ int ob = state->output[slot].output_buffer;
+
+ if ((buffer_total_bytes[ob] + mask_num_comps(writemask) * sizeof(float)) >
+ draw->so.targets[ob]->target.buffer_size) {
+ return;
+ }
+ buffer_total_bytes[ob] += mask_num_comps(writemask) * sizeof(float);
+ }
+ }
+
for (i = 0; i < num_vertices; ++i) {
const float (*input)[4];
unsigned total_written_compos = 0;
/*debug_printf("%d) vertex index = %d (prim idx = %d)\n", i, indices[i], prim_idx);*/
input = (const float (*)[4])(
(const char *)input_ptr + (indices[i] * input_vertex_stride));
+
for (slot = 0; slot < state->num_outputs; ++slot) {
unsigned idx = state->output[slot].register_index;
unsigned writemask = state->output[slot].register_mask;
unsigned written_compos = 0;
unsigned compo;
+ int ob = state->output[slot].output_buffer;
- buffer = (float**)&so->buffers[state->output[slot].output_buffer];
-
- /*debug_printf("\tSlot = %d, vs_slot = %d, idx = %d:\n",
- slot, vs_slot, idx);*/
-#if 1
- assert(!util_is_inf_or_nan(input[idx][0]));
- assert(!util_is_inf_or_nan(input[idx][1]));
- assert(!util_is_inf_or_nan(input[idx][2]));
- assert(!util_is_inf_or_nan(input[idx][3]));
-#endif
+ buffer = (float *)((char *)draw->so.targets[ob]->mapping +
+ draw->so.targets[ob]->target.buffer_offset +
+ draw->so.targets[ob]->internal_offset);
for (compo = 0; compo < 4; ++compo) {
if (is_component_writable(writemask, compo)) {
- float *buf = *buffer;
- buf[written_compos++] = input[idx][compo];
+ buffer[written_compos++] = input[idx][compo];
}
}
-#if 0
- debug_printf("\t\t(writemask = %d)%f %f %f %f\n",
- writemask,
- input[idx][0],
- input[idx][1],
- input[idx][2],
- input[idx][3]);
-#endif
- *buffer += written_compos;
+ draw->so.targets[ob]->internal_offset += written_compos * sizeof(float);
total_written_compos += written_compos;
}
- if (so->single_buffer) {
- int stride = (int)state->stride -
- sizeof(float) * total_written_compos;
-
- debug_assert(stride >= 0);
- *buffer = (float*) (((char*)*buffer) + stride);
- }
}
so->emitted_vertices += num_vertices;
++so->emitted_primitives;
@@ -235,23 +259,18 @@ void draw_pt_so_emit( struct pt_so_emit *emit,
{
struct draw_context *draw = emit->draw;
struct vbuf_render *render = draw->render;
+ struct pipe_stream_output_info *so;
unsigned start, i;
if (!emit->has_so)
return;
+ so = &draw->vs.vertex_shader->state.stream_output;
emit->emitted_vertices = 0;
emit->emitted_primitives = 0;
+ emit->generated_primitives = 0;
emit->input_vertex_stride = input_verts->stride;
emit->inputs = (const float (*)[4])input_verts->verts->data;
- for (i = 0; i < draw->so.num_buffers; ++i) {
- emit->buffers[i] = draw->so.buffers[i];
- }
- emit->single_buffer = TRUE;
- for (i = 0; i < draw->so.state.num_outputs; ++i) {
- if (draw->so.state.output[i].output_buffer != 0)
- emit->single_buffer = FALSE;
- }
/* XXX: need to flush to get prim_vbuf.c to release its allocation??*/
draw_do_flush( draw, DRAW_FLUSH_BACKEND );
@@ -272,7 +291,8 @@ void draw_pt_so_emit( struct pt_so_emit *emit,
render->set_stream_output_info(render,
emit->emitted_primitives,
- emit->emitted_vertices);
+ emit->emitted_vertices,
+ emit->generated_primitives);
}
diff --git a/src/gallium/auxiliary/draw/draw_vbuf.h b/src/gallium/auxiliary/draw/draw_vbuf.h
index 1f1a7b4972f..f10d185868d 100644
--- a/src/gallium/auxiliary/draw/draw_vbuf.h
+++ b/src/gallium/auxiliary/draw/draw_vbuf.h
@@ -124,7 +124,8 @@ struct vbuf_render {
*/
void (*set_stream_output_info)( struct vbuf_render *vbufr,
unsigned primitive_count,
- unsigned vertices_count );
+ unsigned vertices_count,
+ unsigned primitive_generated );
};
diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c
index d9c4209a42b..3f89881534b 100644
--- a/src/gallium/auxiliary/draw/draw_vs_exec.c
+++ b/src/gallium/auxiliary/draw/draw_vs_exec.c
@@ -217,6 +217,7 @@ draw_create_vs_exec(struct draw_context *draw,
tgsi_scan_shader(state->tokens, &vs->base.info);
+ vs->base.state.stream_output = state->stream_output;
vs->base.draw = draw;
vs->base.prepare = vs_exec_prepare;
vs->base.run_linear = vs_exec_run_linear;
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;
}