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/drivers | |
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/drivers')
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_so.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_screen.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_screen.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/nvc0/nvc0_state.c | 8 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_screen.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_pipe.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_screen.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_state.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/softpipe/sp_state_so.c | 13 | ||||
-rw-r--r-- | src/gallium/drivers/trace/tr_dump_state.c | 21 |
11 files changed, 40 insertions, 22 deletions
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(); } |