diff options
author | Marek Olšák <[email protected]> | 2011-12-15 18:42:21 +0100 |
---|---|---|
committer | Christoph Bumiller <[email protected]> | 2011-12-15 18:51:48 +0100 |
commit | 861a029ddb31e91bb4d8e18ab708d0d172f63aad (patch) | |
tree | a938450d80ee5dbda670f7fe37bb51b10c1982c4 /src/gallium/auxiliary | |
parent | 4f4a1be2009863ea34a69b22f58aa1ca08cd710f (diff) |
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
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r-- | src/gallium/auxiliary/draw/draw_context.c | 4 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_context.h | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_private.h | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_so_emit.c | 10 | ||||
-rw-r--r-- | src/gallium/auxiliary/postprocess/pp_run.c | 1 | ||||
-rw-r--r-- | src/gallium/auxiliary/tgsi/tgsi_ureg.c | 1 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_dump_state.c | 19 |
7 files changed, 30 insertions, 9 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); } |