gallium/softpipe/draw: support samplers in geometry shaders
authorZack Rusin <zack@kde.org>
Fri, 11 Jun 2010 17:31:52 +0000 (13:31 -0400)
committerZack Rusin <zack@kde.org>
Fri, 11 Jun 2010 17:31:52 +0000 (13:31 -0400)
src/gallium/auxiliary/draw/draw_context.c
src/gallium/auxiliary/draw/draw_context.h
src/gallium/drivers/softpipe/sp_context.c
src/gallium/drivers/softpipe/sp_context.h
src/gallium/drivers/softpipe/sp_flush.c
src/gallium/drivers/softpipe/sp_state.h
src/gallium/drivers/softpipe/sp_state_derived.c
src/gallium/drivers/softpipe/sp_state_fs.c
src/gallium/drivers/softpipe/sp_state_sampler.c
src/gallium/include/pipe/p_context.h
src/gallium/include/pipe/p_state.h

index 7c7702549e09d0fe1a06cacf1eea034fb50d82fd..dab95e50515ceb35c9ef8f7e8f4ef5dcae34bab6 100644 (file)
@@ -435,13 +435,18 @@ draw_num_shader_outputs(const struct draw_context *draw)
  */
 void
 draw_texture_samplers(struct draw_context *draw,
+                      uint shader,
                       uint num_samplers,
                       struct tgsi_sampler **samplers)
 {
-   draw->vs.num_samplers = num_samplers;
-   draw->vs.samplers = samplers;
-   draw->gs.num_samplers = num_samplers;
-   draw->gs.samplers = samplers;
+   if (shader == PIPE_SHADER_VERTEX) {
+      draw->vs.num_samplers = num_samplers;
+      draw->vs.samplers = samplers;
+   } else {
+      debug_assert(shader == PIPE_SHADER_GEOMETRY);
+      draw->gs.num_samplers = num_samplers;
+      draw->gs.samplers = samplers;
+   }
 }
 
 
index 103d6538b8156ae3b50a36b7f8d3da19ab96d5e3..c0122f2aca5f8e3992c575913e728fd7dbe2555b 100644 (file)
@@ -97,6 +97,7 @@ draw_num_shader_outputs(const struct draw_context *draw);
 
 void
 draw_texture_samplers(struct draw_context *draw,
+                      uint shader_type,
                       uint num_samplers,
                       struct tgsi_sampler **samplers);
 
index 401a28ad3124d98dcdad77c785660bf019d4a432..12ef98aac7589d13cfba4583a67df53d2bf737df 100644 (file)
@@ -114,6 +114,11 @@ softpipe_destroy( struct pipe_context *pipe )
       pipe_sampler_view_reference(&softpipe->vertex_sampler_views[i], NULL);
    }
 
+   for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) {
+      sp_destroy_tex_tile_cache(softpipe->geometry_tex_cache[i]);
+      pipe_sampler_view_reference(&softpipe->geometry_sampler_views[i], NULL);
+   }
+
    for (i = 0; i < PIPE_SHADER_TYPES; i++) {
       uint j;
 
@@ -174,7 +179,12 @@ softpipe_is_resource_referenced( struct pipe_context *pipe,
           softpipe->vertex_tex_cache[i]->texture == texture)
          return PIPE_REFERENCED_FOR_READ;
    }
-   
+   for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) {
+      if (softpipe->geometry_tex_cache[i] &&
+          softpipe->geometry_tex_cache[i]->texture == texture)
+         return PIPE_REFERENCED_FOR_READ;
+   }
+
    return PIPE_UNREFERENCED;
 }
 
@@ -225,6 +235,7 @@ softpipe_create_context( struct pipe_screen *screen,
    softpipe->pipe.create_sampler_state = softpipe_create_sampler_state;
    softpipe->pipe.bind_fragment_sampler_states  = softpipe_bind_sampler_states;
    softpipe->pipe.bind_vertex_sampler_states = softpipe_bind_vertex_sampler_states;
+   softpipe->pipe.bind_geometry_sampler_states = softpipe_bind_geometry_sampler_states;
    softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state;
 
    softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state;
@@ -265,6 +276,7 @@ softpipe_create_context( struct pipe_screen *screen,
    softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
    softpipe->pipe.set_fragment_sampler_views = softpipe_set_sampler_views;
    softpipe->pipe.set_vertex_sampler_views = softpipe_set_vertex_sampler_views;
+   softpipe->pipe.set_geometry_sampler_views = softpipe_set_geometry_sampler_views;
    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;
@@ -301,6 +313,9 @@ softpipe_create_context( struct pipe_screen *screen,
    for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
       softpipe->vertex_tex_cache[i] = sp_create_tex_tile_cache( &softpipe->pipe );
    }
+   for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) {
+      softpipe->geometry_tex_cache[i] = sp_create_tex_tile_cache( &softpipe->pipe );
+   }
 
    softpipe->fs_machine = tgsi_exec_machine_create();
 
@@ -319,10 +334,17 @@ softpipe_create_context( struct pipe_screen *screen,
       goto fail;
 
    draw_texture_samplers(softpipe->draw,
+                         PIPE_SHADER_VERTEX,
                          PIPE_MAX_VERTEX_SAMPLERS,
                          (struct tgsi_sampler **)
                             softpipe->tgsi.vert_samplers_list);
 
+   draw_texture_samplers(softpipe->draw,
+                         PIPE_SHADER_GEOMETRY,
+                         PIPE_MAX_GEOMETRY_SAMPLERS,
+                         (struct tgsi_sampler **)
+                            softpipe->tgsi.geom_samplers_list);
+
    if (debug_get_bool_option( "SP_NO_RAST", FALSE ))
       softpipe->no_rast = TRUE;
 
index e641a81d1fb16ee510d79fe333e1c78e16645158..53115a827d01e9d4617e771ef65471fb27bb3c41 100644 (file)
@@ -60,6 +60,7 @@ struct softpipe_context {
    struct pipe_blend_state *blend;
    struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
    struct pipe_sampler_state *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS];
+   struct pipe_sampler_state *geometry_samplers[PIPE_MAX_GEOMETRY_SAMPLERS];
    struct pipe_depth_stencil_alpha_state *depth_stencil;
    struct pipe_rasterizer_state *rasterizer;
    struct sp_fragment_shader *fs;
@@ -78,6 +79,7 @@ struct softpipe_context {
    struct pipe_scissor_state scissor;
    struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
    struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
+   struct pipe_sampler_view *geometry_sampler_views[PIPE_MAX_GEOMETRY_SAMPLERS];
    struct pipe_viewport_state viewport;
    struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
    struct {
@@ -92,6 +94,8 @@ struct softpipe_context {
    unsigned num_sampler_views;
    unsigned num_vertex_samplers;
    unsigned num_vertex_sampler_views;
+   unsigned num_geometry_samplers;
+   unsigned num_geometry_sampler_views;
    unsigned num_vertex_buffers;
 
    unsigned dirty; /**< Mask of SP_NEW_x flags */
@@ -148,6 +152,7 @@ struct softpipe_context {
 
    /** TGSI exec things */
    struct {
+      struct sp_sampler_varient *geom_samplers_list[PIPE_MAX_GEOMETRY_SAMPLERS];
       struct sp_sampler_varient *vert_samplers_list[PIPE_MAX_VERTEX_SAMPLERS];
       struct sp_sampler_varient *frag_samplers_list[PIPE_MAX_SAMPLERS];
    } tgsi;
@@ -169,6 +174,7 @@ struct softpipe_context {
    unsigned tex_timestamp;
    struct softpipe_tex_tile_cache *tex_cache[PIPE_MAX_SAMPLERS];
    struct softpipe_tex_tile_cache *vertex_tex_cache[PIPE_MAX_VERTEX_SAMPLERS];
+   struct softpipe_tex_tile_cache *geometry_tex_cache[PIPE_MAX_GEOMETRY_SAMPLERS];
 
    unsigned use_sse : 1;
    unsigned dump_fs : 1;
index 5024fc8a81941147c54ca6c0762b678df9aeb96a..4a53ef048f38673f6973ed9b161a2d5827a98e5f 100644 (file)
@@ -56,6 +56,9 @@ softpipe_flush( struct pipe_context *pipe,
       for (i = 0; i < softpipe->num_vertex_sampler_views; i++) {
          sp_flush_tex_tile_cache(softpipe->vertex_tex_cache[i]);
       }
+      for (i = 0; i < softpipe->num_geometry_sampler_views; i++) {
+         sp_flush_tex_tile_cache(softpipe->geometry_tex_cache[i]);
+      }
    }
 
    if (flags & PIPE_FLUSH_SWAPBUFFERS) {
index d0b73cc850c10e8c65a26daa0148a76fac1996a4..7d6b86dce0485406ff8f2bc034fce0cc62753496 100644 (file)
@@ -100,6 +100,7 @@ struct sp_vertex_shader {
 struct sp_geometry_shader {
    struct pipe_shader_state shader;
    struct draw_geometry_shader *draw_data;
+   int max_sampler;
 };
 
 struct sp_velems_state {
@@ -128,6 +129,10 @@ void
 softpipe_bind_vertex_sampler_states(struct pipe_context *,
                                     unsigned num_samplers,
                                     void **samplers);
+void
+softpipe_bind_geometry_sampler_states(struct pipe_context *,
+                                      unsigned num_samplers,
+                                      void **samplers);
 void softpipe_delete_sampler_state(struct pipe_context *, void *);
 
 void *
@@ -195,6 +200,11 @@ softpipe_set_vertex_sampler_views(struct pipe_context *,
                                   unsigned num,
                                   struct pipe_sampler_view **);
 
+void
+softpipe_set_geometry_sampler_views(struct pipe_context *,
+                                    unsigned num,
+                                    struct pipe_sampler_view **);
+
 struct pipe_sampler_view *
 softpipe_create_sampler_view(struct pipe_context *pipe,
                              struct pipe_resource *texture,
index 4c6d4909f5baa08e19bd0e1052de447fe80b5d5c..3ba4d934fd243538eed4b4e3c329128c327ad60e 100644 (file)
@@ -225,6 +225,19 @@ update_tgsi_samplers( struct softpipe_context *softpipe )
          }
       }
    }
+
+   for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) {
+      struct softpipe_tex_tile_cache *tc = softpipe->geometry_tex_cache[i];
+
+      if (tc->texture) {
+         struct softpipe_resource *spt = softpipe_resource(tc->texture);
+
+         if (spt->timestamp != tc->timestamp) {
+           sp_tex_tile_cache_validate_texture(tc);
+            tc->timestamp = spt->timestamp;
+         }
+      }
+   }
 }
 
 
index 2fff80c4385305ed122a251b43184ed0434982da..3fbf1f2578172d853a66fbd58c5d0965dbf56b19 100644 (file)
@@ -35,6 +35,7 @@
 #include "util/u_inlines.h"
 #include "draw/draw_context.h"
 #include "draw/draw_vs.h"
+#include "draw/draw_gs.h"
 #include "tgsi/tgsi_dump.h"
 #include "tgsi/tgsi_exec.h"
 #include "tgsi/tgsi_scan.h"
@@ -223,6 +224,8 @@ softpipe_create_gs_state(struct pipe_context *pipe,
    if (state->draw_data == NULL)
       goto fail;
 
+   state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER];
+
    return state;
 
 fail:
index 2692f06c927bf2fc52ebe36b2d874260e034f841..09b0ffc1dad7500f58d5534a5b44c9a1f62535e1 100644 (file)
@@ -121,6 +121,33 @@ softpipe_bind_vertex_sampler_states(struct pipe_context *pipe,
    softpipe->dirty |= SP_NEW_SAMPLER;
 }
 
+void
+softpipe_bind_geometry_sampler_states(struct pipe_context *pipe,
+                                      unsigned num_samplers,
+                                      void **samplers)
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+   unsigned i;
+
+   assert(num_samplers <= PIPE_MAX_GEOMETRY_SAMPLERS);
+
+   /* Check for no-op */
+   if (num_samplers == softpipe->num_geometry_samplers &&
+       !memcmp(softpipe->geometry_samplers, samplers, num_samplers * sizeof(void *)))
+      return;
+
+   draw_flush(softpipe->draw);
+
+   for (i = 0; i < num_samplers; ++i)
+      softpipe->geometry_samplers[i] = samplers[i];
+   for (i = num_samplers; i < PIPE_MAX_GEOMETRY_SAMPLERS; ++i)
+      softpipe->geometry_samplers[i] = NULL;
+
+   softpipe->num_geometry_samplers = num_samplers;
+
+   softpipe->dirty |= SP_NEW_SAMPLER;
+}
+
 
 struct pipe_sampler_view *
 softpipe_create_sampler_view(struct pipe_context *pipe,
@@ -210,6 +237,36 @@ softpipe_set_vertex_sampler_views(struct pipe_context *pipe,
    softpipe->dirty |= SP_NEW_TEXTURE;
 }
 
+void
+softpipe_set_geometry_sampler_views(struct pipe_context *pipe,
+                                    unsigned num,
+                                    struct pipe_sampler_view **views)
+{
+   struct softpipe_context *softpipe = softpipe_context(pipe);
+   uint i;
+
+   assert(num <= PIPE_MAX_GEOMETRY_SAMPLERS);
+
+   /* Check for no-op */
+   if (num == softpipe->num_geometry_sampler_views &&
+       !memcmp(softpipe->geometry_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) {
+      return;
+   }
+
+   draw_flush(softpipe->draw);
+
+   for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) {
+      struct pipe_sampler_view *view = i < num ? views[i] : NULL;
+
+      pipe_sampler_view_reference(&softpipe->geometry_sampler_views[i], view);
+      sp_tex_tile_cache_set_sampler_view(softpipe->geometry_tex_cache[i], view);
+   }
+
+   softpipe->num_geometry_sampler_views = num;
+
+   softpipe->dirty |= SP_NEW_TEXTURE;
+}
+
 
 /**
  * Find/create an sp_sampler_varient object for sampling the given texture,
@@ -293,6 +350,26 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe)
       }
    }
 
+   for (i = 0; i <= softpipe->gs->max_sampler; i++) {
+      if (softpipe->geometry_samplers[i]) {
+         struct pipe_resource *texture = NULL;
+
+         if (softpipe->geometry_sampler_views[i]) {
+            texture = softpipe->geometry_sampler_views[i]->texture;
+         }
+
+         softpipe->tgsi.geom_samplers_list[i] =
+            get_sampler_varient( i,
+                                 sp_sampler(softpipe->geometry_samplers[i]),
+                                 texture,
+                                 TGSI_PROCESSOR_GEOMETRY );
+
+         sp_sampler_varient_bind_texture( softpipe->tgsi.geom_samplers_list[i],
+                                          softpipe->geometry_tex_cache[i],
+                                          texture );
+      }
+   }
+
    for (i = 0; i <= softpipe->fs->info.file_max[TGSI_FILE_SAMPLER]; i++) {
       if (softpipe->sampler[i]) {
          struct pipe_resource *texture = NULL;
index 72afad60ba9a4d22e591b8b66fba4a876382a2aa..7ec3d63a3fdfdbe80c12f67e3e4cbe3bce6f2911 100644 (file)
@@ -158,6 +158,9 @@ struct pipe_context {
    void   (*bind_vertex_sampler_states)(struct pipe_context *,
                                         unsigned num_samplers,
                                         void **samplers);
+   void   (*bind_geometry_sampler_states)(struct pipe_context *,
+                                          unsigned num_samplers,
+                                          void **samplers);
    void   (*delete_sampler_state)(struct pipe_context *, void *);
 
    void * (*create_rasterizer_state)(struct pipe_context *,
@@ -238,6 +241,10 @@ struct pipe_context {
                                     unsigned num_views,
                                     struct pipe_sampler_view **);
 
+   void (*set_geometry_sampler_views)(struct pipe_context *,
+                                      unsigned num_views,
+                                      struct pipe_sampler_view **);
+
    void (*set_vertex_buffers)( struct pipe_context *,
                                unsigned num_buffers,
                                const struct pipe_vertex_buffer * );
index 5ed1cca67a5151f39535b24ec69e519e3ccf0a29..6231f06ec718c17fdd0b48501a1f5d84113073b1 100644 (file)
@@ -60,6 +60,7 @@ extern "C" {
 #define PIPE_MAX_CONSTANT_BUFFERS 32
 #define PIPE_MAX_SAMPLERS         16
 #define PIPE_MAX_VERTEX_SAMPLERS  16
+#define PIPE_MAX_GEOMETRY_SAMPLERS  16
 #define PIPE_MAX_SHADER_INPUTS    16
 #define PIPE_MAX_SHADER_OUTPUTS   16
 #define PIPE_MAX_TEXTURE_LEVELS   16