diff options
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; |