gallium: interface changes necessary to implement transform feedback (v5)
Namely: - EXT_transform_feedback - ARB_transform_feedback2 - ARB_transform_feedback_instanced The old interface was not useful for OpenGL and had to be reworked. This interface was originally designed for OpenGL, but additional changes have been made in order to make st/d3d1x support easier. The most notable change is the stream-out info must be linked with a vertex or geometry shader and cannot be set independently. This is due to limitations of existing hardware (special shader instructions must be used to write into stream-out buffers), and it's also how OpenGL works (stream outputs must be specified prior to linking shaders). Other than that, each stream output buffer has a "view" into it that internally maintains the number of bytes which have been written into it. (one buffer can be bound in several different transform feedback objects in OpenGL, so we must be able to have several views around) The set_stream_output_targets function contains a parameter saying whether new data should be appended or not. Also, the view can optionally be used to provide the vertex count for draw_vbo. Note that the count is supposed to be stored in device memory and the CPU never gets to know its value. OpenGL way | Gallium way ------------------------------------ BeginTF = set_so_targets(append_bitmask = 0) PauseTF = set_so_targets(num_targets = 0) ResumeTF = set_so_targets(append_bitmask = ~0) EndTF = set_so_targets(num_targets = 0) DrawTF = use pipe_draw_info::count_from_stream_output v2: * removed the reset_stream_output_targets function * added a parameter append_bitmask to set_stream_output_targets, each bit specifies whether new data should be appended to each buffer or not. v3: * added PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME for ARB_tfb2, note that the draw-auto subset is always required (for d3d10), only the pause/resume functionality is limited if the CAP is not advertised v4: * update gallium/docs v5: * compactified struct pipe_stream_output_info, updated dump/trace
This commit is contained in:

committed by
Christoph Bumiller

parent
4f4a1be200
commit
861a029ddb
@@ -722,11 +722,11 @@ draw_set_mapped_so_buffers(struct draw_context *draw,
|
|||||||
|
|
||||||
void
|
void
|
||||||
draw_set_so_state(struct draw_context *draw,
|
draw_set_so_state(struct draw_context *draw,
|
||||||
struct pipe_stream_output_state *state)
|
struct pipe_stream_output_info *state)
|
||||||
{
|
{
|
||||||
memcpy(&draw->so.state,
|
memcpy(&draw->so.state,
|
||||||
state,
|
state,
|
||||||
sizeof(struct pipe_stream_output_state));
|
sizeof(struct pipe_stream_output_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@@ -202,7 +202,7 @@ draw_set_mapped_so_buffers(struct draw_context *draw,
|
|||||||
unsigned num_buffers);
|
unsigned num_buffers);
|
||||||
void
|
void
|
||||||
draw_set_so_state(struct draw_context *draw,
|
draw_set_so_state(struct draw_context *draw,
|
||||||
struct pipe_stream_output_state *state);
|
struct pipe_stream_output_info *state);
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@@ -270,7 +270,7 @@ struct draw_context
|
|||||||
|
|
||||||
/** Stream output (vertex feedback) state */
|
/** Stream output (vertex feedback) state */
|
||||||
struct {
|
struct {
|
||||||
struct pipe_stream_output_state state;
|
struct pipe_stream_output_info state;
|
||||||
void *buffers[PIPE_MAX_SO_BUFFERS];
|
void *buffers[PIPE_MAX_SO_BUFFERS];
|
||||||
uint num_buffers;
|
uint num_buffers;
|
||||||
} so;
|
} so;
|
||||||
|
@@ -130,7 +130,7 @@ static void so_emit_prim(struct pt_so_emit *so,
|
|||||||
unsigned input_vertex_stride = so->input_vertex_stride;
|
unsigned input_vertex_stride = so->input_vertex_stride;
|
||||||
struct draw_context *draw = so->draw;
|
struct draw_context *draw = so->draw;
|
||||||
const float (*input_ptr)[4];
|
const float (*input_ptr)[4];
|
||||||
const struct pipe_stream_output_state *state =
|
const struct pipe_stream_output_info *state =
|
||||||
&draw->so.state;
|
&draw->so.state;
|
||||||
float **buffer = 0;
|
float **buffer = 0;
|
||||||
|
|
||||||
@@ -143,12 +143,12 @@ static void so_emit_prim(struct pt_so_emit *so,
|
|||||||
input = (const float (*)[4])(
|
input = (const float (*)[4])(
|
||||||
(const char *)input_ptr + (indices[i] * input_vertex_stride));
|
(const char *)input_ptr + (indices[i] * input_vertex_stride));
|
||||||
for (slot = 0; slot < state->num_outputs; ++slot) {
|
for (slot = 0; slot < state->num_outputs; ++slot) {
|
||||||
unsigned idx = state->register_index[slot];
|
unsigned idx = state->output[slot].register_index;
|
||||||
unsigned writemask = state->register_mask[slot];
|
unsigned writemask = state->output[slot].register_mask;
|
||||||
unsigned written_compos = 0;
|
unsigned written_compos = 0;
|
||||||
unsigned compo;
|
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",
|
/*debug_printf("\tSlot = %d, vs_slot = %d, idx = %d:\n",
|
||||||
slot, vs_slot, idx);*/
|
slot, vs_slot, idx);*/
|
||||||
@@ -249,7 +249,7 @@ void draw_pt_so_emit( struct pt_so_emit *emit,
|
|||||||
}
|
}
|
||||||
emit->single_buffer = TRUE;
|
emit->single_buffer = TRUE;
|
||||||
for (i = 0; i < draw->so.state.num_outputs; ++i) {
|
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;
|
emit->single_buffer = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -144,6 +144,7 @@ pp_tgsi_to_state(struct pipe_context *pipe, const char *text, bool isvs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
state.tokens = tokens;
|
state.tokens = tokens;
|
||||||
|
memset(&state.stream_output, 0, sizeof(state.stream_output));
|
||||||
|
|
||||||
if (isvs)
|
if (isvs)
|
||||||
return pipe->create_vs_state(pipe, &state);
|
return pipe->create_vs_state(pipe, &state);
|
||||||
|
@@ -1597,6 +1597,7 @@ void *ureg_create_shader( struct ureg_program *ureg,
|
|||||||
state.tokens = ureg_finalize(ureg);
|
state.tokens = ureg_finalize(ureg);
|
||||||
if(!state.tokens)
|
if(!state.tokens)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
memset(&state.stream_output, 0, sizeof(state.stream_output));
|
||||||
|
|
||||||
if (ureg->processor == TGSI_PROCESSOR_VERTEX)
|
if (ureg->processor == TGSI_PROCESSOR_VERTEX)
|
||||||
return pipe->create_vs_state( pipe, &state );
|
return pipe->create_vs_state( pipe, &state );
|
||||||
|
@@ -423,6 +423,7 @@ void
|
|||||||
util_dump_shader_state(FILE *stream, const struct pipe_shader_state *state)
|
util_dump_shader_state(FILE *stream, const struct pipe_shader_state *state)
|
||||||
{
|
{
|
||||||
char str[8192];
|
char str[8192];
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
if(!state) {
|
if(!state) {
|
||||||
util_dump_null(stream);
|
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_string(stream, str);
|
||||||
util_dump_member_end(stream);
|
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);
|
util_dump_struct_end(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -54,8 +54,6 @@ buffers, surfaces) are bound to the driver.
|
|||||||
|
|
||||||
* ``set_index_buffer``
|
* ``set_index_buffer``
|
||||||
|
|
||||||
* ``set_stream_output_buffers``
|
|
||||||
|
|
||||||
|
|
||||||
Non-CSO State
|
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
|
* ``surface_destroy`` destroys a surface and releases its reference to the
|
||||||
associated resource.
|
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
|
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
|
for a driver to batch multiple blits with the same source and
|
||||||
destination.
|
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
|
Transfers
|
||||||
^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
|
||||||
|
@@ -51,6 +51,8 @@ The integer capabilities:
|
|||||||
from color blend equations, in :ref:`Blend` state.
|
from color blend equations, in :ref:`Blend` state.
|
||||||
* ``PIPE_CAP_SM3``: Whether the vertex shader and fragment shader support equivalent
|
* ``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
|
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
|
* ``PIPE_CAP_MAX_COMBINED_SAMPLERS``: The total number of samplers accessible from
|
||||||
the vertex and fragment shader, inclusive.
|
the vertex and fragment shader, inclusive.
|
||||||
* ``PIPE_CAP_INDEP_BLEND_ENABLE``: Whether per-rendertarget blend enabling and channel
|
* ``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_CONSTANT_BUFFER``: A buffer of shader constants.
|
||||||
* ``PIPE_BIND_TRANSFER_WRITE``: A transfer object which will be written to.
|
* ``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_TRANSFER_READ``: A transfer object which will be read from.
|
||||||
|
* ``PIPE_BIND_STREAM_OUTPUT``: A stream output buffer.
|
||||||
* ``PIPE_BIND_CUSTOM``:
|
* ``PIPE_BIND_CUSTOM``:
|
||||||
* ``PIPE_BIND_SCANOUT``: A front color buffer or scanout buffer.
|
* ``PIPE_BIND_SCANOUT``: A front color buffer or scanout buffer.
|
||||||
* ``PIPE_BIND_SHARED``: A sharable buffer that can be given to another
|
* ``PIPE_BIND_SHARED``: A sharable buffer that can be given to another
|
||||||
|
@@ -86,7 +86,7 @@ struct lp_velems_state
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct lp_so_state {
|
struct lp_so_state {
|
||||||
struct pipe_stream_output_state base;
|
struct pipe_stream_output_info base;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
static void *
|
static void *
|
||||||
llvmpipe_create_stream_output_state(struct pipe_context *pipe,
|
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;
|
struct lp_so_state *so;
|
||||||
so = (struct lp_so_state *) CALLOC_STRUCT(lp_so_state);
|
so = (struct lp_so_state *) CALLOC_STRUCT(lp_so_state);
|
||||||
|
@@ -116,7 +116,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||||||
case PIPE_CAP_TIMER_QUERY:
|
case PIPE_CAP_TIMER_QUERY:
|
||||||
case PIPE_CAP_OCCLUSION_QUERY:
|
case PIPE_CAP_OCCLUSION_QUERY:
|
||||||
return 1;
|
return 1;
|
||||||
case PIPE_CAP_STREAM_OUTPUT:
|
case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
|
||||||
return 0;
|
return 0;
|
||||||
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
|
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
|
||||||
case PIPE_CAP_INDEP_BLEND_ENABLE:
|
case PIPE_CAP_INDEP_BLEND_ENABLE:
|
||||||
|
@@ -105,7 +105,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
|||||||
case PIPE_CAP_TIMER_QUERY:
|
case PIPE_CAP_TIMER_QUERY:
|
||||||
case PIPE_CAP_OCCLUSION_QUERY:
|
case PIPE_CAP_OCCLUSION_QUERY:
|
||||||
return 1;
|
return 1;
|
||||||
case PIPE_CAP_STREAM_OUTPUT:
|
case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
|
||||||
return 0;
|
return 0;
|
||||||
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
|
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
|
||||||
case PIPE_CAP_INDEP_BLEND_ENABLE:
|
case PIPE_CAP_INDEP_BLEND_ENABLE:
|
||||||
|
@@ -749,7 +749,7 @@ nvc0_vertex_state_bind(struct pipe_context *pipe, void *hwcso)
|
|||||||
|
|
||||||
static void *
|
static void *
|
||||||
nvc0_tfb_state_create(struct pipe_context *pipe,
|
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;
|
struct nvc0_transform_feedback_state *so;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
@@ -761,13 +761,13 @@ nvc0_tfb_state_create(struct pipe_context *pipe,
|
|||||||
|
|
||||||
for (b = 0; b < 4; ++b) {
|
for (b = 0; b < 4; ++b) {
|
||||||
for (i = 0; i < pso->num_outputs; ++i) {
|
for (i = 0; i < pso->num_outputs; ++i) {
|
||||||
if (pso->output_buffer[i] != b)
|
if (pso->output[i].output_buffer != b)
|
||||||
continue;
|
continue;
|
||||||
for (c = 0; c < 4; ++c) {
|
for (c = 0; c < 4; ++c) {
|
||||||
if (!(pso->register_mask[i] & (1 << c)))
|
if (!(pso->output[i].register_mask & (1 << c)))
|
||||||
continue;
|
continue;
|
||||||
so->varying_count[b]++;
|
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;
|
so->stride[b] = so->varying_count[b] * 4;
|
||||||
|
@@ -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_SCALED_RESOLVE:
|
||||||
case PIPE_CAP_MIN_TEXEL_OFFSET:
|
case PIPE_CAP_MIN_TEXEL_OFFSET:
|
||||||
case PIPE_CAP_MAX_TEXEL_OFFSET:
|
case PIPE_CAP_MAX_TEXEL_OFFSET:
|
||||||
case PIPE_CAP_STREAM_OUTPUT:
|
case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* SWTCL-only features. */
|
/* SWTCL-only features. */
|
||||||
|
@@ -391,7 +391,11 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
|
|||||||
return family >= CHIP_CEDAR ? 1 : 0;
|
return family >= CHIP_CEDAR ? 1 : 0;
|
||||||
|
|
||||||
/* Unsupported features. */
|
/* 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_INSTANCEID:
|
||||||
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
|
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
|
||||||
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
|
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
|
||||||
|
@@ -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_HALF_INTEGER:
|
||||||
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
|
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
|
||||||
return 1;
|
return 1;
|
||||||
case PIPE_CAP_STREAM_OUTPUT:
|
case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
|
||||||
return 0;
|
return 0;
|
||||||
case PIPE_CAP_PRIMITIVE_RESTART:
|
case PIPE_CAP_PRIMITIVE_RESTART:
|
||||||
return 1;
|
return 1;
|
||||||
|
@@ -122,7 +122,7 @@ struct sp_velems_state {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct sp_so_state {
|
struct sp_so_state {
|
||||||
struct pipe_stream_output_state base;
|
struct pipe_stream_output_info base;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
static void *
|
static void *
|
||||||
softpipe_create_stream_output_state(struct pipe_context *pipe,
|
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;
|
struct sp_so_state *so;
|
||||||
so = (struct sp_so_state *) CALLOC_STRUCT(sp_so_state);
|
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) {
|
if (so) {
|
||||||
so->base.num_outputs = templ->num_outputs;
|
so->base.num_outputs = templ->num_outputs;
|
||||||
so->base.stride = templ->stride;
|
so->base.stride = templ->stride;
|
||||||
memcpy(so->base.output_buffer,
|
memcpy(so->base.output, templ->output,
|
||||||
templ->output_buffer,
|
templ->num_outputs * sizeof(templ->output[0]));
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
return so;
|
return so;
|
||||||
}
|
}
|
||||||
|
@@ -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)
|
void trace_dump_shader_state(const struct pipe_shader_state *state)
|
||||||
{
|
{
|
||||||
static char str[8192];
|
static char str[8192];
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
if (!trace_dumping_enabled_locked())
|
if (!trace_dumping_enabled_locked())
|
||||||
return;
|
return;
|
||||||
@@ -267,6 +268,24 @@ void trace_dump_shader_state(const struct pipe_shader_state *state)
|
|||||||
trace_dump_string(str);
|
trace_dump_string(str);
|
||||||
trace_dump_member_end();
|
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();
|
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, min_index);
|
||||||
trace_dump_member(uint, state, max_index);
|
trace_dump_member(uint, state, max_index);
|
||||||
|
|
||||||
|
trace_dump_member(ptr, state, count_from_stream_output);
|
||||||
|
|
||||||
trace_dump_struct_end();
|
trace_dump_struct_end();
|
||||||
}
|
}
|
||||||
|
@@ -56,7 +56,7 @@ struct pipe_sampler_view;
|
|||||||
struct pipe_scissor_state;
|
struct pipe_scissor_state;
|
||||||
struct pipe_shader_state;
|
struct pipe_shader_state;
|
||||||
struct pipe_stencil_ref;
|
struct pipe_stencil_ref;
|
||||||
struct pipe_stream_output_state;
|
struct pipe_stream_output_target;
|
||||||
struct pipe_surface;
|
struct pipe_surface;
|
||||||
struct pipe_vertex_buffer;
|
struct pipe_vertex_buffer;
|
||||||
struct pipe_vertex_element;
|
struct pipe_vertex_element;
|
||||||
@@ -86,11 +86,6 @@ struct pipe_context {
|
|||||||
/*@{*/
|
/*@{*/
|
||||||
void (*draw_vbo)( struct pipe_context *pipe,
|
void (*draw_vbo)( struct pipe_context *pipe,
|
||||||
const struct pipe_draw_info *info );
|
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 (*bind_vertex_elements_state)(struct pipe_context *, void *);
|
||||||
void (*delete_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,
|
void (*set_index_buffer)( struct pipe_context *pipe,
|
||||||
const struct pipe_index_buffer * );
|
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
|
* Stream output functions.
|
||||||
of the buffers */
|
*/
|
||||||
int num_buffers);
|
/*@{*/
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
|
@@ -438,7 +438,7 @@ enum pipe_cap {
|
|||||||
PIPE_CAP_TEXTURE_MIRROR_CLAMP = 25,
|
PIPE_CAP_TEXTURE_MIRROR_CLAMP = 25,
|
||||||
PIPE_CAP_BLEND_EQUATION_SEPARATE = 28,
|
PIPE_CAP_BLEND_EQUATION_SEPARATE = 28,
|
||||||
PIPE_CAP_SM3 = 29, /*< Shader Model, supported */
|
PIPE_CAP_SM3 = 29, /*< Shader Model, supported */
|
||||||
PIPE_CAP_STREAM_OUTPUT = 30,
|
PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS = 30,
|
||||||
PIPE_CAP_PRIMITIVE_RESTART = 31,
|
PIPE_CAP_PRIMITIVE_RESTART = 31,
|
||||||
/** Maximum texture image units accessible from vertex and fragment shaders
|
/** Maximum texture image units accessible from vertex and fragment shaders
|
||||||
* combined */
|
* combined */
|
||||||
@@ -466,8 +466,12 @@ enum pipe_cap {
|
|||||||
PIPE_CAP_MAX_TEXEL_OFFSET = 51,
|
PIPE_CAP_MAX_TEXEL_OFFSET = 51,
|
||||||
PIPE_CAP_CONDITIONAL_RENDER = 52,
|
PIPE_CAP_CONDITIONAL_RENDER = 52,
|
||||||
PIPE_CAP_TEXTURE_BARRIER = 53,
|
PIPE_CAP_TEXTURE_BARRIER = 53,
|
||||||
PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS = 54, /* temporary */
|
PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_ATTRIBS = 54,
|
||||||
PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS = 55 /* temporary */
|
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 */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -121,6 +121,12 @@ struct pipe_rasterizer_state
|
|||||||
*/
|
*/
|
||||||
unsigned gl_rasterization_rules:1;
|
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_factor:8; /**< [1..256] actually */
|
||||||
unsigned line_stipple_pattern:16;
|
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
|
struct pipe_shader_state
|
||||||
{
|
{
|
||||||
const struct tgsi_token *tokens;
|
const struct tgsi_token *tokens;
|
||||||
|
struct pipe_stream_output_info stream_output;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -374,24 +401,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.
|
* Transfer object. For data transfer to/from a resource.
|
||||||
*/
|
*/
|
||||||
@@ -421,6 +430,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)
|
* Information to describe a vertex attribute (position, color, etc)
|
||||||
*/
|
*/
|
||||||
@@ -481,6 +514,22 @@ struct pipe_draw_info
|
|||||||
*/
|
*/
|
||||||
boolean primitive_restart;
|
boolean primitive_restart;
|
||||||
unsigned restart_index;
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -441,6 +441,7 @@ struct vg_shader * shader_create_from_text(struct pipe_context *pipe,
|
|||||||
type == PIPE_SHADER_FRAGMENT);
|
type == PIPE_SHADER_FRAGMENT);
|
||||||
|
|
||||||
state.tokens = tokens;
|
state.tokens = tokens;
|
||||||
|
memset(&state.stream_output, 0, sizeof(state.stream_output));
|
||||||
shader->type = type;
|
shader->type = type;
|
||||||
shader->tokens = tokens;
|
shader->tokens = tokens;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user