aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_context.h2
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_so_emit.c10
-rw-r--r--src/gallium/auxiliary/postprocess/pp_run.c1
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.c1
-rw-r--r--src/gallium/auxiliary/util/u_dump_state.c19
-rw-r--r--src/gallium/docs/source/context.rst61
-rw-r--r--src/gallium/docs/source/screen.rst3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_so.c2
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c2
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.c2
-rw-r--r--src/gallium/drivers/nvc0/nvc0_state.c8
-rw-r--r--src/gallium/drivers/r300/r300_screen.c2
-rw-r--r--src/gallium/drivers/r600/r600_pipe.c6
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_state.h2
-rw-r--r--src/gallium/drivers/softpipe/sp_state_so.c13
-rw-r--r--src/gallium/drivers/trace/tr_dump_state.c21
-rw-r--r--src/gallium/include/pipe/p_context.h38
-rw-r--r--src/gallium/include/pipe/p_defines.h10
-rw-r--r--src/gallium/include/pipe/p_state.h85
-rw-r--r--src/gallium/state_trackers/vega/shaders_cache.c1
24 files changed, 210 insertions, 89 deletions
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index a4447936d51..9c00687a9ea 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -722,11 +722,11 @@ draw_set_mapped_so_buffers(struct draw_context *draw,
void
draw_set_so_state(struct draw_context *draw,
- struct pipe_stream_output_state *state)
+ struct pipe_stream_output_info *state)
{
memcpy(&draw->so.state,
state,
- sizeof(struct pipe_stream_output_state));
+ sizeof(struct pipe_stream_output_info));
}
void
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index 799eb94f013..93577d0b8fc 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -202,7 +202,7 @@ draw_set_mapped_so_buffers(struct draw_context *draw,
unsigned num_buffers);
void
draw_set_so_state(struct draw_context *draw,
- struct pipe_stream_output_state *state);
+ 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 3521a035e2f..89653e11161 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -270,7 +270,7 @@ struct draw_context
/** Stream output (vertex feedback) state */
struct {
- struct pipe_stream_output_state state;
+ struct pipe_stream_output_info state;
void *buffers[PIPE_MAX_SO_BUFFERS];
uint num_buffers;
} so;
diff --git a/src/gallium/auxiliary/draw/draw_pt_so_emit.c b/src/gallium/auxiliary/draw/draw_pt_so_emit.c
index c86bdd99a33..2dc9e299f56 100644
--- a/src/gallium/auxiliary/draw/draw_pt_so_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_so_emit.c
@@ -130,7 +130,7 @@ static void so_emit_prim(struct pt_so_emit *so,
unsigned input_vertex_stride = so->input_vertex_stride;
struct draw_context *draw = so->draw;
const float (*input_ptr)[4];
- const struct pipe_stream_output_state *state =
+ const struct pipe_stream_output_info *state =
&draw->so.state;
float **buffer = 0;
@@ -143,12 +143,12 @@ static void so_emit_prim(struct pt_so_emit *so,
input = (const float (*)[4])(
(const char *)input_ptr + (indices[i] * input_vertex_stride));
for (slot = 0; slot < state->num_outputs; ++slot) {
- unsigned idx = state->register_index[slot];
- unsigned writemask = state->register_mask[slot];
+ unsigned idx = state->output[slot].register_index;
+ unsigned writemask = state->output[slot].register_mask;
unsigned written_compos = 0;
unsigned compo;
- buffer = (float**)&so->buffers[state->output_buffer[slot]];
+ buffer = (float**)&so->buffers[state->output[slot].output_buffer];
/*debug_printf("\tSlot = %d, vs_slot = %d, idx = %d:\n",
slot, vs_slot, idx);*/
@@ -249,7 +249,7 @@ void draw_pt_so_emit( struct pt_so_emit *emit,
}
emit->single_buffer = TRUE;
for (i = 0; i < draw->so.state.num_outputs; ++i) {
- if (draw->so.state.output_buffer[i] != 0)
+ if (draw->so.state.output[i].output_buffer != 0)
emit->single_buffer = FALSE;
}
diff --git a/src/gallium/auxiliary/postprocess/pp_run.c b/src/gallium/auxiliary/postprocess/pp_run.c
index de1fe559e49..ab09a5645cc 100644
--- a/src/gallium/auxiliary/postprocess/pp_run.c
+++ b/src/gallium/auxiliary/postprocess/pp_run.c
@@ -144,6 +144,7 @@ pp_tgsi_to_state(struct pipe_context *pipe, const char *text, bool isvs,
}
state.tokens = tokens;
+ memset(&state.stream_output, 0, sizeof(state.stream_output));
if (isvs)
return pipe->create_vs_state(pipe, &state);
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index ee013a5d687..33d285cb64c 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -1597,6 +1597,7 @@ void *ureg_create_shader( struct ureg_program *ureg,
state.tokens = ureg_finalize(ureg);
if(!state.tokens)
return NULL;
+ memset(&state.stream_output, 0, sizeof(state.stream_output));
if (ureg->processor == TGSI_PROCESSOR_VERTEX)
return pipe->create_vs_state( pipe, &state );
diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c
index 917d7cd359b..91f4aae69ef 100644
--- a/src/gallium/auxiliary/util/u_dump_state.c
+++ b/src/gallium/auxiliary/util/u_dump_state.c
@@ -423,6 +423,7 @@ void
util_dump_shader_state(FILE *stream, const struct pipe_shader_state *state)
{
char str[8192];
+ unsigned i;
if(!state) {
util_dump_null(stream);
@@ -437,6 +438,24 @@ util_dump_shader_state(FILE *stream, const struct pipe_shader_state *state)
util_dump_string(stream, str);
util_dump_member_end(stream);
+ util_dump_member_begin(stream, "stream_output");
+ util_dump_struct_begin(stream, "pipe_stream_output_info");
+ util_dump_member(stream, uint, &state->stream_output, num_outputs);
+ util_dump_member(stream, uint, &state->stream_output, stride);
+ util_dump_array_begin(stream);
+ for(i = 0; i < state->stream_output.num_outputs; ++i) {
+ util_dump_elem_begin(stream);
+ util_dump_struct_begin(stream, ""); /* anonymous */
+ util_dump_member(stream, uint, &state->stream_output.output[i], register_index);
+ util_dump_member(stream, uint, &state->stream_output.output[i], register_mask);
+ util_dump_member(stream, uint, &state->stream_output.output[i], output_buffer);
+ util_dump_struct_end(stream);
+ util_dump_elem_end(stream);
+ }
+ util_dump_array_end(stream);
+ util_dump_struct_end(stream);
+ util_dump_member_end(stream);
+
util_dump_struct_end(stream);
}
diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst
index 391139fb0ef..b2872cd282f 100644
--- a/src/gallium/docs/source/context.rst
+++ b/src/gallium/docs/source/context.rst
@@ -54,8 +54,6 @@ buffers, surfaces) are bound to the driver.
* ``set_index_buffer``
-* ``set_stream_output_buffers``
-
Non-CSO State
^^^^^^^^^^^^^
@@ -139,6 +137,47 @@ cube, and 3d textures otherwise they are 0.
* ``surface_destroy`` destroys a surface and releases its reference to the
associated resource.
+Stream output targets
+^^^^^^^^^^^^^^^^^^^^^
+
+Stream output, also known as transform feedback, allows writing the primitives
+produced by the vertex pipeline to buffers. This is done after the geometry
+shader or vertex shader if no geometry shader is present.
+
+The stream output targets are views into buffer resources which can be bound
+as stream outputs and specify a memory range where it's valid to write
+primitives. The pipe driver must implement memory protection such that any
+primitives written outside of the specified memory range are discarded.
+
+Two stream output targets can use the same resource at the same time, but
+with a disjoint memory range.
+
+Additionally, the stream output target internally maintains the offset
+into the buffer which is incremented everytime something is written to it.
+The internal offset is equal to how much data has already been written.
+It can be stored in device memory and the CPU actually doesn't have to query
+it.
+
+The stream output target can be used in a draw command to provide
+the vertex count. The vertex count is derived from the internal offset
+discussed above.
+
+* ``create_stream_output_target`` create a new target.
+
+* ``stream_output_target_destroy`` destroys a target. Users of this should
+ use pipe_so_target_reference instead.
+
+* ``set_stream_output_targets`` binds stream output targets. The parameter
+ append_bitmask is a bitmask, where the i-th bit specifies whether new
+ primitives should be appended to the i-th buffer (writing starts at
+ the internal offset), or whether writing should start at the beginning
+ (the internal offset is effectively set to 0).
+
+NOTE: The currently-bound vertex or geometry shader must be compiled with
+the properly-filled-in structure pipe_stream_output_info describing which
+outputs should be written to buffers and how. The structure is part of
+pipe_shader_state.
+
Clearing
^^^^^^^^
@@ -394,24 +433,6 @@ The interfaces to these calls are likely to change to make it easier
for a driver to batch multiple blits with the same source and
destination.
-
-Stream Output
-^^^^^^^^^^^^^
-
-Stream output, also known as transform feedback allows writing the results of the
-vertex pipeline (after the geometry shader or vertex shader if no geometry shader
-is present) to be written to a buffer created with a ``PIPE_BIND_STREAM_OUTPUT``
-flag.
-
-First a stream output state needs to be created with the
-``create_stream_output_state`` call. It specific the details of what's being written,
-to which buffer and with what kind of a writemask.
-
-Then target buffers needs to be set with the call to ``set_stream_output_buffers``
-which sets the buffers and the offsets from the start of those buffer to where
-the data will be written to.
-
-
Transfers
^^^^^^^^^
diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst
index 8b504201b3e..a1cd075e309 100644
--- a/src/gallium/docs/source/screen.rst
+++ b/src/gallium/docs/source/screen.rst
@@ -51,6 +51,8 @@ The integer capabilities:
from color blend equations, in :ref:`Blend` state.
* ``PIPE_CAP_SM3``: Whether the vertex shader and fragment shader support equivalent
opcodes to the Shader Model 3 specification. XXX oh god this is horrible
+* ``PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS``: The maximum number of stream buffers.
+* ``PIPE_CAP_PRIMITIVE_RESTART``: Whether primitive restart is supported.
* ``PIPE_CAP_MAX_COMBINED_SAMPLERS``: The total number of samplers accessible from
the vertex and fragment shader, inclusive.
* ``PIPE_CAP_INDEP_BLEND_ENABLE``: Whether per-rendertarget blend enabling and channel
@@ -179,6 +181,7 @@ resources might be created and handled quite differently.
* ``PIPE_BIND_CONSTANT_BUFFER``: A buffer of shader constants.
* ``PIPE_BIND_TRANSFER_WRITE``: A transfer object which will be written to.
* ``PIPE_BIND_TRANSFER_READ``: A transfer object which will be read from.
+* ``PIPE_BIND_STREAM_OUTPUT``: A stream output buffer.
* ``PIPE_BIND_CUSTOM``:
* ``PIPE_BIND_SCANOUT``: A front color buffer or scanout buffer.
* ``PIPE_BIND_SHARED``: A sharable buffer that can be given to another
diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h
index 7893e9cdc0c..97ca1727c9b 100644
--- a/src/gallium/drivers/llvmpipe/lp_state.h
+++ b/src/gallium/drivers/llvmpipe/lp_state.h
@@ -86,7 +86,7 @@ struct lp_velems_state
};
struct lp_so_state {
- struct pipe_stream_output_state base;
+ struct pipe_stream_output_info base;
};
diff --git a/src/gallium/drivers/llvmpipe/lp_state_so.c b/src/gallium/drivers/llvmpipe/lp_state_so.c
index 35de52c6c99..4874bd65a96 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_so.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_so.c
@@ -35,7 +35,7 @@
static void *
llvmpipe_create_stream_output_state(struct pipe_context *pipe,
- const struct pipe_stream_output_state *templ)
+ const struct pipe_stream_output_info *templ)
{
struct lp_so_state *so;
so = (struct lp_so_state *) CALLOC_STRUCT(lp_so_state);
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index f1dec3527d2..15f579efb86 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -116,7 +116,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_TIMER_QUERY:
case PIPE_CAP_OCCLUSION_QUERY:
return 1;
- case PIPE_CAP_STREAM_OUTPUT:
+ case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
return 0;
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
case PIPE_CAP_INDEP_BLEND_ENABLE:
diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c
index 190737e224b..43fcc617910 100644
--- a/src/gallium/drivers/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nvc0/nvc0_screen.c
@@ -105,7 +105,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_TIMER_QUERY:
case PIPE_CAP_OCCLUSION_QUERY:
return 1;
- case PIPE_CAP_STREAM_OUTPUT:
+ case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
return 0;
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
case PIPE_CAP_INDEP_BLEND_ENABLE:
diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c
index 0d6952dd9b4..63d53ab70d0 100644
--- a/src/gallium/drivers/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nvc0/nvc0_state.c
@@ -749,7 +749,7 @@ nvc0_vertex_state_bind(struct pipe_context *pipe, void *hwcso)
static void *
nvc0_tfb_state_create(struct pipe_context *pipe,
- const struct pipe_stream_output_state *pso)
+ const struct pipe_stream_output_info *pso)
{
struct nvc0_transform_feedback_state *so;
int n = 0;
@@ -761,13 +761,13 @@ nvc0_tfb_state_create(struct pipe_context *pipe,
for (b = 0; b < 4; ++b) {
for (i = 0; i < pso->num_outputs; ++i) {
- if (pso->output_buffer[i] != b)
+ if (pso->output[i].output_buffer != b)
continue;
for (c = 0; c < 4; ++c) {
- if (!(pso->register_mask[i] & (1 << c)))
+ if (!(pso->output[i].register_mask & (1 << c)))
continue;
so->varying_count[b]++;
- so->varying_index[n++] = (pso->register_index[i] << 2) | c;
+ so->varying_index[n++] = (pso->output[i].register_index << 2) | c;
}
}
so->stride[b] = so->varying_count[b] * 4;
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 0bae065176a..f3030b2c6c9 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -131,7 +131,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_SCALED_RESOLVE:
case PIPE_CAP_MIN_TEXEL_OFFSET:
case PIPE_CAP_MAX_TEXEL_OFFSET:
- case PIPE_CAP_STREAM_OUTPUT:
+ case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
return 0;
/* SWTCL-only features. */
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index ddea167e86a..97c6808260d 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -391,7 +391,11 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
return family >= CHIP_CEDAR ? 1 : 0;
/* Unsupported features. */
- case PIPE_CAP_STREAM_OUTPUT:
+ case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
+ case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_ATTRIBS:
+ case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
+ case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
+ case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
case PIPE_CAP_TGSI_INSTANCEID:
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index ef98f25c477..49e8626b0d4 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -105,7 +105,7 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
return 1;
- case PIPE_CAP_STREAM_OUTPUT:
+ case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
return 0;
case PIPE_CAP_PRIMITIVE_RESTART:
return 1;
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index ec4c8cf5e4d..bdda29495b2 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -122,7 +122,7 @@ struct sp_velems_state {
};
struct sp_so_state {
- struct pipe_stream_output_state base;
+ struct pipe_stream_output_info base;
};
diff --git a/src/gallium/drivers/softpipe/sp_state_so.c b/src/gallium/drivers/softpipe/sp_state_so.c
index 40e563457d9..31ef3841294 100644
--- a/src/gallium/drivers/softpipe/sp_state_so.c
+++ b/src/gallium/drivers/softpipe/sp_state_so.c
@@ -36,7 +36,7 @@
static void *
softpipe_create_stream_output_state(struct pipe_context *pipe,
- const struct pipe_stream_output_state *templ)
+ const struct pipe_stream_output_info *templ)
{
struct sp_so_state *so;
so = (struct sp_so_state *) CALLOC_STRUCT(sp_so_state);
@@ -44,15 +44,8 @@ softpipe_create_stream_output_state(struct pipe_context *pipe,
if (so) {
so->base.num_outputs = templ->num_outputs;
so->base.stride = templ->stride;
- memcpy(so->base.output_buffer,
- templ->output_buffer,
- sizeof(int) * templ->num_outputs);
- memcpy(so->base.register_index,
- templ->register_index,
- sizeof(int) * templ->num_outputs);
- memcpy(so->base.register_mask,
- templ->register_mask,
- sizeof(ubyte) * templ->num_outputs);
+ memcpy(so->base.output, templ->output,
+ templ->num_outputs * sizeof(templ->output[0]));
}
return so;
}
diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c
index cbe4cb6b8c4..b1fec2d3bf6 100644
--- a/src/gallium/drivers/trace/tr_dump_state.c
+++ b/src/gallium/drivers/trace/tr_dump_state.c
@@ -250,6 +250,7 @@ void trace_dump_clip_state(const struct pipe_clip_state *state)
void trace_dump_shader_state(const struct pipe_shader_state *state)
{
static char str[8192];
+ unsigned i;
if (!trace_dumping_enabled_locked())
return;
@@ -267,6 +268,24 @@ void trace_dump_shader_state(const struct pipe_shader_state *state)
trace_dump_string(str);
trace_dump_member_end();
+ trace_dump_member_begin("stream_output");
+ trace_dump_struct_begin("pipe_stream_output_info");
+ trace_dump_member(uint, &state->stream_output, num_outputs);
+ trace_dump_member(uint, &state->stream_output, stride);
+ trace_dump_array_begin();
+ for(i = 0; i < state->stream_output.num_outputs; ++i) {
+ trace_dump_elem_begin();
+ trace_dump_struct_begin(""); /* anonymous */
+ trace_dump_member(uint, &state->stream_output.output[i], register_index);
+ trace_dump_member(uint, &state->stream_output.output[i], register_mask);
+ trace_dump_member(uint, &state->stream_output.output[i], output_buffer);
+ trace_dump_struct_end();
+ trace_dump_elem_end();
+ }
+ trace_dump_array_end();
+ trace_dump_struct_end();
+ trace_dump_member_end();
+
trace_dump_struct_end();
}
@@ -660,5 +679,7 @@ void trace_dump_draw_info(const struct pipe_draw_info *state)
trace_dump_member(uint, state, min_index);
trace_dump_member(uint, state, max_index);
+ trace_dump_member(ptr, state, count_from_stream_output);
+
trace_dump_struct_end();
}
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index b2d5f9543e6..de79a9bfff1 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -56,7 +56,7 @@ struct pipe_sampler_view;
struct pipe_scissor_state;
struct pipe_shader_state;
struct pipe_stencil_ref;
-struct pipe_stream_output_state;
+struct pipe_stream_output_target;
struct pipe_surface;
struct pipe_vertex_buffer;
struct pipe_vertex_element;
@@ -86,11 +86,6 @@ struct pipe_context {
/*@{*/
void (*draw_vbo)( struct pipe_context *pipe,
const struct pipe_draw_info *info );
-
- /**
- * Draw the stream output buffer at index 0
- */
- void (*draw_stream_output)( struct pipe_context *pipe, unsigned mode );
/*@}*/
/**
@@ -179,11 +174,6 @@ struct pipe_context {
void (*bind_vertex_elements_state)(struct pipe_context *, void *);
void (*delete_vertex_elements_state)(struct pipe_context *, void *);
- void * (*create_stream_output_state)(struct pipe_context *,
- const struct pipe_stream_output_state *);
- void (*bind_stream_output_state)(struct pipe_context *, void *);
- void (*delete_stream_output_state)(struct pipe_context*, void*);
-
/*@}*/
/**
@@ -237,12 +227,26 @@ struct pipe_context {
void (*set_index_buffer)( struct pipe_context *pipe,
const struct pipe_index_buffer * );
- void (*set_stream_output_buffers)(struct pipe_context *,
- struct pipe_resource **buffers,
- int *offsets, /*array of offsets
- from the start of each
- of the buffers */
- int num_buffers);
+ /*@}*/
+
+ /**
+ * Stream output functions.
+ */
+ /*@{*/
+
+ struct pipe_stream_output_target *(*create_stream_output_target)(
+ struct pipe_context *,
+ struct pipe_resource *,
+ unsigned buffer_offset,
+ unsigned buffer_size);
+
+ void (*stream_output_target_destroy)(struct pipe_context *,
+ struct pipe_stream_output_target *);
+
+ void (*set_stream_output_targets)(struct pipe_context *,
+ unsigned num_targets,
+ struct pipe_stream_output_target **targets,
+ unsigned append_bitmask);
/*@}*/
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 30f1d7fb964..800a04cd8f0 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -438,7 +438,7 @@ enum pipe_cap {
PIPE_CAP_TEXTURE_MIRROR_CLAMP = 25,
PIPE_CAP_BLEND_EQUATION_SEPARATE = 28,
PIPE_CAP_SM3 = 29, /*< Shader Model, supported */
- PIPE_CAP_STREAM_OUTPUT = 30,
+ PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS = 30,
PIPE_CAP_PRIMITIVE_RESTART = 31,
/** Maximum texture image units accessible from vertex and fragment shaders
* combined */
@@ -466,8 +466,12 @@ enum pipe_cap {
PIPE_CAP_MAX_TEXEL_OFFSET = 51,
PIPE_CAP_CONDITIONAL_RENDER = 52,
PIPE_CAP_TEXTURE_BARRIER = 53,
- PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS = 54, /* temporary */
- PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS = 55 /* temporary */
+ PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_ATTRIBS = 54,
+ PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS = 55,
+ PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS = 56,
+ PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME = 57,
+ PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS = 58, /* temporary */
+ PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS = 59 /* temporary */
};
/**
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 37e0679e15f..f943ca58b88 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -121,6 +121,12 @@ struct pipe_rasterizer_state
*/
unsigned gl_rasterization_rules:1;
+ /**
+ * When true, rasterization is disabled and no pixels are written.
+ * This only makes sense with the Stream Out functionality.
+ */
+ unsigned rasterizer_discard:1;
+
unsigned line_stipple_factor:8; /**< [1..256] actually */
unsigned line_stipple_pattern:16;
@@ -164,9 +170,30 @@ struct pipe_clip_state
};
+/**
+ * Stream output for vertex transform feedback.
+ */
+struct pipe_stream_output_info
+{
+ unsigned num_outputs;
+ /** stride for an entire vertex, only used if all output_buffers are 0 */
+ unsigned stride;
+ /**
+ * Array of stream outputs, in the order they are to be written in.
+ * Selected components are tightly packed into the output buffer.
+ */
+ struct {
+ unsigned register_index:8; /**< 0 to PIPE_MAX_SHADER_OUTPUTS */
+ unsigned register_mask:4; /**< TGSI_WRITEMASK_x */
+ unsigned output_buffer:4; /**< 0 to PIPE_MAX_SO_BUFFERS */
+ } output[PIPE_MAX_SHADER_OUTPUTS];
+};
+
+
struct pipe_shader_state
{
const struct tgsi_token *tokens;
+ struct pipe_stream_output_info stream_output;
};
@@ -375,24 +402,6 @@ struct pipe_resource
/**
- * Stream output for vertex transform feedback.
- */
-struct pipe_stream_output_state
-{
- /** number of the output buffer to insert each element into */
- int output_buffer[PIPE_MAX_SHADER_OUTPUTS];
- /** which register to grab each output from */
- int register_index[PIPE_MAX_SHADER_OUTPUTS];
- /** TGSI_WRITEMASK signifying which components to output */
- ubyte register_mask[PIPE_MAX_SHADER_OUTPUTS];
- /** number of outputs */
- int num_outputs;
- /** stride for an entire vertex, only used if all output_buffers are 0 */
- unsigned stride;
-};
-
-
-/**
* Transfer object. For data transfer to/from a resource.
*/
struct pipe_transfer
@@ -422,6 +431,30 @@ struct pipe_vertex_buffer
/**
+ * A stream output target. The structure specifies the range vertices can
+ * be written to.
+ *
+ * In addition to that, the structure should internally maintain the offset
+ * into the buffer, which should be incremented everytime something is written
+ * (appended) to it. The internal offset is buffer_offset + how many bytes
+ * have been written. The internal offset can be stored on the device
+ * and the CPU actually doesn't have to query it.
+ *
+ * Use PIPE_QUERY_SO_STATISTICS to know how many primitives have
+ * actually been written.
+ */
+struct pipe_stream_output_target
+{
+ struct pipe_reference reference;
+ struct pipe_resource *buffer; /**< buffer into which this is a target view */
+ struct pipe_context *context; /**< context this view belongs to */
+
+ unsigned buffer_offset; /**< offset where data should be written, in bytes */
+ unsigned buffer_size; /**< how much data is allowed to be written */
+};
+
+
+/**
* Information to describe a vertex attribute (position, color, etc)
*/
struct pipe_vertex_element
@@ -481,6 +514,22 @@ struct pipe_draw_info
*/
boolean primitive_restart;
unsigned restart_index;
+
+ /**
+ * Stream output target. If not NULL, it's used to provide the 'count'
+ * parameter based on the number vertices captured by the stream output
+ * stage. (or generally, based on the number of bytes captured)
+ *
+ * Only 'mode', 'start_instance', and 'instance_count' are taken into
+ * account, all the other variables from pipe_draw_info are ignored.
+ *
+ * 'start' is implicitly 0 and 'count' is set as discussed above.
+ * The draw command is non-indexed.
+ *
+ * Note that this only provides the count. The vertex buffers must
+ * be set via set_vertex_buffers manually.
+ */
+ struct pipe_stream_output_target *count_from_stream_output;
};
diff --git a/src/gallium/state_trackers/vega/shaders_cache.c b/src/gallium/state_trackers/vega/shaders_cache.c
index 70d860ddc8e..dac1a7406c6 100644
--- a/src/gallium/state_trackers/vega/shaders_cache.c
+++ b/src/gallium/state_trackers/vega/shaders_cache.c
@@ -441,6 +441,7 @@ struct vg_shader * shader_create_from_text(struct pipe_context *pipe,
type == PIPE_SHADER_FRAGMENT);
state.tokens = tokens;
+ memset(&state.stream_output, 0, sizeof(state.stream_output));
shader->type = type;
shader->tokens = tokens;