diff options
| author | Zack Rusin <zack@kde.org> | 2010-05-28 13:14:07 -0400 | 
|---|---|---|
| committer | Zack Rusin <zackr@vmware.com> | 2010-06-08 06:28:10 -0400 | 
| commit | a45b7f47ee0e38b288cc8fc4f6a1c013e8c227bc (patch) | |
| tree | 39d93f4236a0068db6f515b2f0681c6da4dc016d /src | |
| parent | a2817f6ae566b672f195cff22e14e2058d3617ea (diff) | |
gallium: basic and initial implementation of the stream output interface
aka transform feedback
Diffstat (limited to 'src')
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_context.c | 22 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_context.h | 8 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_private.h | 6 | ||||
| -rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_emit.c | 75 | ||||
| -rw-r--r-- | src/gallium/drivers/softpipe/SConscript | 1 | ||||
| -rw-r--r-- | src/gallium/drivers/softpipe/sp_context.c | 6 | ||||
| -rw-r--r-- | src/gallium/drivers/softpipe/sp_context.h | 2 | ||||
| -rw-r--r-- | src/gallium/drivers/softpipe/sp_state.h | 21 | ||||
| -rw-r--r-- | src/gallium/include/pipe/p_context.h | 12 | ||||
| -rw-r--r-- | src/gallium/include/pipe/p_defines.h | 2 | ||||
| -rw-r--r-- | src/gallium/include/pipe/p_state.h | 7 | 
11 files changed, 161 insertions, 1 deletions
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index 61980c3e4f..7c7702549e 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -574,3 +574,25 @@ draw_get_rasterizer_no_cull( struct draw_context *draw,     }     return draw->rasterizer_no_cull[scissor][flatshade];  } + +void +draw_set_mapped_so_buffers(struct draw_context *draw, +                           void *buffers[PIPE_MAX_SO_BUFFERS], +                           unsigned num_buffers) +{ +   int i; + +   for (i = 0; i < num_buffers; ++i) { +      draw->so.buffers[i] = buffers[i]; +   } +   draw->so.num_buffers = num_buffers; +} + +void +draw_set_so_state(struct draw_context *draw, +                  struct pipe_stream_output_state *state) +{ +   memcpy(&draw->so.state, +          state, +          sizeof(struct pipe_stream_output_state)); +} diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h index b905c2f2da..103d6538b8 100644 --- a/src/gallium/auxiliary/draw/draw_context.h +++ b/src/gallium/auxiliary/draw/draw_context.h @@ -162,6 +162,14 @@ draw_set_mapped_constant_buffer(struct draw_context *draw,                                  const void *buffer,                                  unsigned size); +void +draw_set_mapped_so_buffers(struct draw_context *draw, +                           void *buffers[PIPE_MAX_SO_BUFFERS], +                           unsigned num_buffers); +void +draw_set_so_state(struct draw_context *draw, +                  struct pipe_stream_output_state *state); +  /***********************************************************************   * draw_prim.c  diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index a2bfb693c0..ca8f9cfab1 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -235,6 +235,12 @@ struct draw_context        struct tgsi_sampler **samplers;     } gs; +   struct { +      struct pipe_stream_output_state state; +      void *buffers[PIPE_MAX_SO_BUFFERS]; +      uint num_buffers; +   } so; +     /* Clip derived state:      */     float plane[12][4]; diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index f623c0743d..3b4237245e 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -33,11 +33,13 @@  #include "draw/draw_pt.h"  #include "translate/translate.h"  #include "translate/translate_cache.h" +#include "util/u_format.h"  struct pt_emit {     struct draw_context *draw;     struct translate *translate; +   struct translate *so_translate;     struct translate_cache *cache;     unsigned prim; @@ -45,6 +47,51 @@ struct pt_emit {     const struct vertex_info *vinfo;  }; +static void +prepare_so_emit( struct pt_emit *emit, +                 const struct vertex_info *vinfo ) +{ +   struct draw_context *draw = emit->draw; +   unsigned i; +   struct translate_key hw_key; +   unsigned dst_offset = 0; +   unsigned output_stride = 0; +   boolean has_so = (draw->so.state.num_outputs > 0); + +   if (has_so) { + +      for (i = 0; i < draw->so.state.num_outputs; ++i) { +         unsigned src_offset = (vinfo->attrib[i].src_index * 4 * sizeof(float) ); +         unsigned output_format = draw->so.state.format[i]; +         unsigned output_bytes = util_format_get_blocksize(output_format); + +         hw_key.element[i].type = TRANSLATE_ELEMENT_NORMAL; +         hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; +         hw_key.element[i].input_buffer = 0; +         hw_key.element[i].input_offset = src_offset; +         hw_key.element[i].instance_divisor = 0; +         hw_key.element[i].output_format = output_format; +         hw_key.element[i].output_offset = dst_offset; + +         dst_offset += output_bytes; +         output_stride += output_bytes; +      } +      hw_key.nr_elements = draw->so.state.num_outputs; +      hw_key.output_stride = output_stride; + +      if (!emit->so_translate || +          translate_key_compare(&emit->so_translate->key, &hw_key) != 0) +      { +         translate_key_sanitize(&hw_key); +         emit->so_translate = translate_cache_find(emit->cache, &hw_key); +      } +   } else { +      /* no stream output */ +      emit->so_translate = NULL; +   } +} + +  void draw_pt_emit_prepare( struct pt_emit *emit,  			   unsigned prim,                             unsigned *max_vertices ) @@ -121,6 +168,8 @@ void draw_pt_emit_prepare( struct pt_emit *emit,     *max_vertices = (draw->render->max_vertex_buffer_bytes /                       (vinfo->size * 4)); +   prepare_so_emit( emit, vinfo ); +     /* even number */     *max_vertices = *max_vertices & ~1;  } @@ -135,6 +184,7 @@ void draw_pt_emit( struct pt_emit *emit,  {     struct draw_context *draw = emit->draw;     struct translate *translate = emit->translate; +   struct translate *so_translate = emit->so_translate;     struct vbuf_render *render = draw->render;     void *hw_verts; @@ -186,6 +236,18 @@ void draw_pt_emit( struct pt_emit *emit,                     draw->instance_id,  		   hw_verts ); +   if (so_translate) { +      void *so_buffer = draw->so.buffers[0]; + +      /* XXX we only support single output buffer right now */ +      debug_assert(draw->so.num_buffers >= 0); + +      so_translate->set_buffer(translate, 0, vertex_data, +                               stride, ~0); +      so_translate->run(translate, 0, vertex_count, +                        draw->instance_id, so_buffer); +   } +     render->unmap_vertices( render,                              0,                              vertex_count - 1 ); @@ -205,6 +267,7 @@ void draw_pt_emit_linear(struct pt_emit *emit,  {     struct draw_context *draw = emit->draw;     struct translate *translate = emit->translate; +   struct translate *so_translate = emit->so_translate;     struct vbuf_render *render = draw->render;     void *hw_verts; @@ -246,6 +309,18 @@ void draw_pt_emit_linear(struct pt_emit *emit,                    draw->instance_id,                    hw_verts); +   if (so_translate) { +      void *so_buffer = draw->so.buffers[0]; + +      /* XXX we only support single output buffer right now */ +      debug_assert(draw->so.num_buffers >= 0); + +      so_translate->set_buffer(translate, 0, +                               vertex_data, stride, count - 1); +      so_translate->run(translate, 0, count, +                        draw->instance_id, so_buffer); +   } +     if (0) {        unsigned i;        for (i = 0; i < count; i++) { diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript index b80c6dea93..be5917a688 100644 --- a/src/gallium/drivers/softpipe/SConscript +++ b/src/gallium/drivers/softpipe/SConscript @@ -27,6 +27,7 @@ softpipe = env.ConvenienceLibrary(  		'sp_state_fs.c',  		'sp_state_rasterizer.c',  		'sp_state_sampler.c', +		'sp_state_so.c',  		'sp_state_surface.c',  		'sp_state_vertex.c',  		'sp_surface.c', diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 2f10b46e98..b1970140d5 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -251,6 +251,10 @@ softpipe_create_context( struct pipe_screen *screen,     softpipe->pipe.bind_vertex_elements_state = softpipe_bind_vertex_elements_state;     softpipe->pipe.delete_vertex_elements_state = softpipe_delete_vertex_elements_state; +   softpipe->pipe.create_stream_output_state = softpipe_create_stream_output_state; +   softpipe->pipe.bind_stream_output_state = softpipe_bind_stream_output_state; +   softpipe->pipe.delete_stream_output_state = softpipe_delete_stream_output_state; +     softpipe->pipe.set_blend_color = softpipe_set_blend_color;     softpipe->pipe.set_stencil_ref = softpipe_set_stencil_ref;     softpipe->pipe.set_clip_state = softpipe_set_clip_state; @@ -264,7 +268,7 @@ softpipe_create_context( struct pipe_screen *screen,     softpipe->pipe.create_sampler_view = softpipe_create_sampler_view;     softpipe->pipe.sampler_view_destroy = softpipe_sampler_view_destroy;     softpipe->pipe.set_viewport_state = softpipe_set_viewport_state; - +   softpipe->pipe.set_stream_output_buffers = softpipe_set_stream_output_buffers;     softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers;     softpipe->pipe.draw_arrays = softpipe_draw_arrays; diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index b3d3fe620f..f8ffc5787d 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -50,6 +50,7 @@ struct softpipe_tex_tile_cache;  struct sp_fragment_shader;  struct sp_vertex_shader;  struct sp_velems_state; +struct sp_so_state;  struct softpipe_context { @@ -65,6 +66,7 @@ struct softpipe_context {     struct sp_vertex_shader *vs;     struct sp_geometry_shader *gs;     struct sp_velems_state *velems; +   struct sp_so_state *so;     /** Other rendering state */     struct pipe_blend_color blend_color; diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 5b0faabeae..dd958ebb53 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -51,6 +51,8 @@  #define SP_NEW_VS            0x2000  #define SP_NEW_QUERY         0x4000  #define SP_NEW_GS            0x8000 +#define SP_NEW_SO            0x10000 +#define SP_NEW_SO_BUFFERS    0x20000  struct tgsi_sampler; @@ -105,6 +107,10 @@ struct sp_velems_state {     struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];  }; +struct sp_so_state { +   struct pipe_stream_output_state base; +}; +  void *  softpipe_create_blend_state(struct pipe_context *, @@ -263,5 +269,20 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe);  struct vertex_info *  softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe); +void * +softpipe_create_stream_output_state( +   struct pipe_context *pipe, +   const struct pipe_stream_output_state *templ); +void +softpipe_bind_stream_output_state(struct pipe_context *pipe, +                                  void *so); +void +softpipe_delete_stream_output_state(struct pipe_context *pipe, void *so); + +void +softpipe_set_stream_output_buffers(struct pipe_context *pipe, +                                   struct pipe_resource **buffers, +                                   int *offsets, +                                   int num_buffers);  #endif diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 3e082bef2f..0267ed8fa4 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -186,6 +186,11 @@ 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*); +     /*@}*/     /** @@ -232,6 +237,13 @@ struct pipe_context {                                 unsigned num_buffers,                                 const struct pipe_vertex_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); +     /*@}*/ diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index b00677425c..be42c27222 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -288,6 +288,7 @@ enum pipe_transfer_usage {  #define PIPE_BIND_DISPLAY_TARGET       (1 << 8) /* flush_front_buffer */  #define PIPE_BIND_TRANSFER_WRITE       (1 << 9) /* get_transfer */  #define PIPE_BIND_TRANSFER_READ        (1 << 10) /* get_transfer */ +#define PIPE_BIND_STREAM_OUTPUT        (1 << 11) /* set_stream_output_buffers */  #define PIPE_BIND_CUSTOM               (1 << 16) /* state-tracker/winsys usages */  /* The first two flags above were previously part of the amorphous @@ -322,6 +323,7 @@ enum pipe_transfer_usage {  #define PIPE_USAGE_STATIC         2 /* same as immutable?? */  #define PIPE_USAGE_IMMUTABLE      3 /* no change after first upload */  #define PIPE_USAGE_STREAM         4 /* upload, draw, upload, draw */ +#define PIPE_USAGE_STAGING        5 /* supports data transfers from the GPU to the CPU */  /* These are intended to be used in calls to is_format_supported, but diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 5255b2003f..33ee066c0c 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -63,6 +63,7 @@ extern "C" {  #define PIPE_MAX_SHADER_INPUTS    16  #define PIPE_MAX_SHADER_OUTPUTS   16  #define PIPE_MAX_TEXTURE_LEVELS   16 +#define PIPE_MAX_SO_BUFFERS        4  struct pipe_reference @@ -345,6 +346,12 @@ struct pipe_resource     unsigned flags;	     /**< bitmask of PIPE_RESOURCE_FLAG_x */  }; +struct pipe_stream_output_state +{ +   /**< format for each output */ +   enum pipe_format format[PIPE_MAX_SHADER_OUTPUTS]; +   int num_outputs; +};  /**   * Extra indexing info for (cube) texture resources.  | 
