diff options
75 files changed, 1600 insertions, 548 deletions
| diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile index 0ac18426d9..e2796d5bd3 100644 --- a/src/gallium/auxiliary/Makefile +++ b/src/gallium/auxiliary/Makefile @@ -119,6 +119,7 @@ C_SOURCES = \  	util/u_mm.c \  	util/u_rect.c \  	util/u_ringbuffer.c \ +	util/u_sampler.c \  	util/u_simple_shaders.c \  	util/u_snprintf.c \  	util/u_surface.c \ @@ -126,12 +127,13 @@ C_SOURCES = \  	util/u_tile.c \  	util/u_timed_winsys.c \  	util/u_upload_mgr.c \ -	util/u_simple_screen.c \ -	vl/vl_bitstream_parser.c \ -	vl/vl_mpeg12_mc_renderer.c \ -	vl/vl_compositor.c \ -	vl/vl_csc.c \ -	vl/vl_shader_build.c \ +	util/u_simple_screen.c +	# Disabling until pipe-video branch gets merged in +	#vl/vl_bitstream_parser.c \ +	#vl/vl_mpeg12_mc_renderer.c \ +	#vl/vl_compositor.c \ +	#vl/vl_csc.c \ +	#vl/vl_shader_build.c \  	target-helpers/wrap_screen.c  GALLIVM_SOURCES = \ diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript index 2be16776fb..65e1dc8a58 100644 --- a/src/gallium/auxiliary/SConscript +++ b/src/gallium/auxiliary/SConscript @@ -162,6 +162,7 @@ source = [      'util/u_mm.c',      'util/u_rect.c',      'util/u_ringbuffer.c', +    'util/u_sampler.c',      'util/u_simple_shaders.c',      'util/u_snprintf.c',      'util/u_surface.c', @@ -170,11 +171,12 @@ source = [      'util/u_timed_winsys.c',      'util/u_upload_mgr.c',      'util/u_simple_screen.c', -    'vl/vl_bitstream_parser.c', -    'vl/vl_mpeg12_mc_renderer.c', -    'vl/vl_compositor.c', -    'vl/vl_csc.c', -    'vl/vl_shader_build.c', +    # Disabling until pipe-video branch gets merged in +    #'vl/vl_bitstream_parser.c', +    #'vl/vl_mpeg12_mc_renderer.c', +    #'vl/vl_compositor.c', +    #'vl/vl_csc.c', +    #'vl/vl_shader_build.c',      'target-helpers/wrap_screen.c',  ] diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 6500891a10..8568a0052d 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -38,6 +38,7 @@  #include "pipe/p_state.h"  #include "util/u_inlines.h"  #include "util/u_memory.h" +#include "util/u_sampler.h"  #include "tgsi/tgsi_parse.h"  #include "cso_cache/cso_context.h" @@ -70,16 +71,20 @@ struct cso_context {     void *vertex_samplers_saved[PIPE_MAX_VERTEX_SAMPLERS];     struct pipe_texture *textures[PIPE_MAX_SAMPLERS]; +   struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];     uint nr_textures;     struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS]; +   struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];     uint nr_vertex_textures;     uint nr_textures_saved;     struct pipe_texture *textures_saved[PIPE_MAX_SAMPLERS]; +   struct pipe_sampler_view *sampler_views_saved[PIPE_MAX_SAMPLERS];     uint nr_vertex_textures_saved; -   struct pipe_texture *vertex_textures_saved[PIPE_MAX_SAMPLERS]; +   struct pipe_texture *vertex_textures_saved[PIPE_MAX_VERTEX_SAMPLERS]; +   struct pipe_sampler_view *vertex_sampler_views_saved[PIPE_MAX_VERTEX_SAMPLERS];     /** Current and saved state.      * The saved state is used as a 1-deep stack. @@ -295,11 +300,15 @@ void cso_release_all( struct cso_context *ctx )     for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {        pipe_texture_reference(&ctx->textures[i], NULL);        pipe_texture_reference(&ctx->textures_saved[i], NULL); +      pipe_sampler_view_reference(&ctx->sampler_views[i], NULL); +      pipe_sampler_view_reference(&ctx->sampler_views_saved[i], NULL);     }     for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {        pipe_texture_reference(&ctx->vertex_textures[i], NULL);        pipe_texture_reference(&ctx->vertex_textures_saved[i], NULL); +      pipe_sampler_view_reference(&ctx->vertex_sampler_views[i], NULL); +      pipe_sampler_view_reference(&ctx->vertex_sampler_views_saved[i], NULL);     }     free_framebuffer_state(&ctx->fb); @@ -624,12 +633,27 @@ enum pipe_error cso_set_sampler_textures( struct cso_context *ctx,     ctx->nr_textures = count; -   for (i = 0; i < count; i++) +   for (i = 0; i < count; i++) { +      struct pipe_sampler_view templ, *view; + +      u_sampler_view_default_template(&templ, +                                      textures[i], +                                      textures[i]->format); +      view = ctx->pipe->create_sampler_view(ctx->pipe, +                                            textures[i], +                                            &templ); +        pipe_texture_reference(&ctx->textures[i], textures[i]); -   for ( ; i < PIPE_MAX_SAMPLERS; i++) +      pipe_sampler_view_reference(&ctx->sampler_views[i], view); +   } +   for ( ; i < PIPE_MAX_SAMPLERS; i++) {        pipe_texture_reference(&ctx->textures[i], NULL); +      pipe_sampler_view_reference(&ctx->sampler_views[i], NULL); +   } -   ctx->pipe->set_fragment_sampler_textures(ctx->pipe, count, textures); +   ctx->pipe->set_fragment_sampler_views(ctx->pipe, +                                         count, +                                         ctx->sampler_views);     return PIPE_OK;  } @@ -641,7 +665,11 @@ void cso_save_sampler_textures( struct cso_context *ctx )     ctx->nr_textures_saved = ctx->nr_textures;     for (i = 0; i < ctx->nr_textures; i++) {        assert(!ctx->textures_saved[i]); +      assert(!ctx->sampler_views_saved[i]); +        pipe_texture_reference(&ctx->textures_saved[i], ctx->textures[i]); +      pipe_sampler_view_reference(&ctx->sampler_views_saved[i], +                                  ctx->sampler_views[i]);     }  } @@ -655,11 +683,19 @@ void cso_restore_sampler_textures( struct cso_context *ctx )        pipe_texture_reference(&ctx->textures[i], NULL);        ctx->textures[i] = ctx->textures_saved[i];        ctx->textures_saved[i] = NULL; + +      pipe_sampler_view_reference(&ctx->sampler_views[i], NULL); +      ctx->sampler_views[i] = ctx->sampler_views_saved[i]; +      ctx->sampler_views_saved[i] = NULL;     } -   for ( ; i < PIPE_MAX_SAMPLERS; i++) +   for ( ; i < PIPE_MAX_SAMPLERS; i++) {        pipe_texture_reference(&ctx->textures[i], NULL); +      pipe_sampler_view_reference(&ctx->sampler_views[i], NULL); +   } -   ctx->pipe->set_fragment_sampler_textures(ctx->pipe, ctx->nr_textures, ctx->textures); +   ctx->pipe->set_fragment_sampler_views(ctx->pipe, +                                         ctx->nr_textures, +                                         ctx->sampler_views);     ctx->nr_textures_saved = 0;  } @@ -676,13 +712,26 @@ cso_set_vertex_sampler_textures(struct cso_context *ctx,     ctx->nr_vertex_textures = count;     for (i = 0; i < count; i++) { +      struct pipe_sampler_view templ, *view; + +      u_sampler_view_default_template(&templ, +                                      textures[i], +                                      textures[i]->format); +      view = ctx->pipe->create_sampler_view(ctx->pipe, +                                            textures[i], +                                            &templ); +        pipe_texture_reference(&ctx->vertex_textures[i], textures[i]); +      pipe_sampler_view_reference(&ctx->vertex_sampler_views[i], view);     }     for ( ; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {        pipe_texture_reference(&ctx->vertex_textures[i], NULL); +      pipe_sampler_view_reference(&ctx->vertex_sampler_views[i], NULL);     } -   ctx->pipe->set_vertex_sampler_textures(ctx->pipe, count, textures); +   ctx->pipe->set_vertex_sampler_views(ctx->pipe, +                                       count, +                                       ctx->vertex_sampler_views);     return PIPE_OK;  } @@ -695,7 +744,11 @@ cso_save_vertex_sampler_textures(struct cso_context *ctx)     ctx->nr_vertex_textures_saved = ctx->nr_vertex_textures;     for (i = 0; i < ctx->nr_vertex_textures; i++) {        assert(!ctx->vertex_textures_saved[i]); +      assert(!ctx->vertex_sampler_views_saved[i]); +        pipe_texture_reference(&ctx->vertex_textures_saved[i], ctx->vertex_textures[i]); +      pipe_sampler_view_reference(&ctx->vertex_sampler_views_saved[i], +                                  ctx->vertex_sampler_views[i]);     }  } @@ -710,14 +763,19 @@ cso_restore_vertex_sampler_textures(struct cso_context *ctx)        pipe_texture_reference(&ctx->vertex_textures[i], NULL);        ctx->vertex_textures[i] = ctx->vertex_textures_saved[i];        ctx->vertex_textures_saved[i] = NULL; + +      pipe_sampler_view_reference(&ctx->vertex_sampler_views[i], NULL); +      ctx->vertex_sampler_views[i] = ctx->vertex_sampler_views_saved[i]; +      ctx->vertex_sampler_views_saved[i] = NULL;     }     for ( ; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {        pipe_texture_reference(&ctx->vertex_textures[i], NULL); +      pipe_sampler_view_reference(&ctx->vertex_sampler_views[i], NULL);     } -   ctx->pipe->set_vertex_sampler_textures(ctx->pipe, -                                          ctx->nr_vertex_textures, -                                          ctx->vertex_textures); +   ctx->pipe->set_vertex_sampler_views(ctx->pipe, +                                       ctx->nr_vertex_textures, +                                       ctx->vertex_sampler_views);     ctx->nr_vertex_textures_saved = 0;  } diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index 8f6ca15dfa..70d7dbdfc7 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -40,6 +40,7 @@  #include "util/u_format.h"  #include "util/u_math.h"  #include "util/u_memory.h" +#include "util/u_sampler.h"  #include "tgsi/tgsi_transform.h"  #include "tgsi/tgsi_dump.h" @@ -88,8 +89,9 @@ struct aaline_stage     void *sampler_cso;     struct pipe_texture *texture; +   struct pipe_sampler_view *sampler_view;     uint num_samplers; -   uint num_textures; +   uint num_sampler_views;     /* @@ -98,7 +100,7 @@ struct aaline_stage     struct aaline_fragment_shader *fs;     struct {        void *sampler[PIPE_MAX_SAMPLERS]; -      struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; +      struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];     } state;     /* @@ -111,8 +113,9 @@ struct aaline_stage     void (*driver_bind_sampler_states)(struct pipe_context *, unsigned,                                        void **); -   void (*driver_set_sampler_textures)(struct pipe_context *, unsigned, -                                       struct pipe_texture **); +   void (*driver_set_sampler_views)(struct pipe_context *, +                                    unsigned, +                                    struct pipe_sampler_view **);     struct pipe_context *pipe;  }; @@ -394,6 +397,7 @@ aaline_create_texture(struct aaline_stage *aaline)     struct pipe_context *pipe = aaline->pipe;     struct pipe_screen *screen = pipe->screen;     struct pipe_texture texTemp; +   struct pipe_sampler_view viewTempl;     uint level;     memset(&texTemp, 0, sizeof(texTemp)); @@ -408,6 +412,16 @@ aaline_create_texture(struct aaline_stage *aaline)     if (!aaline->texture)        return FALSE; +   u_sampler_view_default_template(&viewTempl, +                                   aaline->texture, +                                   aaline->texture->format); +   aaline->sampler_view = pipe->create_sampler_view(pipe, +                                                    aaline->texture, +                                                    &viewTempl); +   if (!aaline->sampler_view) { +      return FALSE; +   } +     /* Fill in mipmap images.      * Basically each level is solid opaque, except for the outermost      * texels which are zero.  Special case the 1x1 and 2x2 levels. @@ -669,16 +683,16 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)     /* how many samplers? */     /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ -   num_samplers = MAX2(aaline->num_textures, aaline->num_samplers); +   num_samplers = MAX2(aaline->num_sampler_views, aaline->num_samplers);     num_samplers = MAX2(num_samplers, aaline->fs->sampler_unit + 1);     aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso; -   pipe_texture_reference(&aaline->state.texture[aaline->fs->sampler_unit], -                          aaline->texture); +   pipe_sampler_view_reference(&aaline->state.sampler_views[aaline->fs->sampler_unit], +                               aaline->sampler_view);     draw->suspend_flushing = TRUE;     aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler); -   aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture); +   aaline->driver_set_sampler_views(pipe, num_samplers, aaline->state.sampler_views);     draw->suspend_flushing = FALSE;     /* now really draw first line */ @@ -702,8 +716,9 @@ aaline_flush(struct draw_stage *stage, unsigned flags)     aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs);     aaline->driver_bind_sampler_states(pipe, aaline->num_samplers,                                        aaline->state.sampler); -   aaline->driver_set_sampler_textures(pipe, aaline->num_textures, -                                       aaline->state.texture); +   aaline->driver_set_sampler_views(pipe, +                                    aaline->num_sampler_views, +                                    aaline->state.sampler_views);     draw->suspend_flushing = FALSE;     draw->extra_shader_outputs.slot = 0; @@ -724,7 +739,7 @@ aaline_destroy(struct draw_stage *stage)     uint i;     for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { -      pipe_texture_reference(&aaline->state.texture[i], NULL); +      pipe_sampler_view_reference(&aaline->state.sampler_views[i], NULL);     }     if (aaline->sampler_cso) @@ -733,6 +748,10 @@ aaline_destroy(struct draw_stage *stage)     if (aaline->texture)        pipe_texture_reference(&aaline->texture, NULL); +   if (aaline->sampler_view) { +      pipe_sampler_view_reference(&aaline->sampler_view, NULL); +   } +     draw_free_temp_verts( stage );     FREE( stage ); @@ -844,23 +863,24 @@ aaline_bind_sampler_states(struct pipe_context *pipe,  static void -aaline_set_sampler_textures(struct pipe_context *pipe, -                            unsigned num, struct pipe_texture **texture) +aaline_set_sampler_views(struct pipe_context *pipe, +                         unsigned num, +                         struct pipe_sampler_view **views)  {     struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);     uint i;     /* save current */     for (i = 0; i < num; i++) { -      pipe_texture_reference(&aaline->state.texture[i], texture[i]); +      pipe_sampler_view_reference(&aaline->state.sampler_views[i], views[i]);     }     for ( ; i < PIPE_MAX_SAMPLERS; i++) { -      pipe_texture_reference(&aaline->state.texture[i], NULL); +      pipe_sampler_view_reference(&aaline->state.sampler_views[i], NULL);     } -   aaline->num_textures = num; +   aaline->num_sampler_views = num;     /* pass-through */ -   aaline->driver_set_sampler_textures(aaline->pipe, num, texture); +   aaline->driver_set_sampler_views(aaline->pipe, num, views);  } @@ -898,7 +918,7 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe)     aaline->driver_delete_fs_state = pipe->delete_fs_state;     aaline->driver_bind_sampler_states = pipe->bind_fragment_sampler_states; -   aaline->driver_set_sampler_textures = pipe->set_fragment_sampler_textures; +   aaline->driver_set_sampler_views = pipe->set_fragment_sampler_views;     /* override the driver's functions */     pipe->create_fs_state = aaline_create_fs_state; @@ -906,7 +926,7 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe)     pipe->delete_fs_state = aaline_delete_fs_state;     pipe->bind_fragment_sampler_states = aaline_bind_sampler_states; -   pipe->set_fragment_sampler_textures = aaline_set_sampler_textures; +   pipe->set_fragment_sampler_views = aaline_set_sampler_views;     /* Install once everything is known to be OK:      */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index d0d99aa331..e03081d65c 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -42,6 +42,7 @@  #include "util/u_format.h"  #include "util/u_math.h"  #include "util/u_memory.h" +#include "util/u_sampler.h"  #include "tgsi/tgsi_transform.h"  #include "tgsi/tgsi_dump.h" @@ -75,8 +76,9 @@ struct pstip_stage     void *sampler_cso;     struct pipe_texture *texture; +   struct pipe_sampler_view *sampler_view;     uint num_samplers; -   uint num_textures; +   uint num_sampler_views;     /*      * Currently bound state @@ -84,7 +86,7 @@ struct pstip_stage     struct pstip_fragment_shader *fs;     struct {        void *samplers[PIPE_MAX_SAMPLERS]; -      struct pipe_texture *textures[PIPE_MAX_SAMPLERS]; +      struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];        const struct pipe_poly_stipple *stipple;     } state; @@ -98,8 +100,9 @@ struct pstip_stage     void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, void **); -   void (*driver_set_sampler_textures)(struct pipe_context *, unsigned, -                                       struct pipe_texture **); +   void (*driver_set_sampler_views)(struct pipe_context *, +                                    unsigned, +                                    struct pipe_sampler_view **);     void (*driver_set_polygon_stipple)(struct pipe_context *,                                        const struct pipe_poly_stipple *); @@ -422,6 +425,7 @@ pstip_create_texture(struct pstip_stage *pstip)     struct pipe_context *pipe = pstip->pipe;     struct pipe_screen *screen = pipe->screen;     struct pipe_texture texTemp; +   struct pipe_sampler_view viewTempl;     memset(&texTemp, 0, sizeof(texTemp));     texTemp.target = PIPE_TEXTURE_2D; @@ -435,6 +439,16 @@ pstip_create_texture(struct pstip_stage *pstip)     if (pstip->texture == NULL)        return FALSE; +   u_sampler_view_default_template(&viewTempl, +                                   pstip->texture, +                                   pstip->texture->format); +   pstip->sampler_view = pipe->create_sampler_view(pipe, +                                                   pstip->texture, +                                                   &viewTempl); +   if (!pstip->sampler_view) { +      return FALSE; +   } +     return TRUE;  } @@ -513,19 +527,19 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header)     /* how many samplers? */     /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */ -   num_samplers = MAX2(pstip->num_textures, pstip->num_samplers); +   num_samplers = MAX2(pstip->num_sampler_views, pstip->num_samplers);     num_samplers = MAX2(num_samplers, pstip->fs->sampler_unit + 1);     /* plug in our sampler, texture */     pstip->state.samplers[pstip->fs->sampler_unit] = pstip->sampler_cso; -   pipe_texture_reference(&pstip->state.textures[pstip->fs->sampler_unit], -                          pstip->texture); +   pipe_sampler_view_reference(&pstip->state.sampler_views[pstip->fs->sampler_unit], +                               pstip->sampler_view);     assert(num_samplers <= PIPE_MAX_SAMPLERS);     draw->suspend_flushing = TRUE;     pstip->driver_bind_sampler_states(pipe, num_samplers, pstip->state.samplers); -   pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures); +   pstip->driver_set_sampler_views(pipe, num_samplers, pstip->state.sampler_views);     draw->suspend_flushing = FALSE;     /* now really draw first triangle */ @@ -549,8 +563,9 @@ pstip_flush(struct draw_stage *stage, unsigned flags)     pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs);     pstip->driver_bind_sampler_states(pipe, pstip->num_samplers,                                       pstip->state.samplers); -   pstip->driver_set_sampler_textures(pipe, pstip->num_textures, -                                      pstip->state.textures); +   pstip->driver_set_sampler_views(pipe, +                                   pstip->num_sampler_views, +                                   pstip->state.sampler_views);     draw->suspend_flushing = FALSE;  } @@ -569,13 +584,17 @@ pstip_destroy(struct draw_stage *stage)     uint i;     for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { -      pipe_texture_reference(&pstip->state.textures[i], NULL); +      pipe_sampler_view_reference(&pstip->state.sampler_views[i], NULL);     }     pstip->pipe->delete_sampler_state(pstip->pipe, pstip->sampler_cso);     pipe_texture_reference(&pstip->texture, NULL); +   if (pstip->sampler_view) { +      pipe_sampler_view_reference(&pstip->sampler_view, NULL); +   } +     draw_free_temp_verts( stage );     FREE( stage );  } @@ -680,24 +699,25 @@ pstip_bind_sampler_states(struct pipe_context *pipe,  static void -pstip_set_sampler_textures(struct pipe_context *pipe, -                           unsigned num, struct pipe_texture **texture) +pstip_set_sampler_views(struct pipe_context *pipe, +                        unsigned num, +                        struct pipe_sampler_view **views)  {     struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);     uint i;     /* save current */     for (i = 0; i < num; i++) { -      pipe_texture_reference(&pstip->state.textures[i], texture[i]); +      pipe_sampler_view_reference(&pstip->state.sampler_views[i], views[i]);     }     for (; i < PIPE_MAX_SAMPLERS; i++) { -      pipe_texture_reference(&pstip->state.textures[i], NULL); +      pipe_sampler_view_reference(&pstip->state.sampler_views[i], NULL);     } -   pstip->num_textures = num; +   pstip->num_sampler_views = num;     /* pass-through */ -   pstip->driver_set_sampler_textures(pstip->pipe, num, texture); +   pstip->driver_set_sampler_views(pstip->pipe, num, views);  } @@ -754,7 +774,7 @@ draw_install_pstipple_stage(struct draw_context *draw,     pstip->driver_delete_fs_state = pipe->delete_fs_state;     pstip->driver_bind_sampler_states = pipe->bind_fragment_sampler_states; -   pstip->driver_set_sampler_textures = pipe->set_fragment_sampler_textures; +   pstip->driver_set_sampler_views = pipe->set_fragment_sampler_views;     pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple;     /* override the driver's functions */ @@ -763,7 +783,7 @@ draw_install_pstipple_stage(struct draw_context *draw,     pipe->delete_fs_state = pstip_delete_fs_state;     pipe->bind_fragment_sampler_states = pstip_bind_sampler_states; -   pipe->set_fragment_sampler_textures = pstip_set_sampler_textures; +   pipe->set_fragment_sampler_views = pstip_set_sampler_views;     pipe->set_polygon_stipple = pstip_set_polygon_stipple;     return TRUE; diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 33d09085f0..71cf9525d3 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -45,6 +45,7 @@  #include "util/u_draw_quad.h"  #include "util/u_pack_color.h"  #include "util/u_rect.h" +#include "util/u_sampler.h"  #include "util/u_simple_shaders.h"  #include "util/u_texture.h" @@ -96,6 +97,8 @@ struct blitter_context_priv     /* Rasterizer state. */     void *rs_state; +   struct pipe_sampler_view *sampler_view; +     /* Viewport state. */     struct pipe_viewport_state viewport; @@ -127,7 +130,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)     ctx->blitter.saved_vs = INVALID_PTR;     ctx->blitter.saved_velem_state = INVALID_PTR;     ctx->blitter.saved_fb_state.nr_cbufs = ~0; -   ctx->blitter.saved_num_textures = ~0; +   ctx->blitter.saved_num_sampler_views = ~0;     ctx->blitter.saved_num_sampler_states = ~0;     /* blend state objects */ @@ -250,6 +253,10 @@ void util_blitter_destroy(struct blitter_context *blitter)        if (ctx->sampler_state[i])           pipe->delete_sampler_state(pipe, ctx->sampler_state[i]); +   if (ctx->sampler_view) { +      pipe_sampler_view_reference(&ctx->sampler_view, NULL); +   } +     pipe_buffer_reference(&ctx->vbuf, NULL);     FREE(ctx);  } @@ -303,11 +310,11 @@ static void blitter_restore_CSOs(struct blitter_context_priv *ctx)        ctx->blitter.saved_num_sampler_states = ~0;     } -   if (ctx->blitter.saved_num_textures != ~0) { -      pipe->set_fragment_sampler_textures(pipe, -                                          ctx->blitter.saved_num_textures, -                                          ctx->blitter.saved_textures); -      ctx->blitter.saved_num_textures = ~0; +   if (ctx->blitter.saved_num_sampler_views != ~0) { +      pipe->set_fragment_sampler_views(pipe, +                                       ctx->blitter.saved_num_sampler_views, +                                       ctx->blitter.saved_sampler_views); +      ctx->blitter.saved_num_sampler_views = ~0;     }  } @@ -619,9 +626,10 @@ static void util_blitter_do_copy(struct blitter_context *blitter,     struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;     struct pipe_context *pipe = ctx->pipe;     struct pipe_framebuffer_state fb_state; +   struct pipe_sampler_view viewTempl, *view;     assert(blitter->saved_fb_state.nr_cbufs != ~0); -   assert(blitter->saved_num_textures != ~0); +   assert(blitter->saved_num_sampler_views != ~0);     assert(blitter->saved_num_sampler_states != ~0);     assert(src->texture->target < PIPE_MAX_TEXTURE_TYPES); @@ -649,12 +657,24 @@ static void util_blitter_do_copy(struct blitter_context *blitter,        fb_state.zsbuf = 0;     } +   u_sampler_view_default_template(&viewTempl, +                                   src->texture, +                                   src->texture->format); +   view = pipe->create_sampler_view(pipe, +                                    src->texture, +                                    &viewTempl); + +   if (ctx->sampler_view) { +      pipe_sampler_view_reference(&ctx->sampler_view, NULL); +   } +   ctx->sampler_view = view; +     pipe->bind_rasterizer_state(pipe, ctx->rs_state);     pipe->bind_vs_state(pipe, ctx->vs_tex);     pipe->bind_fragment_sampler_states(pipe, 1,        blitter_get_sampler_state(ctx, src->level));     pipe->bind_vertex_elements_state(pipe, ctx->velem_state); -   pipe->set_fragment_sampler_textures(pipe, 1, &src->texture); +   pipe->set_fragment_sampler_views(pipe, 1, &view);     pipe->set_framebuffer_state(pipe, &fb_state);     /* set texture coordinates */ diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h index ecafdabafa..2ad7201a29 100644 --- a/src/gallium/auxiliary/util/u_blitter.h +++ b/src/gallium/auxiliary/util/u_blitter.h @@ -53,10 +53,10 @@ struct blitter_context     struct pipe_clip_state saved_clip;     int saved_num_sampler_states; -   void *saved_sampler_states[32]; +   void *saved_sampler_states[PIPE_MAX_SAMPLERS]; -   int saved_num_textures; -   struct pipe_texture *saved_textures[32]; /* is 32 enough? */ +   int saved_num_sampler_views; +   struct pipe_sampler_view *saved_sampler_views[PIPE_MAX_SAMPLERS];  };  /** @@ -242,17 +242,17 @@ void util_blitter_save_fragment_sampler_states(            num_sampler_states * sizeof(void *));  } -static INLINE -void util_blitter_save_fragment_sampler_textures( -                  struct blitter_context *blitter, -                  int num_textures, -                  struct pipe_texture **textures) +static INLINE void +util_blitter_save_fragment_sampler_views(struct blitter_context *blitter, +                                         int num_views, +                                         struct pipe_sampler_view **views)  { -   assert(num_textures <= Elements(blitter->saved_textures)); +   assert(num_views <= Elements(blitter->saved_sampler_views)); -   blitter->saved_num_textures = num_textures; -   memcpy(blitter->saved_textures, textures, -          num_textures * sizeof(struct pipe_texture *)); +   blitter->saved_num_sampler_views = num_views; +   memcpy(blitter->saved_sampler_views, +          views, +          num_views * sizeof(struct pipe_sampler_view *));  }  #ifdef __cplusplus diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h index 0cb3432c6e..84d849aa90 100644 --- a/src/gallium/auxiliary/util/u_inlines.h +++ b/src/gallium/auxiliary/util/u_inlines.h @@ -120,6 +120,16 @@ pipe_texture_reference(struct pipe_texture **ptr, struct pipe_texture *tex)     *ptr = tex;  } +static INLINE void +pipe_sampler_view_reference(struct pipe_sampler_view **ptr, struct pipe_sampler_view *view) +{ +   struct pipe_sampler_view *old_view = *ptr; + +   if (pipe_reference(&(*ptr)->reference, &view->reference)) +      old_view->context->sampler_view_destroy(old_view->context, old_view); +   *ptr = view; +} +  /*   * Convenience wrappers for screen buffer functions. diff --git a/src/gallium/auxiliary/util/u_sampler.c b/src/gallium/auxiliary/util/u_sampler.c new file mode 100644 index 0000000000..08cf1fcf22 --- /dev/null +++ b/src/gallium/auxiliary/util/u_sampler.c @@ -0,0 +1,100 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "u_format.h" +#include "u_sampler.h" + + +static void +default_template(struct pipe_sampler_view *view, +                 const struct pipe_texture *texture, +                 enum pipe_format format, +                 unsigned expand_green_blue) +{ +   /* XXX: Check if format is compatible with texture->format. +    */ + +   view->format = format; +   view->first_level = 0; +   view->num_levels = texture->last_level + 1; +   view->swizzle_r = PIPE_SWIZZLE_RED; +   view->swizzle_g = PIPE_SWIZZLE_GREEN; +   view->swizzle_b = PIPE_SWIZZLE_BLUE; +   view->swizzle_a = PIPE_SWIZZLE_ALPHA; + +   /* Override default green and blue component expansion to the requested +    * one. +    * +    * Gallium expands nonexistent components to (0,0,0,1), DX9 expands +    * to (1,1,1,1).  Since alpha is always expanded to 1, and red is +    * always present, we only really care about green and blue +    * components. +    * +    * To make it look less hackish, one would have to add +    * UTIL_FORMAT_SWIZZLE_EXPAND to indicate components for expansion +    * and then override without exceptions or favoring one component +    * over another. +    */ +   if (format != PIPE_FORMAT_A8_UNORM) { +      const struct util_format_description *desc = util_format_description(format); + +      assert(desc); +      if (desc) { +         if (desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_0) { +            view->swizzle_g = expand_green_blue; +         } +         if (desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_0) { +            view->swizzle_b = expand_green_blue; +         } +      } +   } +} + +void +u_sampler_view_default_template(struct pipe_sampler_view *view, +                                const struct pipe_texture *texture, +                                enum pipe_format format) +{ +   /* Expand to (0, 0, 0, 1) */ +   default_template(view, +                    texture, +                    format, +                    PIPE_SWIZZLE_ZERO); +} + +void +u_sampler_view_default_dx9_template(struct pipe_sampler_view *view, +                                    const struct pipe_texture *texture, +                                    enum pipe_format format) +{ +   /* Expand to (1, 1, 1, 1) */ +   default_template(view, +                    texture, +                    format, +                    PIPE_SWIZZLE_ONE); +} diff --git a/src/gallium/auxiliary/util/u_sampler.h b/src/gallium/auxiliary/util/u_sampler.h new file mode 100644 index 0000000000..bdd061c851 --- /dev/null +++ b/src/gallium/auxiliary/util/u_sampler.h @@ -0,0 +1,57 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#ifndef U_SAMPLER_H +#define U_SAMPLER_H + + +#include "pipe/p_defines.h" +#include "pipe/p_format.h" +#include "pipe/p_state.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +void +u_sampler_view_default_template(struct pipe_sampler_view *view, +                                const struct pipe_texture *texture, +                                enum pipe_format format); + +void +u_sampler_view_default_dx9_template(struct pipe_sampler_view *view, +                                    const struct pipe_texture *texture, +                                    enum pipe_format format); + + +#ifdef __cplusplus +} /* extern "C" { */ +#endif + +#endif /* U_SAMPLER_H */ diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c index 79481b710b..024d9577bc 100644 --- a/src/gallium/auxiliary/util/u_tile.c +++ b/src/gallium/auxiliary/util/u_tile.c @@ -1274,6 +1274,48 @@ pipe_get_tile_rgba(struct pipe_transfer *pt,  void +pipe_get_tile_swizzle(struct pipe_transfer *pt, +                      uint x, +                      uint y, +                      uint w, +                      uint h, +                      uint swizzle_r, +                      uint swizzle_g, +                      uint swizzle_b, +                      uint swizzle_a, +                      float *p) +{ +   uint i; +   float rgba01[6]; + +   pipe_get_tile_rgba(pt, x, y, w, h, p); + +   if (swizzle_r == PIPE_SWIZZLE_RED && +       swizzle_g == PIPE_SWIZZLE_GREEN && +       swizzle_b == PIPE_SWIZZLE_BLUE && +       swizzle_a == PIPE_SWIZZLE_ALPHA) { +      /* no-op, skip */ +      return; +   } + +   rgba01[PIPE_SWIZZLE_ZERO] = 0.0f; +   rgba01[PIPE_SWIZZLE_ONE] = 1.0f; + +   for (i = 0; i < w * h; i++) { +      rgba01[PIPE_SWIZZLE_RED] = p[0]; +      rgba01[PIPE_SWIZZLE_GREEN] = p[1]; +      rgba01[PIPE_SWIZZLE_BLUE] = p[2]; +      rgba01[PIPE_SWIZZLE_ALPHA] = p[3]; + +      *p++ = rgba01[swizzle_r]; +      *p++ = rgba01[swizzle_g]; +      *p++ = rgba01[swizzle_b]; +      *p++ = rgba01[swizzle_a]; +   } +} + + +void  pipe_put_tile_rgba(struct pipe_transfer *pt,                     uint x, uint y, uint w, uint h,                     const float *p) diff --git a/src/gallium/auxiliary/util/u_tile.h b/src/gallium/auxiliary/util/u_tile.h index 1453af38b8..b4706179a5 100644 --- a/src/gallium/auxiliary/util/u_tile.h +++ b/src/gallium/auxiliary/util/u_tile.h @@ -72,6 +72,18 @@ pipe_get_tile_rgba(struct pipe_transfer *pt,                     float *p);  void +pipe_get_tile_swizzle(struct pipe_transfer *pt, +                      uint x, +                      uint y, +                      uint w, +                      uint h, +                      uint swizzle_r, +                      uint swizzle_g, +                      uint swizzle_b, +                      uint swizzle_a, +                      float *p); + +void  pipe_put_tile_rgba(struct pipe_transfer *pt,                     uint x, uint y, uint w, uint h,                     const float *p); diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst index 4608e97adb..ef3e463931 100644 --- a/src/gallium/docs/source/context.rst +++ b/src/gallium/docs/source/context.rst @@ -40,8 +40,24 @@ buffers, surfaces) are bound to the driver.    are mostly restricted to the first one right now).  * ``set_framebuffer_state`` -* ``set_fragment_sampler_textures`` -* ``set_vertex_sampler_textures`` + +* ``set_fragment_sampler_views`` binds an array of sampler views to +  fragment shader stage. Every binding point acquires a reference +  to a respective sampler view and releases a reference to the previous +  sampler view. + +* ``set_vertex_sampler_views`` binds an array of sampler views to vertex +  shader stage. Every binding point acquires a reference to a respective +  sampler view and releases a reference to the previous sampler view. + +* ``create_sampler_view`` creates a new sampler view. texture is associated +  with the sampler view which results in sampler view holding a reference +  to the texture. Format specified in template must be compatible +  with texture format. + +* ``sampler_view_destroy`` destroys a sampler view and releases its reference +  to associated texture. +  * ``set_vertex_buffers`` diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index 28f80b82cd..4d87f9a038 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -127,6 +127,7 @@ struct cell_context     struct pipe_poly_stipple poly_stipple;     struct pipe_scissor_state scissor;     struct cell_texture *texture[PIPE_MAX_SAMPLERS]; +   struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];     uint num_textures;     struct pipe_viewport_state viewport;     struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index dce10ae7f8..2fc82933e4 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -257,8 +257,9 @@ cell_delete_sampler_state(struct pipe_context *pipe,  static void -cell_set_sampler_textures(struct pipe_context *pipe, -                          unsigned num, struct pipe_texture **texture) +cell_set_fragment_sampler_views(struct pipe_context *pipe, +                                unsigned num, +                                struct pipe_sampler_view **views)  {     struct cell_context *cell = cell_context(pipe);     uint i, changed = 0x0; @@ -266,10 +267,14 @@ cell_set_sampler_textures(struct pipe_context *pipe,     assert(num <= CELL_MAX_SAMPLERS);     for (i = 0; i < CELL_MAX_SAMPLERS; i++) { -      struct cell_texture *new_tex = cell_texture(i < num ? texture[i] : NULL); -      struct cell_texture *old_tex = cell->texture[i]; -      if (old_tex != new_tex) { +      struct pipe_sampler_view *new_view = i < num ? views[i] : NULL; +      struct pipe_sampler_view *old_view = cell->fragment_sampler_views[i]; +      if (old_view != new_view) { +         struct pipe_texture *new_tex = new_view ? new_view->texture : NULL; + +         pipe_sampler_view_reference(&cell->fragment_sampler_views[i], +                                     views[i]);           pipe_texture_reference((struct pipe_texture **) &cell->texture[i],                                  (struct pipe_texture *) new_tex); @@ -286,6 +291,32 @@ cell_set_sampler_textures(struct pipe_context *pipe,  } +static struct pipe_sampler_view * +cell_create_sampler_view(struct pipe_context *pipe, +                         struct pipe_texture *texture, +                         const struct pipe_sampler_view *templ) +{ +   struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); + +   *view = *templ; +   view->reference.count = 1; +   view->texture = NULL; +   pipe_texture_reference(&view->texture, texture); +   view->context = pipe; + +   return view; +} + + +static void +cell_sampler_view_destroy(struct pipe_context *pipe, +                          struct pipe_sampler_view *view) +{ +   pipe_texture_reference(&view->texture, NULL); +   FREE(view); +} + +  /**   * Map color and z/stencil framebuffer surfaces.   */ @@ -409,7 +440,9 @@ cell_init_state_functions(struct cell_context *cell)     cell->pipe.bind_fragment_sampler_states = cell_bind_sampler_states;     cell->pipe.delete_sampler_state = cell_delete_sampler_state; -   cell->pipe.set_fragment_sampler_textures = cell_set_sampler_textures; +   cell->pipe.set_fragment_sampler_views = cell_set_fragment_sampler_views; +   cell->pipe.create_sampler_view = cell_create_sampler_view; +   cell->pipe.sampler_view_destroy = cell_sampler_view_destroy;     cell->pipe.create_depth_stencil_alpha_state = cell_create_depth_stencil_alpha_state;     cell->pipe.bind_depth_stencil_alpha_state   = cell_bind_depth_stencil_alpha_state; diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h index 4a754465bb..73031321d9 100644 --- a/src/gallium/drivers/failover/fo_context.h +++ b/src/gallium/drivers/failover/fo_context.h @@ -47,7 +47,7 @@  #define FO_NEW_ALPHA_TEST      0x100  #define FO_NEW_DEPTH_STENCIL   0x200  #define FO_NEW_SAMPLER         0x400 -#define FO_NEW_TEXTURE         0x800 +#define FO_NEW_SAMPLER_VIEW    0x800  #define FO_NEW_VERTEX          0x2000  #define FO_NEW_VERTEX_SHADER   0x4000  #define FO_NEW_BLEND_COLOR     0x8000 @@ -65,6 +65,13 @@ struct fo_state {     void *sw_state;     void *hw_state;  }; + +struct fo_sampler_view { +   struct pipe_sampler_view base; +   struct pipe_sampler_view *sw; +   struct pipe_sampler_view *hw; +}; +  struct failover_context {     struct pipe_context pipe;  /**< base class */ @@ -86,8 +93,6 @@ struct failover_context {     struct pipe_framebuffer_state framebuffer;     struct pipe_poly_stipple poly_stipple;     struct pipe_scissor_state scissor; -   struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; -   struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];     struct pipe_viewport_state viewport;     struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; @@ -98,12 +103,15 @@ struct failover_context {     void *sw_vertex_sampler_state[PIPE_MAX_VERTEX_SAMPLERS];     void *hw_vertex_sampler_state[PIPE_MAX_VERTEX_SAMPLERS]; +   struct fo_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; +   struct fo_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS]; +   unsigned num_fragment_sampler_views; +   unsigned num_vertex_sampler_views; +     unsigned dirty;     unsigned num_samplers;     unsigned num_vertex_samplers; -   unsigned num_textures; -   unsigned num_vertex_textures;     unsigned mode;     struct pipe_context *hw; diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c index 0247fb803b..25c6273570 100644 --- a/src/gallium/drivers/failover/fo_state.c +++ b/src/gallium/drivers/failover/fo_state.c @@ -447,60 +447,96 @@ failover_delete_sampler_state(struct pipe_context *pipe, void *sampler)  } +static struct pipe_sampler_view * +failover_create_sampler_view(struct pipe_context *pipe, +                             struct pipe_texture *texture, +                             const struct pipe_sampler_view *templ) +{ +   struct fo_sampler_view *view = malloc(sizeof(struct fo_sampler_view)); +   struct failover_context *failover = failover_context(pipe); + +   view->sw = failover->sw->create_sampler_view(failover->sw, texture, templ); +   view->hw = failover->hw->create_sampler_view(failover->hw, texture, templ); + +   view->base = *templ; +   view->base.reference.count = 1; +   view->base.texture = NULL; +   pipe_texture_reference(&view->base.texture, texture); +   view->base.context = pipe; + +   return &view->base; +} + +static void +failover_sampler_view_destroy(struct pipe_context *pipe, +                              struct pipe_sampler_view *view) +{ +   struct fo_sampler_view *fo_view = (struct fo_sampler_view *)view; +   struct failover_context *failover = failover_context(pipe); + +   failover->sw->sampler_view_destroy(failover->sw, fo_view->sw); +   failover->hw->sampler_view_destroy(failover->hw, fo_view->hw); + +   pipe_texture_reference(&fo_view->base.texture, NULL); +   free(fo_view); +} +  static void -failover_set_fragment_sampler_textures(struct pipe_context *pipe, -                                       unsigned num, -                                       struct pipe_texture **texture) +failover_set_fragment_sampler_views(struct pipe_context *pipe, +                                    unsigned num, +                                    struct pipe_sampler_view **views)  {     struct failover_context *failover = failover_context(pipe); +   struct pipe_sampler_view *hw_views[PIPE_MAX_SAMPLERS];     uint i;     assert(num <= PIPE_MAX_SAMPLERS);     /* Check for no-op */ -   if (num == failover->num_textures && -       !memcmp(failover->texture, texture, num * sizeof(struct pipe_texture *))) +   if (num == failover->num_fragment_sampler_views && +       !memcmp(failover->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *)))        return; -   for (i = 0; i < num; i++) -      pipe_texture_reference((struct pipe_texture **) &failover->texture[i], -                             texture[i]); -   for (i = num; i < failover->num_textures; i++) -      pipe_texture_reference((struct pipe_texture **) &failover->texture[i], -                             NULL); -   failover->dirty |= FO_NEW_TEXTURE; -   failover->num_textures = num; -   failover->sw->set_fragment_sampler_textures( failover->sw, num, texture ); -   failover->hw->set_fragment_sampler_textures( failover->hw, num, texture ); +   for (i = 0; i < num; i++) { +      struct fo_sampler_view *fo_view = (struct fo_sampler_view *)views[i]; + +      pipe_sampler_view_reference((struct pipe_sampler_view **)&failover->fragment_sampler_views[i], views[i]); +      hw_views[i] = fo_view->hw; +   } +   for (i = num; i < failover->num_fragment_sampler_views; i++) +      pipe_sampler_view_reference((struct pipe_sampler_view **)&failover->fragment_sampler_views[i], NULL); +   failover->dirty |= FO_NEW_SAMPLER_VIEW; +   failover->num_fragment_sampler_views = num; +   failover->hw->set_fragment_sampler_views(failover->hw, num, hw_views);  }  static void -failover_set_vertex_sampler_textures(struct pipe_context *pipe, -                                     unsigned num_textures, -                                     struct pipe_texture **textures) +failover_set_vertex_sampler_views(struct pipe_context *pipe, +                                  unsigned num, +                                  struct pipe_sampler_view **views)  {     struct failover_context *failover = failover_context(pipe); +   struct pipe_sampler_view *hw_views[PIPE_MAX_VERTEX_SAMPLERS];     uint i; -   assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS); +   assert(num <= PIPE_MAX_VERTEX_SAMPLERS);     /* Check for no-op */ -   if (num_textures == failover->num_vertex_textures && -       !memcmp(failover->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) { +   if (num == failover->num_vertex_sampler_views && +       !memcmp(failover->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) {        return;     } -   for (i = 0; i < num_textures; i++) { -      pipe_texture_reference((struct pipe_texture **)&failover->vertex_textures[i], -                             textures[i]); -   } -   for (i = num_textures; i < failover->num_vertex_textures; i++) { -      pipe_texture_reference((struct pipe_texture **)&failover->vertex_textures[i], -                             NULL); +   for (i = 0; i < num; i++) { +      struct fo_sampler_view *fo_view = (struct fo_sampler_view *)views[i]; + +      pipe_sampler_view_reference((struct pipe_sampler_view **)&failover->vertex_sampler_views[i], views[i]); +      hw_views[i] = fo_view->hw;     } -   failover->dirty |= FO_NEW_TEXTURE; -   failover->num_vertex_textures = num_textures; -   failover->sw->set_vertex_sampler_textures(failover->sw, num_textures, textures); -   failover->hw->set_vertex_sampler_textures(failover->hw, num_textures, textures); +   for (i = num; i < failover->num_vertex_sampler_views; i++) +      pipe_sampler_view_reference((struct pipe_sampler_view **)&failover->vertex_sampler_views[i], NULL); +   failover->dirty |= FO_NEW_SAMPLER_VIEW; +   failover->num_vertex_sampler_views = num; +   failover->hw->set_vertex_sampler_views(failover->hw, num, hw_views);  } @@ -580,9 +616,11 @@ failover_init_state_functions( struct failover_context *failover )     failover->pipe.set_framebuffer_state = failover_set_framebuffer_state;     failover->pipe.set_polygon_stipple = failover_set_polygon_stipple;     failover->pipe.set_scissor_state = failover_set_scissor_state; -   failover->pipe.set_fragment_sampler_textures = failover_set_fragment_sampler_textures; -   failover->pipe.set_vertex_sampler_textures = failover_set_vertex_sampler_textures; +   failover->pipe.set_fragment_sampler_views = failover_set_fragment_sampler_views; +   failover->pipe.set_vertex_sampler_views = failover_set_vertex_sampler_views;     failover->pipe.set_viewport_state = failover_set_viewport_state;     failover->pipe.set_vertex_buffers = failover_set_vertex_buffers;     failover->pipe.set_constant_buffer = failover_set_constant_buffer; +   failover->pipe.create_sampler_view = failover_create_sampler_view; +   failover->pipe.sampler_view_destroy = failover_sampler_view_destroy;  } diff --git a/src/gallium/drivers/failover/fo_state_emit.c b/src/gallium/drivers/failover/fo_state_emit.c index 09ca194497..42bd6929a7 100644 --- a/src/gallium/drivers/failover/fo_state_emit.c +++ b/src/gallium/drivers/failover/fo_state_emit.c @@ -106,12 +106,24 @@ failover_state_emit( struct failover_context *failover )                                                 failover->sw_vertex_sampler_state);     } -   if (failover->dirty & FO_NEW_TEXTURE) { -      failover->sw->set_fragment_sampler_textures( failover->sw, failover->num_textures,  -                                                   failover->texture ); -      failover->sw->set_vertex_sampler_textures(failover->sw, -                                                failover->num_vertex_textures,  -                                                failover->vertex_textures); +   if (failover->dirty & FO_NEW_SAMPLER_VIEW) { +      struct pipe_sampler_view *fragment_views[PIPE_MAX_SAMPLERS]; +      struct pipe_sampler_view *vertex_views[PIPE_MAX_VERTEX_SAMPLERS]; +      uint i; + +      for (i = 0; i < failover->num_fragment_sampler_views; i++) { +         fragment_views[i] = failover->fragment_sampler_views[i]->sw; +      } +      failover->sw->set_fragment_sampler_views(failover->sw, +                                               failover->num_fragment_sampler_views, +                                               fragment_views); + +      for (i = 0; i < failover->num_vertex_sampler_views; i++) { +         vertex_views[i] = failover->vertex_sampler_views[i]->sw; +      } +      failover->sw->set_vertex_sampler_views(failover->sw, +                                             failover->num_vertex_sampler_views, +                                             vertex_views);     }     if (failover->dirty & FO_NEW_VERTEX_BUFFER) { diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h index 4994537683..9d03ca37fd 100644 --- a/src/gallium/drivers/i915/i915_context.h +++ b/src/gallium/drivers/i915/i915_context.h @@ -247,14 +247,14 @@ struct i915_context     struct pipe_framebuffer_state framebuffer;     struct pipe_poly_stipple poly_stipple;     struct pipe_scissor_state scissor; -   struct i915_texture *texture[PIPE_MAX_SAMPLERS]; +   struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];     struct pipe_viewport_state viewport;     struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];     unsigned dirty;     unsigned num_samplers; -   unsigned num_textures; +   unsigned num_fragment_sampler_views;     unsigned num_vertex_buffers;     struct intel_batchbuffer *batch; @@ -283,7 +283,7 @@ struct i915_context  #define I915_NEW_ALPHA_TEST    0x100  #define I915_NEW_DEPTH_STENCIL 0x200  #define I915_NEW_SAMPLER       0x400 -#define I915_NEW_TEXTURE       0x800 +#define I915_NEW_SAMPLER_VIEW  0x800  #define I915_NEW_CONSTANTS     0x1000  #define I915_NEW_VBO           0x2000  #define I915_NEW_VS            0x4000 diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index 8927dfc33d..884abe622b 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -560,9 +560,9 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,  } -static void i915_set_sampler_textures(struct pipe_context *pipe, -                                      unsigned num, -                                      struct pipe_texture **texture) +static void i915_set_fragment_sampler_views(struct pipe_context *pipe, +                                            unsigned num, +                                            struct pipe_sampler_view **views)  {     struct i915_context *i915 = i915_context(pipe);     uint i; @@ -570,27 +570,52 @@ static void i915_set_sampler_textures(struct pipe_context *pipe,     assert(num <= PIPE_MAX_SAMPLERS);     /* Check for no-op */ -   if (num == i915->num_textures && -       !memcmp(i915->texture, texture, num * sizeof(struct pipe_texture *))) +   if (num == i915->num_fragment_sampler_views && +       !memcmp(i915->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *)))        return;     /* Fixes wrong texture in texobj with VBUF */     draw_flush(i915->draw);     for (i = 0; i < num; i++) -      pipe_texture_reference((struct pipe_texture **) &i915->texture[i], -                             texture[i]); +      pipe_sampler_view_reference(&i915->fragment_sampler_views[i], +                                  views[i]); -   for (i = num; i < i915->num_textures; i++) -      pipe_texture_reference((struct pipe_texture **) &i915->texture[i], -                             NULL); +   for (i = num; i < i915->num_fragment_sampler_views; i++) +      pipe_sampler_view_reference(&i915->fragment_sampler_views[i], +                                  NULL); -   i915->num_textures = num; +   i915->num_fragment_sampler_views = num; -   i915->dirty |= I915_NEW_TEXTURE; +   i915->dirty |= I915_NEW_SAMPLER_VIEW;  } +static struct pipe_sampler_view * +i915_create_sampler_view(struct pipe_context *pipe, +                         struct pipe_texture *texture, +                         const struct pipe_sampler_view *templ) +{ +   struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); + +   *view = *templ; +   view->reference.count = 1; +   view->texture = NULL; +   pipe_texture_reference(&view->texture, texture); +   view->context = pipe; + +   return view; +} + + +static void +i915_sampler_view_destroy(struct pipe_context *pipe, +                          struct pipe_sampler_view *view) +{ +   pipe_texture_reference(&view->texture, NULL); +   FREE(view); +} +  static void i915_set_framebuffer_state(struct pipe_context *pipe,  				       const struct pipe_framebuffer_state *fb) @@ -815,7 +840,9 @@ i915_init_state_functions( struct i915_context *i915 )     i915->base.set_polygon_stipple = i915_set_polygon_stipple;     i915->base.set_scissor_state = i915_set_scissor_state; -   i915->base.set_fragment_sampler_textures = i915_set_sampler_textures; +   i915->base.set_fragment_sampler_views = i915_set_fragment_sampler_views; +   i915->base.create_sampler_view = i915_create_sampler_view; +   i915->base.sampler_view_destroy = i915_sampler_view_destroy;     i915->base.set_viewport_state = i915_set_viewport_state;     i915->base.set_vertex_buffers = i915_set_vertex_buffers;  } diff --git a/src/gallium/drivers/i915/i915_state_derived.c b/src/gallium/drivers/i915/i915_state_derived.c index f5b0e9f011..0eb1e3f91a 100644 --- a/src/gallium/drivers/i915/i915_state_derived.c +++ b/src/gallium/drivers/i915/i915_state_derived.c @@ -157,10 +157,10 @@ void i915_update_derived( struct i915_context *i915 )     if (i915->dirty & (I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS))        calculate_vertex_layout( i915 ); -   if (i915->dirty & (I915_NEW_SAMPLER | I915_NEW_TEXTURE)) +   if (i915->dirty & (I915_NEW_SAMPLER | I915_NEW_SAMPLER_VIEW))        i915_update_samplers(i915); -   if (i915->dirty & I915_NEW_TEXTURE) +   if (i915->dirty & I915_NEW_SAMPLER_VIEW)        i915_update_textures(i915);     if (i915->dirty) diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c index 51f0ef12ba..d79c1ca0b2 100644 --- a/src/gallium/drivers/i915/i915_state_emit.c +++ b/src/gallium/drivers/i915/i915_state_emit.c @@ -290,7 +290,8 @@ i915_emit_hardware_state(struct i915_context *i915 )              OUT_BATCH(enabled);              for (unit = 0; unit < I915_TEX_UNITS; unit++) {                 if (enabled & (1 << unit)) { -                  struct intel_buffer *buf = i915->texture[unit]->buffer; +                  struct i915_texture *texture = (struct i915_texture *)i915->fragment_sampler_views[unit]->texture; +                  struct intel_buffer *buf = texture->buffer;                    uint offset = 0;                    assert(buf); diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c index 9813290b51..d6da822549 100644 --- a/src/gallium/drivers/i915/i915_state_sampler.c +++ b/src/gallium/drivers/i915/i915_state_sampler.c @@ -144,20 +144,22 @@ void i915_update_samplers( struct i915_context *i915 )     i915->current.sampler_enable_nr = 0;     i915->current.sampler_enable_flags = 0x0; -   for (unit = 0; unit < i915->num_textures && unit < i915->num_samplers; +   for (unit = 0; unit < i915->num_fragment_sampler_views && unit < i915->num_samplers;          unit++) {        /* determine unit enable/disable by looking for a bound texture */        /* could also examine the fragment program? */ -      if (i915->texture[unit]) { +      if (i915->fragment_sampler_views[unit]) { +         struct i915_texture *texture = (struct i915_texture *)i915->fragment_sampler_views[unit]->texture; +  	 update_sampler( i915,  	                 unit,  	                 i915->sampler[unit],       /* sampler state */ -	                 i915->texture[unit],        /* texture */ +	                 texture,                    /* texture */  	                 i915->current.sampler[unit] /* the result */  	                 );  	 i915_update_texture( i915,  	                      unit, -	                      i915->texture[unit],          /* texture */ +	                      texture,                      /* texture */  	                      i915->sampler[unit],          /* sampler state */  	                      i915->current.texbuffer[unit] ); @@ -281,14 +283,16 @@ i915_update_textures(struct i915_context *i915)  {     uint unit; -   for (unit = 0; unit < i915->num_textures && unit < i915->num_samplers; +   for (unit = 0; unit < i915->num_fragment_sampler_views && unit < i915->num_samplers;          unit++) {        /* determine unit enable/disable by looking for a bound texture */        /* could also examine the fragment program? */ -      if (i915->texture[unit]) { +      if (i915->fragment_sampler_views[unit]) { +         struct i915_texture *texture = (struct i915_texture *)i915->fragment_sampler_views[unit]->texture; +  	 i915_update_texture( i915,  	                      unit, -	                      i915->texture[unit],          /* texture */ +	                      texture,                      /* texture */  	                      i915->sampler[unit],          /* sampler state */  	                      i915->current.texbuffer[unit] );        } diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h index f5b1a06576..dab881fea2 100644 --- a/src/gallium/drivers/i965/brw_context.h +++ b/src/gallium/drivers/i965/brw_context.h @@ -551,9 +551,9 @@ struct brw_context        const struct brw_sampler *sampler[PIPE_MAX_SAMPLERS];        unsigned num_samplers; -      struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; +      struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];        struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; -      unsigned num_textures; +      unsigned num_fragment_sampler_views;        unsigned num_vertex_buffers;        struct pipe_scissor_state scissor; diff --git a/src/gallium/drivers/i965/brw_pipe_sampler.c b/src/gallium/drivers/i965/brw_pipe_sampler.c index c7c0e2ae95..fbc3a07d61 100644 --- a/src/gallium/drivers/i965/brw_pipe_sampler.c +++ b/src/gallium/drivers/i965/brw_pipe_sampler.c @@ -183,26 +183,26 @@ static void brw_delete_sampler_state(struct pipe_context *pipe,     FREE(cso);  } -static void brw_set_sampler_textures(struct pipe_context *pipe, -				     unsigned num, -				     struct pipe_texture **texture) +static void brw_set_fragment_sampler_views(struct pipe_context *pipe, +                                           unsigned num, +                                           struct pipe_sampler_view **views)  {     struct brw_context *brw = brw_context(pipe);     int i;     for (i = 0; i < num; i++) -      pipe_texture_reference(&brw->curr.texture[i], texture[i]); +      pipe_sampler_view_reference(&brw->curr.fragment_sampler_views[i], views[i]); -   for (i = num; i < brw->curr.num_textures; i++) -      pipe_texture_reference(&brw->curr.texture[i], NULL); +   for (i = num; i < brw->curr.num_fragment_sampler_views; i++) +      pipe_sampler_view_reference(&brw->curr.fragment_sampler_views[i], NULL); -   brw->curr.num_textures = num; +   brw->curr.num_fragment_sampler_views = num;     brw->state.dirty.mesa |= PIPE_NEW_BOUND_TEXTURES;  } -static void brw_set_vertex_sampler_textures(struct pipe_context *pipe, -                                            unsigned num, -                                            struct pipe_texture **texture) +static void brw_set_vertex_sampler_views(struct pipe_context *pipe, +                                         unsigned num, +                                         struct pipe_sampler_view **views)  {  } @@ -212,17 +212,45 @@ static void brw_bind_vertex_sampler_state(struct pipe_context *pipe,  } +static struct pipe_sampler_view * +brw_create_sampler_view(struct pipe_context *pipe, +                        struct pipe_texture *texture, +                        const struct pipe_sampler_view *templ) +{ +   struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); + +   *view = *templ; +   view->reference.count = 1; +   view->texture = NULL; +   pipe_texture_reference(&view->texture, texture); +   view->context = pipe; + +   return view; +} + + +static void +brw_sampler_view_destroy(struct pipe_context *pipe, +                         struct pipe_sampler_view *view) +{ +   pipe_texture_reference(&view->texture, NULL); +   FREE(view); +} + +  void brw_pipe_sampler_init( struct brw_context *brw )  {     brw->base.create_sampler_state = brw_create_sampler_state;     brw->base.delete_sampler_state = brw_delete_sampler_state; -   brw->base.set_fragment_sampler_textures = brw_set_sampler_textures; +   brw->base.set_fragment_sampler_views = brw_set_fragment_sampler_views;     brw->base.bind_fragment_sampler_states = brw_bind_sampler_state; -   brw->base.set_vertex_sampler_textures = brw_set_vertex_sampler_textures; +   brw->base.set_vertex_sampler_views = brw_set_vertex_sampler_views;     brw->base.bind_vertex_sampler_states = brw_bind_vertex_sampler_state; +   brw->base.create_sampler_view = brw_create_sampler_view; +   brw->base.sampler_view_destroy = brw_sampler_view_destroy;  }  void brw_pipe_sampler_cleanup( struct brw_context *brw )  { diff --git a/src/gallium/drivers/i965/brw_wm.c b/src/gallium/drivers/i965/brw_wm.c index dfb718e64f..7ed2378ec0 100644 --- a/src/gallium/drivers/i965/brw_wm.c +++ b/src/gallium/drivers/i965/brw_wm.c @@ -251,8 +251,8 @@ static void brw_wm_populate_key( struct brw_context *brw,     /* PIPE_NEW_BOUND_TEXTURES */ -   for (i = 0; i < brw->curr.num_textures; i++) { -      const struct brw_texture *tex = brw_texture(brw->curr.texture[i]); +   for (i = 0; i < brw->curr.num_fragment_sampler_views; i++) { +      const struct brw_texture *tex = brw_texture(brw->curr.fragment_sampler_views[i]->texture);        if (tex->base.format == PIPE_FORMAT_UYVY)  	 key->yuvtex_mask |= 1 << i; diff --git a/src/gallium/drivers/i965/brw_wm_sampler_state.c b/src/gallium/drivers/i965/brw_wm_sampler_state.c index 6a6086fc51..3f18062c58 100644 --- a/src/gallium/drivers/i965/brw_wm_sampler_state.c +++ b/src/gallium/drivers/i965/brw_wm_sampler_state.c @@ -78,11 +78,11 @@ brw_wm_sampler_populate_key(struct brw_context *brw,     memset(key, 0, sizeof(*key)); -   key->sampler_count = MIN2(brw->curr.num_textures, +   key->sampler_count = MIN2(brw->curr.num_fragment_sampler_views,  			    brw->curr.num_samplers);     for (i = 0; i < key->sampler_count; i++) { -      const struct brw_texture *tex = brw_texture(brw->curr.texture[i]); +      const struct brw_texture *tex = brw_texture(brw->curr.fragment_sampler_views[i]->texture);        const struct brw_sampler *sampler = brw->curr.sampler[i];        struct brw_sampler_state *entry = &key->sampler[i]; @@ -122,12 +122,12 @@ static enum pipe_error  brw_wm_sampler_update_default_colors(struct brw_context *brw)  {     enum pipe_error ret; -   int nr = MIN2(brw->curr.num_textures, +   int nr = MIN2(brw->curr.num_fragment_sampler_views,  		 brw->curr.num_samplers);     int i;     for (i = 0; i < nr; i++) { -      const struct brw_texture *tex = brw_texture(brw->curr.texture[i]); +      const struct brw_texture *tex = brw_texture(brw->curr.fragment_sampler_views[i]->texture);        const struct brw_sampler *sampler = brw->curr.sampler[i];        const float *bc;        float bordercolor[4] = { diff --git a/src/gallium/drivers/i965/brw_wm_surface_state.c b/src/gallium/drivers/i965/brw_wm_surface_state.c index b01a7f194b..2368ae3f80 100644 --- a/src/gallium/drivers/i965/brw_wm_surface_state.c +++ b/src/gallium/drivers/i965/brw_wm_surface_state.c @@ -242,9 +242,9 @@ static enum pipe_error prepare_wm_surfaces(struct brw_context *brw )     /* PIPE_NEW_TEXTURE       */ -   for (i = 0; i < brw->curr.num_textures; i++) { +   for (i = 0; i < brw->curr.num_fragment_sampler_views; i++) {        ret = brw_update_texture_surface(brw,  -                                       brw_texture(brw->curr.texture[i]), +                                       brw_texture(brw->curr.fragment_sampler_views[i]->texture),                                         &brw->wm.surf_bo[BTI_TEXTURE(i)]);        if (ret)           return ret; @@ -261,7 +261,7 @@ static enum pipe_error prepare_wm_surfaces(struct brw_context *brw )        bo_reference(&brw->wm.surf_bo[BTI_FRAGMENT_CONSTANTS], NULL);           /* XXX: no pipe_max_textures define?? */ -   for (i = brw->curr.num_textures; i < PIPE_MAX_SAMPLERS; i++) +   for (i = brw->curr.num_fragment_sampler_views; i < PIPE_MAX_SAMPLERS; i++)        bo_reference(&brw->wm.surf_bo[BTI_TEXTURE(i)], NULL);     if (brw->wm.nr_surfaces != nr_surfaces) { diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c index baf0ae4401..ef5b428161 100644 --- a/src/gallium/drivers/identity/id_context.c +++ b/src/gallium/drivers/identity/id_context.c @@ -528,53 +528,49 @@ identity_set_viewport_state(struct pipe_context *_pipe,  }  static void -identity_set_fragment_sampler_textures(struct pipe_context *_pipe, -                                       unsigned num_textures, -                                       struct pipe_texture **_textures) +identity_set_fragment_sampler_views(struct pipe_context *_pipe, +                                    unsigned num, +                                    struct pipe_sampler_view **_views)  {     struct identity_context *id_pipe = identity_context(_pipe);     struct pipe_context *pipe = id_pipe->pipe; -   struct pipe_texture *unwrapped_textures[PIPE_MAX_SAMPLERS]; -   struct pipe_texture **textures = NULL; +   struct pipe_sampler_view *unwrapped_views[PIPE_MAX_SAMPLERS]; +   struct pipe_sampler_view **views = NULL;     unsigned i; -   if (_textures) { -      for (i = 0; i < num_textures; i++) -         unwrapped_textures[i] = identity_texture_unwrap(_textures[i]); +   if (_views) { +      for (i = 0; i < num; i++) +         unwrapped_views[i] = identity_sampler_view_unwrap(_views[i]);        for (; i < PIPE_MAX_SAMPLERS; i++) -         unwrapped_textures[i] = NULL; +         unwrapped_views[i] = NULL; -      textures = unwrapped_textures; +      views = unwrapped_views;     } -   pipe->set_fragment_sampler_textures(pipe, -                                       num_textures, -                                       textures); +   pipe->set_fragment_sampler_views(pipe, num, views);  }  static void -identity_set_vertex_sampler_textures(struct pipe_context *_pipe, -                                     unsigned num_textures, -                                     struct pipe_texture **_textures) +identity_set_vertex_sampler_views(struct pipe_context *_pipe, +                                  unsigned num, +                                  struct pipe_sampler_view **_views)  {     struct identity_context *id_pipe = identity_context(_pipe);     struct pipe_context *pipe = id_pipe->pipe; -   struct pipe_texture *unwrapped_textures[PIPE_MAX_VERTEX_SAMPLERS]; -   struct pipe_texture **textures = NULL; +   struct pipe_sampler_view *unwrapped_views[PIPE_MAX_VERTEX_SAMPLERS]; +   struct pipe_sampler_view **views = NULL;     unsigned i; -   if (_textures) { -      for (i = 0; i < num_textures; i++) -         unwrapped_textures[i] = identity_texture_unwrap(_textures[i]); +   if (_views) { +      for (i = 0; i < num; i++) +         unwrapped_views[i] = identity_sampler_view_unwrap(_views[i]);        for (; i < PIPE_MAX_VERTEX_SAMPLERS; i++) -         unwrapped_textures[i] = NULL; +         unwrapped_views[i] = NULL; -      textures = unwrapped_textures; +      views = unwrapped_views;     } -   pipe->set_vertex_sampler_textures(pipe, -                                     num_textures, -                                     textures); +   pipe->set_vertex_sampler_views(pipe, num, views);  }  static void @@ -711,6 +707,46 @@ identity_is_buffer_referenced(struct pipe_context *_pipe,                                       buffer);  } +static struct pipe_sampler_view * +identity_create_sampler_view(struct pipe_context *pipe, +                             struct pipe_texture *texture, +                             const struct pipe_sampler_view *templ) +{ +   struct identity_context *id_pipe = identity_context(pipe); +   struct identity_texture *id_texture = identity_texture(texture); +   struct pipe_context *pipe_unwrapped = id_pipe->pipe; +   struct pipe_texture *texture_unwrapped = id_texture->texture; +   struct identity_sampler_view *view = malloc(sizeof(struct identity_sampler_view)); + +   view->sampler_view = pipe_unwrapped->create_sampler_view(pipe_unwrapped, +                                                            texture_unwrapped, +                                                            templ); + +   view->base = *templ; +   view->base.reference.count = 1; +   view->base.texture = NULL; +   pipe_texture_reference(&view->base.texture, texture); +   view->base.context = pipe; + +   return &view->base; +} + +static void +identity_sampler_view_destroy(struct pipe_context *pipe, +                              struct pipe_sampler_view *view) +{ +   struct identity_context *id_pipe = identity_context(pipe); +   struct identity_sampler_view *id_view = identity_sampler_view(view); +   struct pipe_context *pipe_unwrapped = id_pipe->pipe; +   struct pipe_sampler_view *view_unwrapped = id_view->sampler_view; + +   pipe_unwrapped->sampler_view_destroy(pipe_unwrapped, +                                        view_unwrapped); + +   pipe_texture_reference(&view->texture, NULL); +   free(view); +} +  struct pipe_context *  identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)  { @@ -766,8 +802,8 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)     id_pipe->base.set_polygon_stipple = identity_set_polygon_stipple;     id_pipe->base.set_scissor_state = identity_set_scissor_state;     id_pipe->base.set_viewport_state = identity_set_viewport_state; -   id_pipe->base.set_fragment_sampler_textures = identity_set_fragment_sampler_textures; -   id_pipe->base.set_vertex_sampler_textures = identity_set_vertex_sampler_textures; +   id_pipe->base.set_fragment_sampler_views = identity_set_fragment_sampler_views; +   id_pipe->base.set_vertex_sampler_views = identity_set_vertex_sampler_views;     id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers;     id_pipe->base.surface_copy = identity_surface_copy;     id_pipe->base.surface_fill = identity_surface_fill; @@ -775,6 +811,8 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)     id_pipe->base.flush = identity_flush;     id_pipe->base.is_texture_referenced = identity_is_texture_referenced;     id_pipe->base.is_buffer_referenced = identity_is_buffer_referenced; +   id_pipe->base.create_sampler_view = identity_create_sampler_view; +   id_pipe->base.sampler_view_destroy = identity_sampler_view_destroy;     id_pipe->pipe = pipe; diff --git a/src/gallium/drivers/identity/id_objects.h b/src/gallium/drivers/identity/id_objects.h index 77cc719079..b48df83b3e 100644 --- a/src/gallium/drivers/identity/id_objects.h +++ b/src/gallium/drivers/identity/id_objects.h @@ -52,6 +52,14 @@ struct identity_texture  }; +struct identity_sampler_view +{ +   struct pipe_sampler_view base; + +   struct pipe_sampler_view *sampler_view; +}; + +  struct identity_surface  {     struct pipe_surface base; @@ -94,6 +102,15 @@ identity_texture(struct pipe_texture *_texture)     return (struct identity_texture *)_texture;  } +static INLINE struct identity_sampler_view * +identity_sampler_view(struct pipe_sampler_view *_sampler_view) +{ +   if (!_sampler_view) { +      return NULL; +   } +   return (struct identity_sampler_view *)_sampler_view; +} +  static INLINE struct identity_surface *  identity_surface(struct pipe_surface *_surface)  { @@ -138,6 +155,15 @@ identity_texture_unwrap(struct pipe_texture *_texture)     return identity_texture(_texture)->texture;  } +static INLINE struct pipe_sampler_view * +identity_sampler_view_unwrap(struct pipe_sampler_view *_sampler_view) +{ +   if (!_sampler_view) { +      return NULL; +   } +   return identity_sampler_view(_sampler_view)->sampler_view; +} +  static INLINE struct pipe_surface *  identity_surface_unwrap(struct pipe_surface *_surface)  { diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index d94efec16a..bf7ed11809 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -68,11 +68,11 @@ static void llvmpipe_destroy( struct pipe_context *pipe )     pipe_surface_reference(&llvmpipe->framebuffer.zsbuf, NULL);     for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { -      pipe_texture_reference(&llvmpipe->texture[i], NULL); +      pipe_sampler_view_reference(&llvmpipe->fragment_sampler_views[i], NULL);     }     for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { -      pipe_texture_reference(&llvmpipe->vertex_textures[i], NULL); +      pipe_sampler_view_reference(&llvmpipe->vertex_sampler_views[i], NULL);     }     for (i = 0; i < Elements(llvmpipe->constants); i++) { @@ -156,8 +156,10 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )     llvmpipe->pipe.set_framebuffer_state = llvmpipe_set_framebuffer_state;     llvmpipe->pipe.set_polygon_stipple = llvmpipe_set_polygon_stipple;     llvmpipe->pipe.set_scissor_state = llvmpipe_set_scissor_state; -   llvmpipe->pipe.set_fragment_sampler_textures = llvmpipe_set_sampler_textures; -   llvmpipe->pipe.set_vertex_sampler_textures = llvmpipe_set_vertex_sampler_textures; +   llvmpipe->pipe.set_fragment_sampler_views = llvmpipe_set_fragment_sampler_views; +   llvmpipe->pipe.set_vertex_sampler_views = llvmpipe_set_vertex_sampler_views; +   llvmpipe->pipe.create_sampler_view = llvmpipe_create_sampler_view; +   llvmpipe->pipe.sampler_view_destroy = llvmpipe_sampler_view_destroy;     llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state;     llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers; diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 217ec59b68..f83e5ffacf 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -69,15 +69,15 @@ struct llvmpipe_context {     struct pipe_framebuffer_state framebuffer;     struct pipe_poly_stipple poly_stipple;     struct pipe_scissor_state scissor; -   struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; -   struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS]; +   struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; +   struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];     struct pipe_viewport_state viewport;     struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];     unsigned num_samplers; -   unsigned num_textures; +   unsigned num_fragment_sampler_views;     unsigned num_vertex_samplers; -   unsigned num_vertex_textures; +   unsigned num_vertex_sampler_views;     unsigned num_vertex_buffers;     unsigned dirty; /**< Mask of LP_NEW_x flags */ diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index fbe14924cb..059584f2a7 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -448,11 +448,12 @@ lp_setup_set_vertex_info( struct setup_context *setup,  /** - * Called during state validation when LP_NEW_TEXTURE is set. + * Called during state validation when LP_NEW_SAMPLER_VIEW is set.   */  void -lp_setup_set_sampler_textures( struct setup_context *setup, -                               unsigned num, struct pipe_texture **texture) +lp_setup_set_fragment_sampler_views(struct setup_context *setup, +                                    unsigned num, +                                    struct pipe_sampler_view **views)  {     unsigned i; @@ -461,9 +462,10 @@ lp_setup_set_sampler_textures( struct setup_context *setup,     assert(num <= PIPE_MAX_SAMPLERS);     for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { -      struct pipe_texture *tex = i < num ? texture[i] : NULL; +      struct pipe_sampler_view *view = i < num ? views[i] : NULL; -      if(tex) { +      if(view) { +         struct pipe_texture *tex = view->texture;           struct llvmpipe_texture *lp_tex = llvmpipe_texture(tex);           struct lp_jit_texture *jit_tex;           jit_tex = &setup->fs.current.jit_context.textures[i]; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 17c112b528..72116b8c6c 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -120,8 +120,9 @@ lp_setup_set_scissor( struct setup_context *setup,                        const struct pipe_scissor_state *scissor );  void -lp_setup_set_sampler_textures( struct setup_context *setup, -                               unsigned num, struct pipe_texture **texture); +lp_setup_set_fragment_sampler_views(struct setup_context *setup, +                                    unsigned num, +                                    struct pipe_sampler_view **views);  unsigned  lp_setup_is_texture_referenced( const struct setup_context *setup, diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index 6dbdc195bf..9b87cd202e 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -50,7 +50,7 @@  #define LP_NEW_DEPTH_STENCIL_ALPHA 0x100  #define LP_NEW_CONSTANTS     0x200  #define LP_NEW_SAMPLER       0x400 -#define LP_NEW_TEXTURE       0x800 +#define LP_NEW_SAMPLER_VIEW  0x800  #define LP_NEW_VERTEX        0x1000  #define LP_NEW_VS            0x2000  #define LP_NEW_QUERY         0x4000 @@ -192,14 +192,23 @@ void llvmpipe_set_polygon_stipple( struct pipe_context *,  void llvmpipe_set_scissor_state( struct pipe_context *,                                   const struct pipe_scissor_state * ); -void llvmpipe_set_sampler_textures( struct pipe_context *, -                                    unsigned num, -                                    struct pipe_texture ** ); +void llvmpipe_set_fragment_sampler_views(struct pipe_context *, +                                         unsigned num, +                                         struct pipe_sampler_view **);  void -llvmpipe_set_vertex_sampler_textures(struct pipe_context *, -                                     unsigned num_textures, -                                     struct pipe_texture **); +llvmpipe_set_vertex_sampler_views(struct pipe_context *, +                                  unsigned num, +                                  struct pipe_sampler_view **); + +struct pipe_sampler_view * +llvmpipe_create_sampler_view(struct pipe_context *pipe, +                            struct pipe_texture *texture, +                            const struct pipe_sampler_view *templ); + +void +llvmpipe_sampler_view_destroy(struct pipe_context *pipe, +                              struct pipe_sampler_view *view);  void llvmpipe_set_viewport_state( struct pipe_context *,                                    const struct pipe_viewport_state * ); diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index bdd906e1a7..9c91ce9238 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -150,7 +150,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )      */     if (llvmpipe->tex_timestamp != lp_screen->timestamp) {        llvmpipe->tex_timestamp = lp_screen->timestamp; -      llvmpipe->dirty |= LP_NEW_TEXTURE; +      llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW;     }     if (llvmpipe->dirty & (LP_NEW_RASTERIZER | @@ -164,7 +164,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )                            LP_NEW_DEPTH_STENCIL_ALPHA |                            LP_NEW_RASTERIZER |                            LP_NEW_SAMPLER | -                          LP_NEW_TEXTURE)) +                          LP_NEW_SAMPLER_VIEW))        llvmpipe_update_fs( llvmpipe );     if (llvmpipe->dirty & LP_NEW_BLEND_COLOR) @@ -182,10 +182,10 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )        lp_setup_set_fs_constants(llvmpipe->setup,                                   llvmpipe->constants[PIPE_SHADER_FRAGMENT]); -   if (llvmpipe->dirty & LP_NEW_TEXTURE) -      lp_setup_set_sampler_textures(llvmpipe->setup,  -                                    llvmpipe->num_textures, -                                    llvmpipe->texture); +   if (llvmpipe->dirty & LP_NEW_SAMPLER_VIEW) +      lp_setup_set_fragment_sampler_views(llvmpipe->setup,  +                                          llvmpipe->num_fragment_sampler_views, +                                          llvmpipe->fragment_sampler_views);     llvmpipe->dirty = 0;  } diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index c4b79dd415..3e681b561a 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -1091,7 +1091,7 @@ make_variant_key(struct llvmpipe_context *lp,     for(i = 0; i < PIPE_MAX_SAMPLERS; ++i)        if(shader->info.file_mask[TGSI_FILE_SAMPLER] & (1 << i)) -         lp_sampler_static_state(&key->sampler[i], lp->texture[i], lp->sampler[i]); +         lp_sampler_static_state(&key->sampler[i], lp->fragment_sampler_views[i]->texture, lp->sampler[i]);  } diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c index b30a075776..2df86a0814 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c +++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c @@ -105,8 +105,9 @@ llvmpipe_bind_vertex_sampler_states(struct pipe_context *pipe,  void -llvmpipe_set_sampler_textures(struct pipe_context *pipe, -                              unsigned num, struct pipe_texture **texture) +llvmpipe_set_fragment_sampler_views(struct pipe_context *pipe, +                                    unsigned num, +                                    struct pipe_sampler_view **views)  {     struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);     uint i; @@ -114,51 +115,77 @@ llvmpipe_set_sampler_textures(struct pipe_context *pipe,     assert(num <= PIPE_MAX_SAMPLERS);     /* Check for no-op */ -   if (num == llvmpipe->num_textures && -       !memcmp(llvmpipe->texture, texture, num * sizeof(struct pipe_texture *))) +   if (num == llvmpipe->num_fragment_sampler_views && +       !memcmp(llvmpipe->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *)))        return;     draw_flush(llvmpipe->draw);     for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { -      struct pipe_texture *tex = i < num ? texture[i] : NULL; +      struct pipe_sampler_view *view = i < num ? views[i] : NULL; -      pipe_texture_reference(&llvmpipe->texture[i], tex); +      pipe_sampler_view_reference(&llvmpipe->fragment_sampler_views[i], view);     } -   llvmpipe->num_textures = num; +   llvmpipe->num_fragment_sampler_views = num; -   llvmpipe->dirty |= LP_NEW_TEXTURE; +   llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW;  }  void -llvmpipe_set_vertex_sampler_textures(struct pipe_context *pipe, -                                     unsigned num_textures, -                                     struct pipe_texture **textures) +llvmpipe_set_vertex_sampler_views(struct pipe_context *pipe, +                                  unsigned num, +                                  struct pipe_sampler_view **views)  {     struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);     uint i; -   assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS); +   assert(num <= PIPE_MAX_VERTEX_SAMPLERS);     /* Check for no-op */ -   if (num_textures == llvmpipe->num_vertex_textures && -       !memcmp(llvmpipe->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) { +   if (num == llvmpipe->num_vertex_sampler_views && +       !memcmp(llvmpipe->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) {        return;     }     draw_flush(llvmpipe->draw);     for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { -      struct pipe_texture *tex = i < num_textures ? textures[i] : NULL; +      struct pipe_sampler_view *view = i < num ? views[i] : NULL; -      pipe_texture_reference(&llvmpipe->vertex_textures[i], tex); +      pipe_sampler_view_reference(&llvmpipe->vertex_sampler_views[i], view);     } -   llvmpipe->num_vertex_textures = num_textures; +   llvmpipe->num_vertex_sampler_views = num; -   llvmpipe->dirty |= LP_NEW_TEXTURE; +   llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW; +} + + +struct pipe_sampler_view * +llvmpipe_create_sampler_view(struct pipe_context *pipe, +                            struct pipe_texture *texture, +                            const struct pipe_sampler_view *templ) +{ +   struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); + +   *view = *templ; +   view->reference.count = 1; +   view->texture = NULL; +   pipe_texture_reference(&view->texture, texture); +   view->context = pipe; + +   return view; +} + + +void +llvmpipe_sampler_view_destroy(struct pipe_context *pipe, +                              struct pipe_sampler_view *view) +{ +   pipe_texture_reference(&view->texture, NULL); +   FREE(view);  } diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index 1786460aec..34b5953ccf 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -142,6 +142,7 @@ struct nv30_context {  	unsigned idxbuf_format;  	struct nv30_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS];  	struct nv30_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; +	struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];  	unsigned nr_samplers;  	unsigned nr_textures;  	unsigned dirty_samplers; diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index 24b15a63ac..321575da0a 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -272,19 +272,22 @@ nv30_sampler_state_delete(struct pipe_context *pipe, void *hwcso)  }  static void -nv30_set_sampler_texture(struct pipe_context *pipe, unsigned nr, -			 struct pipe_texture **miptree) +nv30_set_fragment_sampler_views(struct pipe_context *pipe, +				unsigned nr, +				struct pipe_sampler_view **views)  {  	struct nv30_context *nv30 = nv30_context(pipe);  	unsigned unit;  	for (unit = 0; unit < nr; unit++) { +		pipe_sampler_view_reference(&nv30->fragment_sampler_views[unit], views[unit]);  		pipe_texture_reference((struct pipe_texture **) -				       &nv30->tex_miptree[unit], miptree[unit]); +				       &nv30->tex_miptree[unit], views[unit]->texture);  		nv30->dirty_samplers |= (1 << unit);  	}  	for (unit = nr; unit < nv30->nr_textures; unit++) { +		pipe_sampler_view_reference(&nv30->fragment_sampler_views[unit], NULL);  		pipe_texture_reference((struct pipe_texture **)  				       &nv30->tex_miptree[unit], NULL);  		nv30->dirty_samplers |= (1 << unit); @@ -294,6 +297,31 @@ nv30_set_sampler_texture(struct pipe_context *pipe, unsigned nr,  	nv30->dirty |= NV30_NEW_SAMPLER;  } +static struct pipe_sampler_view * +nv30_create_sampler_view(struct pipe_context *pipe, +			 struct pipe_texture *texture, +			 const struct pipe_sampler_view *templ) +{ +	struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); + +	*view = *templ; +	view->reference.count = 1; +	view->texture = NULL; +	pipe_texture_reference(&view->texture, texture); +	view->context = pipe; + +	return view; +} + + +static void +nv30_sampler_view_destroy(struct pipe_context *pipe, +			  struct pipe_sampler_view *view) +{ +	pipe_texture_reference(&view->texture, NULL); +	FREE(view); +} +  static void *  nv30_rasterizer_state_create(struct pipe_context *pipe,  			     const struct pipe_rasterizer_state *cso) @@ -711,7 +739,9 @@ nv30_init_state_functions(struct nv30_context *nv30)  	nv30->pipe.create_sampler_state = nv30_sampler_state_create;  	nv30->pipe.bind_fragment_sampler_states = nv30_sampler_state_bind;  	nv30->pipe.delete_sampler_state = nv30_sampler_state_delete; -	nv30->pipe.set_fragment_sampler_textures = nv30_set_sampler_texture; +	nv30->pipe.set_fragment_sampler_views = nv30_set_fragment_sampler_views; +	nv30->pipe.create_sampler_view = nv30_create_sampler_view; +	nv30->pipe.sampler_view_destroy = nv30_sampler_view_destroy;  	nv30->pipe.create_rasterizer_state = nv30_rasterizer_state_create;  	nv30->pipe.bind_rasterizer_state = nv30_rasterizer_state_bind; diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 2550ec654b..4d2ffd9772 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -158,6 +158,7 @@ struct nv40_context {  	unsigned idxbuf_format;  	struct nv40_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS];  	struct nv40_miptree *tex_miptree[PIPE_MAX_SAMPLERS]; +	struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];  	unsigned nr_samplers;  	unsigned nr_textures;  	unsigned dirty_samplers; diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index ee471e6ce4..120dc42f7b 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -282,19 +282,22 @@ nv40_sampler_state_delete(struct pipe_context *pipe, void *hwcso)  }  static void -nv40_set_sampler_texture(struct pipe_context *pipe, unsigned nr, -			 struct pipe_texture **miptree) +nv40_set_fragment_sampler_views(struct pipe_context *pipe, +				unsigned nr, +				struct pipe_sampler_view **views)  {  	struct nv40_context *nv40 = nv40_context(pipe);  	unsigned unit;  	for (unit = 0; unit < nr; unit++) { +		pipe_sampler_view_reference(&nv40->fragment_sampler_views[unit], views[unit]);  		pipe_texture_reference((struct pipe_texture **) -				       &nv40->tex_miptree[unit], miptree[unit]); +				       &nv40->tex_miptree[unit], views[unit]->texture);  		nv40->dirty_samplers |= (1 << unit);  	}  	for (unit = nr; unit < nv40->nr_textures; unit++) { +		pipe_sampler_view_reference(&nv40->fragment_sampler_views[unit], NULL);  		pipe_texture_reference((struct pipe_texture **)  				       &nv40->tex_miptree[unit], NULL);  		nv40->dirty_samplers |= (1 << unit); @@ -304,6 +307,31 @@ nv40_set_sampler_texture(struct pipe_context *pipe, unsigned nr,  	nv40->dirty |= NV40_NEW_SAMPLER;  } +static struct pipe_sampler_view * +nv40_create_sampler_view(struct pipe_context *pipe, +			 struct pipe_texture *texture, +			 const struct pipe_sampler_view *templ) +{ +	struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); + +	*view = *templ; +	view->reference.count = 1; +	view->texture = NULL; +	pipe_texture_reference(&view->texture, texture); +	view->context = pipe; + +	return view; +} + + +static void +nv40_sampler_view_destroy(struct pipe_context *pipe, +			  struct pipe_sampler_view *view) +{ +	pipe_texture_reference(&view->texture, NULL); +	FREE(view); +} +  static void *  nv40_rasterizer_state_create(struct pipe_context *pipe,  			     const struct pipe_rasterizer_state *cso) @@ -726,7 +754,9 @@ nv40_init_state_functions(struct nv40_context *nv40)  	nv40->pipe.create_sampler_state = nv40_sampler_state_create;  	nv40->pipe.bind_fragment_sampler_states = nv40_sampler_state_bind;  	nv40->pipe.delete_sampler_state = nv40_sampler_state_delete; -	nv40->pipe.set_fragment_sampler_textures = nv40_set_sampler_texture; +	nv40->pipe.set_fragment_sampler_views = nv40_set_fragment_sampler_views; +	nv40->pipe.create_sampler_view = nv40_create_sampler_view; +	nv40->pipe.sampler_view_destroy = nv40_sampler_view_destroy;  	nv40->pipe.create_rasterizer_state = nv40_rasterizer_state_create;  	nv40->pipe.bind_rasterizer_state = nv40_rasterizer_state_bind; diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 8793c2aac5..8a5f7cb251 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -72,12 +72,23 @@ struct nv50_sampler_stateobj {  	unsigned tsc[8];  }; +struct nv50_sampler_view { +	struct pipe_sampler_view pipe; +	uint32_t tic[8]; +}; +  struct nv50_vtxelt_stateobj {  	struct pipe_vertex_element pipe[16];  	unsigned num_elements;  	uint32_t hw[16];  }; +static INLINE struct nv50_sampler_view * +nv50_sampler_view(struct pipe_sampler_view *view) +{ +	return (struct nv50_sampler_view *)view; +} +  static INLINE unsigned  get_tile_height(uint32_t tile_mode)  { @@ -160,6 +171,8 @@ struct nv50_context {  	struct nv50_vtxelt_stateobj *vtxelt;  	struct nv50_sampler_stateobj *sampler[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];  	unsigned sampler_nr[PIPE_SHADER_TYPES]; +	struct pipe_sampler_view *sampler_views[3][PIPE_MAX_SAMPLERS]; +	unsigned sampler_view_nr[3];  	struct nv50_miptree *miptree[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];  	unsigned miptree_nr[PIPE_SHADER_TYPES]; @@ -242,6 +255,7 @@ extern void nv50_so_init_sifc(struct nv50_context *nv50,  			      unsigned offset, unsigned size);  /* nv50_tex.c */ +extern boolean nv50_tex_construct(struct nv50_sampler_view *view);  extern void nv50_tex_relocs(struct nv50_context *);  extern struct nouveau_stateobj *nv50_tex_validate(struct nv50_context *); diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 7e2e8aa336..8283524b63 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -443,7 +443,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)  	so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);  	so_data  (so, 0x00000131 | (NV50_CB_PFP << 12)); -	ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, PIPE_SHADER_TYPES*32*32, +	ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 3 * 32 * (8 * 4),  			     &screen->tic);  	if (ret) {  		nv50_screen_destroy(pscreen); @@ -455,9 +455,9 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)  		  NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);  	so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM |  		  NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0); -	so_data  (so, PIPE_SHADER_TYPES * 32 - 1); +	so_data  (so, 3 * 32 - 1); -	ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, PIPE_SHADER_TYPES*32*32, +	ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 3 * 32 * (8 * 4),  			     &screen->tsc);  	if (ret) {  		nv50_screen_destroy(pscreen); diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index b0e5552eff..c162808928 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -238,6 +238,9 @@ nv50_sampler_state_create(struct pipe_context *pipe,  	return (void *)sso;  } +/* type == 0 for VPs, 1 for GPs, 2 for FPs, which is how the + * relevant tesla methods are indexed (NV50TCL_BIND_TSC etc.) + */  static INLINE void  nv50_sampler_state_bind(struct pipe_context *pipe, unsigned type,  			unsigned nr, void **sampler) @@ -253,13 +256,13 @@ nv50_sampler_state_bind(struct pipe_context *pipe, unsigned type,  static void  nv50_vp_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **s)  { -	nv50_sampler_state_bind(pipe, PIPE_SHADER_VERTEX, nr, s); +	nv50_sampler_state_bind(pipe, 0, nr, s);  }  static void  nv50_fp_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **s)  { -	nv50_sampler_state_bind(pipe, PIPE_SHADER_FRAGMENT, nr, s); +	nv50_sampler_state_bind(pipe, 2, nr, s);  }  static void @@ -269,35 +272,69 @@ nv50_sampler_state_delete(struct pipe_context *pipe, void *hwcso)  }  static INLINE void -nv50_set_sampler_texture(struct pipe_context *pipe, unsigned type, -			 unsigned nr, struct pipe_texture **pt) +nv50_set_sampler_views(struct pipe_context *pipe, unsigned p, +		       unsigned nr, +		       struct pipe_sampler_view **views)  {  	struct nv50_context *nv50 = nv50_context(pipe);  	unsigned i;  	for (i = 0; i < nr; i++) -		pipe_texture_reference((void *)&nv50->miptree[type][i], pt[i]); -	for (i = nr; i < nv50->miptree_nr[type]; i++) -		pipe_texture_reference((void *)&nv50->miptree[type][i], NULL); +		pipe_sampler_view_reference(&nv50->sampler_views[p][i], +					    views[i]); + +	for (i = nr; i < nv50->sampler_view_nr[p]; i++) +		pipe_sampler_view_reference(&nv50->sampler_views[p][i], NULL); -	nv50->miptree_nr[type] = nr; +	nv50->sampler_view_nr[p] = nr;  	nv50->dirty |= NV50_NEW_TEXTURE;  }  static void -nv50_set_vp_sampler_textures(struct pipe_context *pipe, -			     unsigned nr, struct pipe_texture **pt) +nv50_set_vp_sampler_views(struct pipe_context *pipe, +			  unsigned nr, +			  struct pipe_sampler_view **views)  { -	nv50_set_sampler_texture(pipe, PIPE_SHADER_VERTEX, nr, pt); +	nv50_set_sampler_views(pipe, 0, nr, views);  }  static void -nv50_set_fp_sampler_textures(struct pipe_context *pipe, -			     unsigned nr, struct pipe_texture **pt) +nv50_set_fp_sampler_views(struct pipe_context *pipe, +			  unsigned nr, +			  struct pipe_sampler_view **views)  { -	nv50_set_sampler_texture(pipe, PIPE_SHADER_FRAGMENT, nr, pt); +	nv50_set_sampler_views(pipe, 2, nr, views);  } +static void +nv50_sampler_view_destroy(struct pipe_context *pipe, +			  struct pipe_sampler_view *view) +{ +	pipe_texture_reference(&view->texture, NULL); +	FREE(nv50_sampler_view(view)); +} + +static struct pipe_sampler_view * +nv50_create_sampler_view(struct pipe_context *pipe, +			 struct pipe_texture *texture, +			 const struct pipe_sampler_view *templ) +{ +	struct nv50_sampler_view *view = CALLOC_STRUCT(nv50_sampler_view); + +	view->pipe = *templ; +	view->pipe.reference.count = 1; +	view->pipe.texture = NULL; +	pipe_texture_reference(&view->pipe.texture, texture); +	view->pipe.context = pipe; + +	if (!nv50_tex_construct(view)) { +		nv50_sampler_view_destroy(pipe, &view->pipe); +		return NULL; +	} +	return &view->pipe; +} + +  static void *  nv50_rasterizer_state_create(struct pipe_context *pipe,  			     const struct pipe_rasterizer_state *cso) @@ -765,8 +802,10 @@ nv50_init_state_functions(struct nv50_context *nv50)  	nv50->pipe.delete_sampler_state = nv50_sampler_state_delete;  	nv50->pipe.bind_fragment_sampler_states = nv50_fp_sampler_state_bind;  	nv50->pipe.bind_vertex_sampler_states   = nv50_vp_sampler_state_bind; -	nv50->pipe.set_fragment_sampler_textures = nv50_set_fp_sampler_textures; -	nv50->pipe.set_vertex_sampler_textures   = nv50_set_vp_sampler_textures; +	nv50->pipe.set_fragment_sampler_views = nv50_set_fp_sampler_views; +	nv50->pipe.set_vertex_sampler_views   = nv50_set_vp_sampler_views; +	nv50->pipe.create_sampler_view = nv50_create_sampler_view; +	nv50->pipe.sampler_view_destroy = nv50_sampler_view_destroy;  	nv50->pipe.create_rasterizer_state = nv50_rasterizer_state_create;  	nv50->pipe.bind_rasterizer_state = nv50_rasterizer_state_bind; diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c index 4c48b12cd8..c5029bad2d 100644 --- a/src/gallium/drivers/nv50/nv50_tex.c +++ b/src/gallium/drivers/nv50/nv50_tex.c @@ -29,26 +29,16 @@  #include "util/u_format.h"  #define _MIXED(pf, t0, t1, t2, t3, cr, cg, cb, ca, f)		\ -{                                                       	\ -	PIPE_FORMAT_##pf,					\ +[PIPE_FORMAT_##pf] = (						\  	NV50TIC_0_0_MAPR_##cr | NV50TIC_0_0_TYPER_##t0 |	\  	NV50TIC_0_0_MAPG_##cg | NV50TIC_0_0_TYPEG_##t1 |	\  	NV50TIC_0_0_MAPB_##cb | NV50TIC_0_0_TYPEB_##t2 |	\  	NV50TIC_0_0_MAPA_##ca | NV50TIC_0_0_TYPEA_##t3 |	\ -	NV50TIC_0_0_FMT_##f					\ -} +	NV50TIC_0_0_FMT_##f)  #define _(pf, t, cr, cg, cb, ca, f) _MIXED(pf, t, t, t, t, cr, cg, cb, ca, f) -struct nv50_texture_format { -	enum pipe_format pf; -	uint32_t hw; -}; - -#define NV50_TEX_FORMAT_LIST_SIZE \ -	(sizeof(nv50_tex_format_list) / sizeof(struct nv50_texture_format)) - -static const struct nv50_texture_format nv50_tex_format_list[] = +static const uint32_t nv50_texture_formats[PIPE_FORMAT_COUNT] =  {  	_(B8G8R8A8_UNORM, UNORM, C2, C1, C0, C3,  8_8_8_8),  	_(B8G8R8A8_SRGB,  UNORM, C2, C1, C0, C3,  8_8_8_8), @@ -60,10 +50,12 @@ static const struct nv50_texture_format nv50_tex_format_list[] =  	_(B5G6R5_UNORM, UNORM, C2, C1, C0, ONE, 5_6_5),  	_(L8_UNORM, UNORM, C0, C0, C0, ONE, 8), +	_(L8_SRGB,  UNORM, C0, C0, C0, ONE, 8),  	_(A8_UNORM, UNORM, ZERO, ZERO, ZERO, C0, 8),  	_(I8_UNORM, UNORM, C0, C0, C0, C0, 8), -	_(L8A8_UNORM, UNORM, C0, C0, C0, C1, 8_8), +	_(A8L8_UNORM, UNORM, C0, C0, C0, C1, 8_8), +	_(A8L8_SRGB,  UNORM, C0, C0, C0, C1, 8_8),  	_(DXT1_RGB, UNORM, C0, C1, C2, ONE, DXT1),  	_(DXT1_RGBA, UNORM, C0, C1, C2, C3, DXT1), @@ -81,117 +73,144 @@ static const struct nv50_texture_format nv50_tex_format_list[] =  	_(R16G16_UNORM, UNORM, C0, C1, ZERO, ONE, 16_16),  	_MIXED(Z32_FLOAT, FLOAT, UINT, UINT, UINT, C0, C0, C0, ONE, 32_DEPTH) -  };  #undef _  #undef _MIXED -static int -nv50_tex_construct(struct nv50_context *nv50, struct nouveau_stateobj *so, -		   struct nv50_miptree *mt, int unit, unsigned p) +static INLINE uint32_t +nv50_tic_swizzle(uint32_t tc, unsigned swz) +{ +	switch (swz) { +	case PIPE_SWIZZLE_RED: +		return (tc & NV50TIC_0_0_MAPR_MASK) >> NV50TIC_0_0_MAPR_SHIFT; +	case PIPE_SWIZZLE_GREEN: +		return (tc & NV50TIC_0_0_MAPG_MASK) >> NV50TIC_0_0_MAPG_SHIFT; +	case PIPE_SWIZZLE_BLUE: +		return (tc & NV50TIC_0_0_MAPB_MASK) >> NV50TIC_0_0_MAPB_SHIFT; +	case PIPE_SWIZZLE_ALPHA: +		return (tc & NV50TIC_0_0_MAPA_MASK) >> NV50TIC_0_0_MAPA_SHIFT; +	case PIPE_SWIZZLE_ONE: +		return 7; +	case PIPE_SWIZZLE_ZERO: +	default: +		return 0; +	} +} + +boolean +nv50_tex_construct(struct nv50_sampler_view *view)  { -	unsigned i; -	uint32_t mode;  	const struct util_format_description *desc; +	struct nv50_miptree *mt = nv50_miptree(view->pipe.texture); +	uint32_t swz[4], *tic = view->tic; -	for (i = 0; i < NV50_TEX_FORMAT_LIST_SIZE; i++) -		if (nv50_tex_format_list[i].pf == mt->base.base.format) -			break; -	if (i == NV50_TEX_FORMAT_LIST_SIZE) -                return 1; +	tic[0] = nv50_texture_formats[mt->base.base.format]; -	if (nv50->sampler[p][unit]->normalized) -		mode = 0x50001000 | (1 << 31); -	else { -		mode = 0x50001000 | (7 << 14); -		assert(mt->base.base.target == PIPE_TEXTURE_2D); -	} +	swz[0] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_r); +	swz[1] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_g); +	swz[2] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_b); +	swz[3] = nv50_tic_swizzle(tic[0], view->pipe.swizzle_a); +	view->tic[0] = (tic[0] &  ~NV50TIC_0_0_SWIZZLE_MASK) | +		(swz[0] << NV50TIC_0_0_MAPR_SHIFT) | +		(swz[1] << NV50TIC_0_0_MAPG_SHIFT) | +		(swz[2] << NV50TIC_0_0_MAPB_SHIFT) | +		(swz[3] << NV50TIC_0_0_MAPA_SHIFT); -	mode |= ((mt->base.bo->tile_mode & 0x0f) << 22) | -		((mt->base.bo->tile_mode & 0xf0) << 21); +	tic[2] = 0x50001000; +	tic[2] |= ((mt->base.bo->tile_mode & 0x0f) << 22) | +		  ((mt->base.bo->tile_mode & 0xf0) << 21);  	desc = util_format_description(mt->base.base.format); -	assert(desc); -  	if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) -		mode |= 0x0400; +		tic[2] |= NV50TIC_0_2_COLORSPACE_SRGB;  	switch (mt->base.base.target) {  	case PIPE_TEXTURE_1D: +		tic[2] |= NV50TIC_0_2_TARGET_1D;  		break;  	case PIPE_TEXTURE_2D: -		mode |= (1 << 14); +		tic[2] |= NV50TIC_0_2_TARGET_2D;  		break;  	case PIPE_TEXTURE_3D: -		mode |= (2 << 14); +		tic[2] |= NV50TIC_0_2_TARGET_3D;  		break;  	case PIPE_TEXTURE_CUBE: -		mode |= (3 << 14); +		tic[2] |= NV50TIC_0_2_TARGET_CUBE;  		break;  	default: -		assert(!"unsupported texture target"); -		break; +		NOUVEAU_ERR("invalid texture target: %d\n", +			    mt->base.base.target); +		return FALSE;  	} -	so_data (so, nv50_tex_format_list[i].hw); -	so_reloc(so, mt->base.bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW | -		 NOUVEAU_BO_RD, 0, 0); -	so_data (so, mode); -	so_data (so, 0x00300000); -	so_data (so, mt->base.base.width0 | (1 << 31)); -	so_data (so, (mt->base.base.last_level << 28) | -		 (mt->base.base.depth0 << 16) | mt->base.base.height0); -	so_data (so, 0x03000000); -	so_data (so, mt->base.base.last_level << 4); +	tic[3] = 0x00300000; -	return 0; -} +	tic[4] = (1 << 31) | mt->base.base.width0; +	tic[5] = (mt->base.base.last_level << 28) | +		(mt->base.base.depth0 << 16) | mt->base.base.height0; + +	tic[6] = 0x03000000; -#ifndef NV50TCL_BIND_TIC -#define NV50TCL_BIND_TIC(n) (0x1448 + 8 * n) -#endif +	tic[7] = (view->pipe.num_levels - view->pipe.first_level - 1) << 4; +	tic[7] |= view->pipe.first_level; + +	return TRUE; +} -static boolean +static int  nv50_validate_textures(struct nv50_context *nv50, struct nouveau_stateobj *so,  		       unsigned p)  { -	static const unsigned p_remap[PIPE_SHADER_TYPES] = { 0, 2, 1 }; -  	struct nouveau_grobj *eng2d = nv50->screen->eng2d;  	struct nouveau_grobj *tesla = nv50->screen->tesla; -	unsigned unit, j, p_hw = p_remap[p]; +	unsigned unit, j; + +	const unsigned rll = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_LOW; +	const unsigned rlh = NOUVEAU_BO_VRAM | NOUVEAU_BO_RD | NOUVEAU_BO_HIGH +		| NOUVEAU_BO_OR;  	nv50_so_init_sifc(nv50, so, nv50->screen->tic, NOUVEAU_BO_VRAM, -			  p * (32 * 8 * 4), nv50->miptree_nr[p] * 8 * 4); +			  p * (32 * 8 * 4), nv50->sampler_view_nr[p] * 8 * 4); -	for (unit = 0; unit < nv50->miptree_nr[p]; ++unit) { -		struct nv50_miptree *mt = nv50->miptree[p][unit]; +	for (unit = 0; unit < nv50->sampler_view_nr[p]; ++unit) { +		struct nv50_sampler_view *view = +			nv50_sampler_view(nv50->sampler_views[p][unit]);  		so_method(so, eng2d, NV50_2D_SIFC_DATA | (2 << 29), 8); -		if (mt) { -			if (nv50_tex_construct(nv50, so, mt, unit, p)) -				return FALSE; +		if (view) { +			uint32_t tic2 = view->tic[2]; +			struct nv50_miptree *mt = +				nv50_miptree(view->pipe.texture); + +			if (nv50->sampler[p][unit]->normalized) +				tic2 |= NV50TIC_0_2_NORMALIZED_COORDS; + +			so_data  (so, view->tic[0]); +			so_reloc (so, mt->base.bo, 0, rll, 0, 0); +			so_reloc (so, mt->base.bo, 0, rlh, tic2, tic2); +			so_datap (so, &view->tic[3], 5); +  			/* Set TEX insn $t src binding $unit in program type p  			 * to TIC, TSC entry (32 * p + unit), mark valid (1).  			 */ -			so_method(so, tesla, NV50TCL_BIND_TIC(p_hw), 1); +			so_method(so, tesla, NV50TCL_BIND_TIC(p), 1);  			so_data  (so, ((32 * p + unit) << 9) | (unit << 1) | 1);  		} else {  			for (j = 0; j < 8; ++j)  				so_data(so, 0); -			so_method(so, tesla, NV50TCL_BIND_TIC(p_hw), 1); +			so_method(so, tesla, NV50TCL_BIND_TIC(p), 1);  			so_data  (so, (unit << 1) | 0);  		}  	} -	for (; unit < nv50->state.miptree_nr[p]; unit++) { +	for (; unit < nv50->state.sampler_view_nr[p]; unit++) {  		/* Make other bindings invalid. */ -		so_method(so, tesla, NV50TCL_BIND_TIC(p_hw), 1); +		so_method(so, tesla, NV50TCL_BIND_TIC(p), 1);  		so_data  (so, (unit << 1) | 0);  	} -	nv50->state.miptree_nr[p] = nv50->miptree_nr[p]; +	nv50->state.sampler_view_nr[p] = nv50->sampler_view_nr[p];  	return TRUE;  } @@ -229,21 +248,23 @@ nv50_tex_validate(struct nv50_context *nv50)  {  	struct nouveau_stateobj *so;  	struct nouveau_grobj *tesla = nv50->screen->tesla; -	unsigned p, start, push, nrlc; +	unsigned p, m = 0, d = 0, r = 0; -	for (nrlc = 0, start = 0, push = 0, p = 0; p < PIPE_SHADER_TYPES; ++p) { -		start += MAX2(nv50->miptree_nr[p], nv50->state.miptree_nr[p]); -		push += MAX2(nv50->miptree_nr[p], nv50->state.miptree_nr[p]); -		nrlc += nv50->miptree_nr[p]; +	for (p = 0; p < 3; ++p) { +		unsigned nr = MAX2(nv50->sampler_view_nr[p], +				   nv50->state.sampler_view_nr[p]); +		m += nr; +		d += nr; +		r += nv50->sampler_view_nr[p];  	} -	start = start * 2 + 4 * PIPE_SHADER_TYPES + 2; -	push = push * 9 + 19 * PIPE_SHADER_TYPES + 2; -	nrlc = nrlc * 2 + 2 * PIPE_SHADER_TYPES; +	m = m * 2 + 3 * 4 + 1; +	d = d * 9 + 3 * 19 + 1; +	r = r * 2 + 3 * 2; -	so = so_new(start, push, nrlc); +	so = so_new(m, d, r); -	if (nv50_validate_textures(nv50, so, PIPE_SHADER_VERTEX) == FALSE || -	    nv50_validate_textures(nv50, so, PIPE_SHADER_FRAGMENT) == FALSE) { +	if (nv50_validate_textures(nv50, so, 0) == FALSE || +	    nv50_validate_textures(nv50, so, 2) == FALSE) {  		so_ref(NULL, &so);  		NOUVEAU_ERR("failed tex validate\n"); diff --git a/src/gallium/drivers/nv50/nv50_texture.h b/src/gallium/drivers/nv50/nv50_texture.h index b870302019..3475d3e432 100644 --- a/src/gallium/drivers/nv50/nv50_texture.h +++ b/src/gallium/drivers/nv50/nv50_texture.h @@ -7,7 +7,9 @@   */  /* Texture image control block */ +#define NV50TIC_0_0_SWIZZLE_MASK                                  0x3ffc0000  #define NV50TIC_0_0_MAPA_MASK                                     0x38000000 +#define NV50TIC_0_0_MAPA_SHIFT                                            27  #define NV50TIC_0_0_MAPA_ZERO                                     0x00000000  #define NV50TIC_0_0_MAPA_C0                                       0x10000000  #define NV50TIC_0_0_MAPA_C1                                       0x18000000 @@ -15,6 +17,7 @@  #define NV50TIC_0_0_MAPA_C3                                       0x28000000  #define NV50TIC_0_0_MAPA_ONE                                      0x38000000  #define NV50TIC_0_0_MAPB_MASK                                     0x07000000 +#define NV50TIC_0_0_MAPB_SHIFT                                            24  #define NV50TIC_0_0_MAPB_ZERO                                     0x00000000  #define NV50TIC_0_0_MAPB_C0                                       0x02000000  #define NV50TIC_0_0_MAPB_C1                                       0x03000000 @@ -22,6 +25,7 @@  #define NV50TIC_0_0_MAPB_C3                                       0x05000000  #define NV50TIC_0_0_MAPB_ONE                                      0x07000000  #define NV50TIC_0_0_MAPG_MASK                                     0x00e00000 +#define NV50TIC_0_0_MAPG_SHIFT                                            21  #define NV50TIC_0_0_MAPG_ZERO                                     0x00000000  #define NV50TIC_0_0_MAPG_C0                                       0x00400000  #define NV50TIC_0_0_MAPG_C1                                       0x00600000 @@ -29,6 +33,7 @@  #define NV50TIC_0_0_MAPG_C3                                       0x00a00000  #define NV50TIC_0_0_MAPG_ONE                                      0x00e00000  #define NV50TIC_0_0_MAPR_MASK                                     0x001c0000 +#define NV50TIC_0_0_MAPR_SHIFT                                            18  #define NV50TIC_0_0_MAPR_ZERO                                     0x00000000  #define NV50TIC_0_0_MAPR_C0                                       0x00080000  #define NV50TIC_0_0_MAPR_C1                                       0x000c0000 @@ -89,22 +94,39 @@  #define NV50TIC_0_1_OFFSET_LOW_MASK                               0xffffffff  #define NV50TIC_0_1_OFFSET_LOW_SHIFT                                       0 -#define NV50TIC_0_2_UNKNOWN_MASK                                  0xffffffff +#define NV50TIC_0_2_COLORSPACE_SRGB                               0x00000400 +#define NV50TIC_0_2_TARGET_1D                                     0x00000000 +#define NV50TIC_0_2_TARGET_2D                                     0x00004000 +#define NV50TIC_0_2_TARGET_3D                                     0x00008000 +#define NV50TIC_0_2_TARGET_CUBE                                   0x0000c000 +#define NV50TIC_0_2_TARGET_1D_ARRAY                               0x00010000 +#define NV50TIC_0_2_TARGET_2D_ARRAY                               0x00014000 +#define NV50TIC_0_2_TARGET_BUFFER                                 0x00018000 +#define NV50TIC_0_2_TARGET_RECT                                   0x0001c000 +/* #define NV50TIC_0_0_TILE_MODE_LINEAR                           0x00040000 */ +#define NV50TIC_0_2_TILE_MODE_Y_MASK                              0x01c00000 +#define NV50TIC_0_2_TILE_MODE_Y_SHIFT                                     22 +#define NV50TIC_0_2_TILE_MODE_Z_MASK                              0x0e000000 +#define NV50TIC_0_2_TILE_MODE_Z_SHIFT                                     25 +#define NV50TIC_0_2_NORMALIZED_COORDS                             0x80000000  #define NV50TIC_0_3_UNKNOWN_MASK                                  0xffffffff  #define NV50TIC_0_4_WIDTH_MASK                                    0x0000ffff  #define NV50TIC_0_4_WIDTH_SHIFT                                            0 -#define NV50TIC_0_5_DEPTH_MASK                                    0xffff0000 +#define NV50TIC_0_5_LAST_LEVEL_MASK                               0xf0000000 +#define NV50TIC_0_5_LAST_LEVEL_SHIFT                                      28 +#define NV50TIC_0_5_DEPTH_MASK                                    0x0fff0000  #define NV50TIC_0_5_DEPTH_SHIFT                                           16  #define NV50TIC_0_5_HEIGHT_MASK                                   0x0000ffff  #define NV50TIC_0_5_HEIGHT_SHIFT                                           0 -  #define NV50TIC_0_6_UNKNOWN_MASK                                  0xffffffff -#define NV50TIC_0_7_OFFSET_HIGH_MASK                              0xffffffff -#define NV50TIC_0_7_OFFSET_HIGH_SHIFT                                      0 +#define NV50TIC_0_7_BASE_LEVEL_MASK                               0x0000000f +#define NV50TIC_0_7_BASE_LEVEL_SHIFT                                       0 +#define NV50TIC_0_7_MAX_LEVEL_MASK                                0x000000f0 +#define NV50TIC_0_7_MAX_LEVEL_SHIFT                                        4  /* Texture sampler control block */  #define NV50TSC_1_0_WRAPS_MASK                                   0x00000007 diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index b7ad6b2020..a60b12844d 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -113,9 +113,9 @@ static void r300_hw_copy(struct pipe_context* pipe,      util_blitter_save_fragment_sampler_states(          r300->blitter, state->sampler_count, (void**)state->sampler_states); -    util_blitter_save_fragment_sampler_textures( -        r300->blitter, state->texture_count, -        (struct pipe_texture**)state->textures); +    util_blitter_save_fragment_sampler_views( +        r300->blitter, r300->fragment_sampler_view_count, +        r300->fragment_sampler_views);      /* Do a copy */      util_blitter_copy(r300->blitter, diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 985e339112..3b70bcda82 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -342,8 +342,9 @@ struct r300_context {      struct r300_atom rs_block_state;      /* Scissor state. */      struct r300_atom scissor_state; -    /* Textures state. */ -    struct r300_atom textures_state; +    /* Sampler view states. */ +    struct pipe_sampler_view* fragment_sampler_views[8]; +    int fragment_sampler_view_count;      /* Vertex stream formatting state. */      struct r300_atom vertex_stream_state;      /* VAP (vertex shader) output mapping state. */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 55e9217fd3..fc8a8a2773 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -163,7 +163,7 @@ static const float * get_shader_constant(                  /* Factor for converting rectangle coords to                   * normalized coords. Should only show up on non-r500. */                  case RC_STATE_R300_TEXRECT_FACTOR: -                    tex = &texstate->textures[constant->u.State[1]]->tex; +                    tex = r300->fragment_sampler_views[constant->u.State[1]]->texture;                      vec[0] = 1.0 / tex->width0;                      vec[1] = 1.0 / tex->height0;                      break; @@ -1034,10 +1034,10 @@ validate:          }      }      /* ...textures... */ -    for (i = 0; i < texstate->count; i++) { -        tex = texstate->textures[i]; -        if (!tex || !texstate->sampler_states[i]) +    for (i = 0; i < r300->fragment_sampler_view_count; i++) { +        if (!r300->fragment_sampler_views[i])              continue; +        tex = (struct r300_texture *)r300->fragment_sampler_views[i]->texture;          if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,                      RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) {              r300->context.flush(&r300->context, 0, NULL); diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index bd4c2766cb..09bbf6c60e 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -923,13 +923,11 @@ static void r300_delete_sampler_state(struct pipe_context* pipe, void* state)      FREE(state);  } -static void r300_set_sampler_textures(struct pipe_context* pipe, -                                      unsigned count, -                                      struct pipe_texture** texture) +static void r300_set_fragment_sampler_views(struct pipe_context* pipe, +                                            unsigned count, +                                            struct pipe_sampler_view** views)  {      struct r300_context* r300 = r300_context(pipe); -    struct r300_textures_state* state = -        (struct r300_textures_state*)r300->textures_state.state;      unsigned i;      boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500;      boolean dirty_tex = FALSE; @@ -940,13 +938,17 @@ static void r300_set_sampler_textures(struct pipe_context* pipe,      }      for (i = 0; i < count; i++) { -        if (state->textures[i] != (struct r300_texture*)texture[i]) { -            pipe_texture_reference((struct pipe_texture**)&state->textures[i], -                                   texture[i]); +        if (r300->fragment_sampler_views[i] != views[i]) { +            struct r300_texture *texture; + +            pipe_sampler_view_reference(&r300->fragment_sampler_views[i], +                views[i]);              dirty_tex = TRUE; -            /* R300-specific - set the texrect factor in the fragment shader */ -            if (!is_r500 && state->textures[i]->is_npot) { +            texture = (struct r300_texture *)views[i]->texture; + +            /* R300-specific - set the texrect factor in a fragment shader */ +            if (!is_r500 && texture->is_npot) {                  /* XXX It would be nice to re-emit just 1 constant,                   * XXX not all of them */                  r300->dirty_state |= R300_NEW_FRAGMENT_SHADER_CONSTANTS; @@ -955,13 +957,13 @@ static void r300_set_sampler_textures(struct pipe_context* pipe,      }      for (i = count; i < 8; i++) { -        if (state->textures[i]) { -            pipe_texture_reference((struct pipe_texture**)&state->textures[i], +        if (r300->fragment_sampler_views[i]) { +            pipe_sampler_view_reference(&r300->fragment_sampler_views[i],                  NULL);          }      } -    state->texture_count = count; +    r300->fragment_sampler_view_count = count;      r300->textures_state.dirty = TRUE; @@ -970,6 +972,32 @@ static void r300_set_sampler_textures(struct pipe_context* pipe,      }  } +static struct pipe_sampler_view * +r300_create_sampler_view(struct pipe_context *pipe, +                         struct pipe_texture *texture, +                         const struct pipe_sampler_view *templ) +{ +   struct r300_context *r300 = r300_context(pipe); +   struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); + +   *view = *templ; +   view->reference.count = 1; +   view->texture = NULL; +   pipe_texture_reference(&view->texture, texture); +   view->context = pipe; + +   return view; +} + + +static void +r300_sampler_view_destroy(struct pipe_context *pipe, +                          struct pipe_sampler_view *view) +{ +   pipe_texture_reference(&view->texture, NULL); +   FREE(view); +} +  static void r300_set_scissor_state(struct pipe_context* pipe,                                     const struct pipe_scissor_state* state)  { @@ -1450,7 +1478,9 @@ void r300_init_state_functions(struct r300_context* r300)      r300->context.bind_vertex_sampler_states = r300_lacks_vertex_textures;      r300->context.delete_sampler_state = r300_delete_sampler_state; -    r300->context.set_fragment_sampler_textures = r300_set_sampler_textures; +    r300->context.set_fragment_sampler_views = r300_set_fragment_sampler_views; +    r300->context.create_sampler_view = r300_create_sampler_view; +    r300->context.sampler_view_destroy = r300_sampler_view_destroy;      r300->context.set_scissor_state = r300_set_scissor_state; diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 30494719f7..891a903e4f 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -103,12 +103,12 @@ softpipe_destroy( struct pipe_context *pipe )     for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {        sp_destroy_tex_tile_cache(softpipe->tex_cache[i]); -      pipe_texture_reference(&softpipe->texture[i], NULL); +      pipe_sampler_view_reference(&softpipe->sampler_views[i], NULL);     }     for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {        sp_destroy_tex_tile_cache(softpipe->vertex_tex_cache[i]); -      pipe_texture_reference(&softpipe->vertex_textures[i], NULL); +      pipe_sampler_view_reference(&softpipe->vertex_sampler_views[i], NULL);     }     for (i = 0; i < PIPE_SHADER_TYPES; i++) { @@ -256,8 +256,10 @@ softpipe_create_context( struct pipe_screen *screen,     softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;     softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;     softpipe->pipe.set_scissor_state = softpipe_set_scissor_state; -   softpipe->pipe.set_fragment_sampler_textures = softpipe_set_sampler_textures; -   softpipe->pipe.set_vertex_sampler_textures = softpipe_set_vertex_sampler_textures; +   softpipe->pipe.set_fragment_sampler_views = softpipe_set_sampler_views; +   softpipe->pipe.set_vertex_sampler_views = softpipe_set_vertex_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;     softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers; diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 9a8158e6a2..75e03c8ae6 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -70,15 +70,15 @@ struct softpipe_context {     struct pipe_framebuffer_state framebuffer;     struct pipe_poly_stipple poly_stipple;     struct pipe_scissor_state scissor; -   struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; -   struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS]; +   struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; +   struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];     struct pipe_viewport_state viewport;     struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];     unsigned num_samplers; -   unsigned num_textures; +   unsigned num_sampler_views;     unsigned num_vertex_samplers; -   unsigned num_vertex_textures; +   unsigned num_vertex_sampler_views;     unsigned num_vertex_buffers;     unsigned dirty; /**< Mask of SP_NEW_x flags */ diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index e8952bf4fb..38dea13c66 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -50,10 +50,10 @@ softpipe_flush( struct pipe_context *pipe,     draw_flush(softpipe->draw);     if (flags & PIPE_FLUSH_TEXTURE_CACHE) { -      for (i = 0; i < softpipe->num_textures; i++) { +      for (i = 0; i < softpipe->num_sampler_views; i++) {           sp_flush_tex_tile_cache(softpipe->tex_cache[i]);        } -      for (i = 0; i < softpipe->num_vertex_textures; i++) { +      for (i = 0; i < softpipe->num_vertex_sampler_views; i++) {           sp_flush_tex_tile_cache(softpipe->vertex_tex_cache[i]);        }     } diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 6b01c0f4d7..ade96b0fd4 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -177,14 +177,23 @@ void softpipe_set_polygon_stipple( struct pipe_context *,  void softpipe_set_scissor_state( struct pipe_context *,                                   const struct pipe_scissor_state * ); -void softpipe_set_sampler_textures( struct pipe_context *, -                                    unsigned num, -                                    struct pipe_texture ** ); +void softpipe_set_sampler_views( struct pipe_context *, +                                 unsigned num, +                                 struct pipe_sampler_view ** );  void -softpipe_set_vertex_sampler_textures(struct pipe_context *, -                                     unsigned num_textures, -                                     struct pipe_texture **); +softpipe_set_vertex_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_texture *texture, +                             const struct pipe_sampler_view *templ); + +void +softpipe_sampler_view_destroy(struct pipe_context *pipe, +                              struct pipe_sampler_view *view);  void softpipe_set_viewport_state( struct pipe_context *,                                    const struct pipe_viewport_state * ); diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c index ceb4e338f1..68ea13f8d5 100644 --- a/src/gallium/drivers/softpipe/sp_state_sampler.c +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c @@ -121,9 +121,36 @@ softpipe_bind_vertex_sampler_states(struct pipe_context *pipe,  } +struct pipe_sampler_view * +softpipe_create_sampler_view(struct pipe_context *pipe, +                             struct pipe_texture *texture, +                             const struct pipe_sampler_view *templ) +{ +   struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); + +   *view = *templ; +   view->reference.count = 1; +   view->texture = NULL; +   pipe_texture_reference(&view->texture, texture); +   view->context = pipe; + +   return view; +} + +  void -softpipe_set_sampler_textures(struct pipe_context *pipe, -                              unsigned num, struct pipe_texture **texture) +softpipe_sampler_view_destroy(struct pipe_context *pipe, +                              struct pipe_sampler_view *view) +{ +   pipe_texture_reference(&view->texture, NULL); +   FREE(view); +} + + +void +softpipe_set_sampler_views(struct pipe_context *pipe, +                           unsigned num, +                           struct pipe_sampler_view **views)  {     struct softpipe_context *softpipe = softpipe_context(pipe);     uint i; @@ -131,51 +158,51 @@ softpipe_set_sampler_textures(struct pipe_context *pipe,     assert(num <= PIPE_MAX_SAMPLERS);     /* Check for no-op */ -   if (num == softpipe->num_textures && -       !memcmp(softpipe->texture, texture, num * sizeof(struct pipe_texture *))) +   if (num == softpipe->num_sampler_views && +       !memcmp(softpipe->sampler_views, views, num * sizeof(struct pipe_sampler_view *)))        return;     draw_flush(softpipe->draw);     for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { -      struct pipe_texture *tex = i < num ? texture[i] : NULL; +      struct pipe_sampler_view *view = i < num ? views[i] : NULL; -      pipe_texture_reference(&softpipe->texture[i], tex); -      sp_tex_tile_cache_set_texture(softpipe->tex_cache[i], tex); +      pipe_sampler_view_reference(&softpipe->sampler_views[i], view); +      sp_tex_tile_cache_set_sampler_view(softpipe->tex_cache[i], view);     } -   softpipe->num_textures = num; +   softpipe->num_sampler_views = num;     softpipe->dirty |= SP_NEW_TEXTURE;  }  void -softpipe_set_vertex_sampler_textures(struct pipe_context *pipe, -                                     unsigned num_textures, -                                     struct pipe_texture **textures) +softpipe_set_vertex_sampler_views(struct pipe_context *pipe, +                                  unsigned num, +                                  struct pipe_sampler_view **views)  {     struct softpipe_context *softpipe = softpipe_context(pipe);     uint i; -   assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS); +   assert(num <= PIPE_MAX_VERTEX_SAMPLERS);     /* Check for no-op */ -   if (num_textures == softpipe->num_vertex_textures && -       !memcmp(softpipe->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) { +   if (num == softpipe->num_vertex_sampler_views && +       !memcmp(softpipe->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) {        return;     }     draw_flush(softpipe->draw);     for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { -      struct pipe_texture *tex = i < num_textures ? textures[i] : NULL; +      struct pipe_sampler_view *view = i < num ? views[i] : NULL; -      pipe_texture_reference(&softpipe->vertex_textures[i], tex); -      sp_tex_tile_cache_set_texture(softpipe->vertex_tex_cache[i], tex); +      pipe_sampler_view_reference(&softpipe->vertex_sampler_views[i], view); +      sp_tex_tile_cache_set_sampler_view(softpipe->vertex_tex_cache[i], view);     } -   softpipe->num_vertex_textures = num_textures; +   softpipe->num_vertex_sampler_views = num;     softpipe->dirty |= SP_NEW_TEXTURE;  } @@ -245,29 +272,41 @@ softpipe_reset_sampler_varients(struct softpipe_context *softpipe)      */     for (i = 0; i <= softpipe->vs->max_sampler; i++) {        if (softpipe->vertex_samplers[i]) { +         struct pipe_texture *texture = NULL; + +         if (softpipe->vertex_sampler_views[i]) { +            texture = softpipe->vertex_sampler_views[i]->texture; +         } +           softpipe->tgsi.vert_samplers_list[i] =               get_sampler_varient( i, -                                sp_sampler(softpipe->vertex_samplers[i]), -                                softpipe->vertex_textures[i], +                                 sp_sampler(softpipe->vertex_samplers[i]), +                                 texture,                                   TGSI_PROCESSOR_VERTEX );           sp_sampler_varient_bind_texture( softpipe->tgsi.vert_samplers_list[i],  -                                         softpipe->vertex_tex_cache[i], -                                         softpipe->vertex_textures[i] ); +                                          softpipe->vertex_tex_cache[i], +                                          texture );        }     }     for (i = 0; i <= softpipe->fs->info.file_max[TGSI_FILE_SAMPLER]; i++) {        if (softpipe->sampler[i]) { +         struct pipe_texture *texture = NULL; + +         if (softpipe->sampler_views[i]) { +            texture = softpipe->sampler_views[i]->texture; +         } +           softpipe->tgsi.frag_samplers_list[i] =              get_sampler_varient( i,                                   sp_sampler(softpipe->sampler[i]), -                                 softpipe->texture[i], +                                 texture,                                   TGSI_PROCESSOR_FRAGMENT );           sp_sampler_varient_bind_texture( softpipe->tgsi.frag_samplers_list[i],                                             softpipe->tex_cache[i], -                                          softpipe->texture[i] ); +                                          texture );        }     }  } diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c index a0b95c8884..b9635bee78 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c @@ -119,12 +119,13 @@ sp_tex_tile_cache_validate_texture(struct softpipe_tex_tile_cache *tc)  }  /** - * Specify the texture to cache. + * Specify the sampler view to cache.   */  void -sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc, -                          struct pipe_texture *texture) +sp_tex_tile_cache_set_sampler_view(struct softpipe_tex_tile_cache *tc, +                                   struct pipe_sampler_view *view)  { +   struct pipe_texture *texture = view ? view->texture : NULL;     uint i;     assert(!tc->transfer); @@ -144,6 +145,13 @@ sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc,           tc->tex_trans = NULL;        } +      if (view) { +         tc->swizzle_r = view->swizzle_r; +         tc->swizzle_g = view->swizzle_g; +         tc->swizzle_b = view->swizzle_b; +         tc->swizzle_a = view->swizzle_a; +      } +        /* mark as entries as invalid/empty */        /* XXX we should try to avoid this when the teximage hasn't changed */        for (i = 0; i < NUM_ENTRIES; i++) { @@ -257,11 +265,16 @@ sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,        }        /* get tile from the transfer (view into texture) */ -      pipe_get_tile_rgba(tc->tex_trans, -                         addr.bits.x * TILE_SIZE,  -                         addr.bits.y * TILE_SIZE, -                         TILE_SIZE, TILE_SIZE, -                         (float *) tile->data.color); +      pipe_get_tile_swizzle(tc->tex_trans, +                            addr.bits.x * TILE_SIZE,  +                            addr.bits.y * TILE_SIZE, +                            TILE_SIZE, +                            TILE_SIZE, +                            tc->swizzle_r, +                            tc->swizzle_g, +                            tc->swizzle_b, +                            tc->swizzle_a, +                            (float *) tile->data.color);        tile->addr = addr;     } diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h index ac6886a3df..c562f721be 100644 --- a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h +++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h @@ -83,6 +83,11 @@ struct softpipe_tex_tile_cache     void *tex_trans_map;     int tex_face, tex_level, tex_z; +   unsigned swizzle_r; +   unsigned swizzle_g; +   unsigned swizzle_b; +   unsigned swizzle_a; +     struct softpipe_tex_cached_tile *last_tile;  /**< most recently retrieved tile */  }; @@ -101,8 +106,8 @@ extern void  sp_tex_tile_cache_unmap_transfers(struct softpipe_tex_tile_cache *tc);  extern void -sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc, -                          struct pipe_texture *texture); +sp_tex_tile_cache_set_sampler_view(struct softpipe_tex_tile_cache *tc, +                                   struct pipe_sampler_view *view);  void  sp_tex_tile_cache_validate_texture(struct softpipe_tex_tile_cache *tc); diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h index 791d30edc0..1f66437dfe 100644 --- a/src/gallium/drivers/svga/svga_context.h +++ b/src/gallium/drivers/svga/svga_context.h @@ -185,7 +185,7 @@ struct svga_state     const struct svga_sampler_state *sampler[PIPE_MAX_SAMPLERS];     const struct svga_velems_state *velems; -   struct pipe_texture *texture[PIPE_MAX_SAMPLERS]; /* or texture ID's? */ +   struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; /* or texture ID's? */     struct svga_fragment_shader *fs;     struct svga_vertex_shader *vs; @@ -208,7 +208,7 @@ struct svga_state     struct pipe_viewport_state viewport;     unsigned num_samplers; -   unsigned num_textures; +   unsigned num_sampler_views;     unsigned num_vertex_buffers;     unsigned reduced_prim; diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c index 1a8ef296ca..ebd1b94997 100644 --- a/src/gallium/drivers/svga/svga_pipe_sampler.c +++ b/src/gallium/drivers/svga/svga_pipe_sampler.c @@ -176,9 +176,34 @@ static void svga_delete_sampler_state(struct pipe_context *pipe,  } -static void svga_set_sampler_textures(struct pipe_context *pipe, -                                      unsigned num, -                                      struct pipe_texture **texture) +static struct pipe_sampler_view * +svga_create_sampler_view(struct pipe_context *pipe, +                         struct pipe_texture *texture, +                         const struct pipe_sampler_view *templ) +{ +   struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); + +   *view = *templ; +   view->reference.count = 1; +   view->texture = NULL; +   pipe_texture_reference(&view->texture, texture); +   view->context = pipe; + +   return view; +} + + +static void +svga_sampler_view_destroy(struct pipe_context *pipe, +                          struct pipe_sampler_view *view) +{ +   pipe_texture_reference(&view->texture, NULL); +   FREE(view); +} + +static void svga_set_sampler_views(struct pipe_context *pipe, +                                   unsigned num, +                                   struct pipe_sampler_view **views)  {     struct svga_context *svga = svga_context(pipe);     unsigned flag_1d = 0; @@ -188,31 +213,31 @@ static void svga_set_sampler_textures(struct pipe_context *pipe,     assert(num <= PIPE_MAX_SAMPLERS);     /* Check for no-op */ -   if (num == svga->curr.num_textures && -       !memcmp(svga->curr.texture, texture, num * sizeof(struct pipe_texture *))) { +   if (num == svga->curr.num_sampler_views && +       !memcmp(svga->curr.sampler_views, views, num * sizeof(struct pipe_sampler_view *))) {        if (0) debug_printf("texture noop\n");        return;     }     for (i = 0; i < num; i++) { -      pipe_texture_reference(&svga->curr.texture[i], -                             texture[i]); +      pipe_sampler_view_reference(&svga->curr.sampler_views[i], +                                  views[i]); -      if (!texture[i]) +      if (!views[i])           continue; -      if (texture[i]->format == PIPE_FORMAT_B8G8R8A8_SRGB) +      if (views[i]->texture->format == PIPE_FORMAT_B8G8R8A8_SRGB)           flag_srgb |= 1 << i; -      if (texture[i]->target == PIPE_TEXTURE_1D) +      if (views[i]->texture->target == PIPE_TEXTURE_1D)           flag_1d |= 1 << i;     } -   for (i = num; i < svga->curr.num_textures; i++) -      pipe_texture_reference(&svga->curr.texture[i], -                             NULL); +   for (i = num; i < svga->curr.num_sampler_views; i++) +      pipe_sampler_view_reference(&svga->curr.sampler_views[i], +                                  NULL); -   svga->curr.num_textures = num; +   svga->curr.num_sampler_views = num;     svga->dirty |= SVGA_NEW_TEXTURE_BINDING;     if (flag_srgb != svga->curr.tex_flags.flag_srgb || @@ -231,7 +256,9 @@ void svga_init_sampler_functions( struct svga_context *svga )     svga->pipe.create_sampler_state = svga_create_sampler_state;     svga->pipe.bind_fragment_sampler_states = svga_bind_sampler_states;     svga->pipe.delete_sampler_state = svga_delete_sampler_state; -   svga->pipe.set_fragment_sampler_textures = svga_set_sampler_textures; +   svga->pipe.set_fragment_sampler_views = svga_set_sampler_views; +   svga->pipe.create_sampler_view = svga_create_sampler_view; +   svga->pipe.sampler_view_destroy = svga_sampler_view_destroy;  } diff --git a/src/gallium/drivers/svga/svga_state_constants.c b/src/gallium/drivers/svga/svga_state_constants.c index bb92f818ea..493f78a990 100644 --- a/src/gallium/drivers/svga/svga_state_constants.c +++ b/src/gallium/drivers/svga/svga_state_constants.c @@ -137,7 +137,7 @@ static int emit_fs_consts( struct svga_context *svga,        for (i = 0; i < key->num_textures; i++) {           if (key->tex[i].unnormalized) { -            struct pipe_texture *tex = svga->curr.texture[i]; +            struct pipe_texture *tex = svga->curr.sampler_views[i]->texture;              float data[4];              data[0] = 1.0 / (float)tex->width0; diff --git a/src/gallium/drivers/svga/svga_state_fs.c b/src/gallium/drivers/svga/svga_state_fs.c index 2973444d0a..1310fd9825 100644 --- a/src/gallium/drivers/svga/svga_state_fs.c +++ b/src/gallium/drivers/svga/svga_state_fs.c @@ -158,10 +158,11 @@ static int make_fs_key( const struct svga_context *svga,      *      * SVGA_NEW_TEXTURE_BINDING | SVGA_NEW_SAMPLER      */ -   for (i = 0; i < svga->curr.num_textures; i++) { -      if (svga->curr.texture[i]) { +   for (i = 0; i < svga->curr.num_sampler_views; i++) { +      if (svga->curr.sampler_views[i]) {           assert(svga->curr.sampler[i]); -         key->tex[i].texture_target = svga->curr.texture[i]->target; +         assert(svga->curr.sampler_views[i]->texture); +         key->tex[i].texture_target = svga->curr.sampler_views[i]->texture->target;           if (!svga->curr.sampler[i]->normalized_coords) {              key->tex[i].width_height_idx = idx++;              key->tex[i].unnormalized = TRUE; @@ -169,7 +170,7 @@ static int make_fs_key( const struct svga_context *svga,           }        }     } -   key->num_textures = svga->curr.num_textures; +   key->num_textures = svga->curr.num_sampler_views;     idx = 0;     for (i = 0; i < svga->curr.num_samplers; ++i) { diff --git a/src/gallium/drivers/svga/svga_state_tss.c b/src/gallium/drivers/svga/svga_state_tss.c index 17b4785978..c08ec7c2e8 100644 --- a/src/gallium/drivers/svga/svga_state_tss.c +++ b/src/gallium/drivers/svga/svga_state_tss.c @@ -37,14 +37,14 @@  void svga_cleanup_tss_binding(struct svga_context *svga)  {     int i; -   unsigned count = MAX2( svga->curr.num_textures, +   unsigned count = MAX2( svga->curr.num_sampler_views,                            svga->state.hw_draw.num_views );     for (i = 0; i < count; i++) {        struct svga_hw_view_state *view = &svga->state.hw_draw.views[i];        svga_sampler_view_reference(&view->v, NULL); -      pipe_texture_reference( &svga->curr.texture[i], NULL ); +      pipe_sampler_view_reference( &svga->curr.sampler_views[i], NULL );        pipe_texture_reference( &view->texture, NULL );        view->dirty = 1; @@ -57,7 +57,7 @@ update_tss_binding(struct svga_context *svga,                     unsigned dirty )  {     unsigned i; -   unsigned count = MAX2( svga->curr.num_textures, +   unsigned count = MAX2( svga->curr.num_sampler_views,                            svga->state.hw_draw.num_views );     unsigned min_lod;     unsigned max_lod; @@ -77,30 +77,32 @@ update_tss_binding(struct svga_context *svga,     for (i = 0; i < count; i++) {        const struct svga_sampler_state *s = svga->curr.sampler[i];        struct svga_hw_view_state *view = &svga->state.hw_draw.views[i]; +      struct pipe_texture *texture = NULL;        /* get min max lod */ -      if (svga->curr.texture[i]) { +      if (svga->curr.sampler_views[i]) {           min_lod = MAX2(s->view_min_lod, 0); -         max_lod = MIN2(s->view_max_lod, svga->curr.texture[i]->last_level); +         max_lod = MIN2(s->view_max_lod, svga->curr.sampler_views[i]->texture->last_level); +         texture = svga->curr.sampler_views[i]->texture;        } else {           min_lod = 0;           max_lod = 0;        } -      if (view->texture != svga->curr.texture[i] || +      if (view->texture != texture ||            view->min_lod != min_lod ||            view->max_lod != max_lod) {           svga_sampler_view_reference(&view->v, NULL); -         pipe_texture_reference( &view->texture, svga->curr.texture[i] ); +         pipe_texture_reference( &view->texture, texture );           view->dirty = TRUE;           view->min_lod = min_lod;           view->max_lod = max_lod; -         if (svga->curr.texture[i]) +         if (texture)              view->v = svga_get_tex_sampler_view(&svga->pipe,  -                                                svga->curr.texture[i],  +                                                texture,                                                   min_lod,                                                  max_lod);        } @@ -115,7 +117,7 @@ update_tss_binding(struct svga_context *svga,        }     } -   svga->state.hw_draw.num_views = svga->curr.num_textures; +   svga->state.hw_draw.num_views = svga->curr.num_sampler_views;     if (queue.bind_count) {        SVGA3dTextureState *ts; diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 133521f45e..f9555fb922 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -25,6 +25,7 @@   *   **************************************************************************/ +#include "util/u_inlines.h"  #include "util/u_memory.h"  #include "util/u_simple_list.h" @@ -112,7 +113,7 @@ trace_context_draw_block(struct trace_context *tr_ctx, int flag)                     (void *) tr_ctx->draw_rule.fs, (void *) tr_ctx->curr.fs,                     (void *) tr_ctx->draw_rule.vs, (void *) tr_ctx->curr.vs,                     (void *) tr_ctx->draw_rule.surf, 0, -                   (void *) tr_ctx->draw_rule.tex, 0); +                   (void *) tr_ctx->draw_rule.sampler_view, 0);        if (tr_ctx->draw_rule.fs &&            tr_ctx->draw_rule.fs == tr_ctx->curr.fs)           block = TRUE; @@ -126,12 +127,12 @@ trace_context_draw_block(struct trace_context *tr_ctx, int flag)           for (k = 0; k < tr_ctx->curr.nr_cbufs; k++)              if (tr_ctx->draw_rule.surf == tr_ctx->curr.cbufs[k])                 block = TRUE; -      if (tr_ctx->draw_rule.tex) { -         for (k = 0; k < tr_ctx->curr.num_texs; k++) -            if (tr_ctx->draw_rule.tex == tr_ctx->curr.tex[k]) +      if (tr_ctx->draw_rule.sampler_view) { +         for (k = 0; k < tr_ctx->curr.num_sampler_views; k++) +            if (tr_ctx->draw_rule.sampler_view == tr_ctx->curr.sampler_views[k])                 block = TRUE; -         for (k = 0; k < tr_ctx->curr.num_vert_texs; k++) { -            if (tr_ctx->draw_rule.tex == tr_ctx->curr.vert_tex[k]) { +         for (k = 0; k < tr_ctx->curr.num_vert_sampler_views; k++) { +            if (tr_ctx->draw_rule.sampler_view == tr_ctx->curr.vert_sampler_views[k]) {                 block = TRUE;              }           } @@ -1013,63 +1014,119 @@ trace_context_set_viewport_state(struct pipe_context *_pipe,  } +static struct pipe_sampler_view * +trace_create_sampler_view(struct pipe_context *_pipe, +                          struct pipe_texture *_texture, +                          const struct pipe_sampler_view *templ) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct trace_texture *tr_tex = trace_texture(_texture); +   struct pipe_context *pipe = tr_ctx->pipe; +   struct pipe_texture *texture = tr_tex->texture; +   struct trace_sampler_view *result = CALLOC_STRUCT(trace_sampler_view); + +   trace_dump_call_begin("pipe_context", "create_sampler_view"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, texture); +   trace_dump_arg(ptr, templ); + +   result->sampler_view = pipe->create_sampler_view(pipe, texture, templ); + +   result->base = *templ; +   result->base.reference.count = 1; +   result->base.texture = NULL; +   pipe_texture_reference(&result->base.texture, _texture); +   result->base.context = _pipe; + +   trace_dump_ret(ptr, result); + +   trace_dump_call_end(); + +   return &result->base; +} + + +static void +trace_sampler_view_destroy(struct pipe_context *_pipe, +                           struct pipe_sampler_view *_view) +{ +   struct trace_context *tr_ctx = trace_context(_pipe); +   struct trace_sampler_view *tr_view = trace_sampler_view(_view); +   struct pipe_context *pipe = tr_ctx->pipe; +   struct pipe_sampler_view *view = tr_view->sampler_view; + +   trace_dump_call_begin("pipe_context", "sampler_view_destroy"); + +   trace_dump_arg(ptr, pipe); +   trace_dump_arg(ptr, view); + +   pipe->sampler_view_destroy(pipe, view); + +   trace_dump_call_end(); + +   pipe_texture_reference(&_view->texture, NULL); +   FREE(_view); +} + +  static INLINE void -trace_context_set_fragment_sampler_textures(struct pipe_context *_pipe, -                                            unsigned num_textures, -                                            struct pipe_texture **textures) +trace_context_set_fragment_sampler_views(struct pipe_context *_pipe, +                                         unsigned num, +                                         struct pipe_sampler_view **views)  {     struct trace_context *tr_ctx = trace_context(_pipe); -   struct trace_texture *tr_tex; +   struct trace_sampler_view *tr_view;     struct pipe_context *pipe = tr_ctx->pipe; -   struct pipe_texture *unwrapped_textures[PIPE_MAX_SAMPLERS]; +   struct pipe_sampler_view *unwrapped_views[PIPE_MAX_SAMPLERS];     unsigned i; -   tr_ctx->curr.num_texs = num_textures; -   for(i = 0; i < num_textures; ++i) { -      tr_tex = trace_texture(textures[i]); -      tr_ctx->curr.tex[i] = tr_tex; -      unwrapped_textures[i] = tr_tex ? tr_tex->texture : NULL; +   tr_ctx->curr.num_sampler_views = num; +   for(i = 0; i < num; ++i) { +      tr_view = trace_sampler_view(views[i]); +      tr_ctx->curr.sampler_views[i] = tr_view; +      unwrapped_views[i] = tr_view ? tr_view->sampler_view : NULL;     } -   textures = unwrapped_textures; +   views = unwrapped_views; -   trace_dump_call_begin("pipe_context", "set_fragment_sampler_textures"); +   trace_dump_call_begin("pipe_context", "set_fragment_sampler_views");     trace_dump_arg(ptr, pipe); -   trace_dump_arg(uint, num_textures); -   trace_dump_arg_array(ptr, textures, num_textures); +   trace_dump_arg(uint, num); +   trace_dump_arg_array(ptr, views, num); -   pipe->set_fragment_sampler_textures(pipe, num_textures, textures); +   pipe->set_fragment_sampler_views(pipe, num, views);     trace_dump_call_end();  }  static INLINE void -trace_context_set_vertex_sampler_textures(struct pipe_context *_pipe, -                                          unsigned num_textures, -                                          struct pipe_texture **textures) +trace_context_set_vertex_sampler_views(struct pipe_context *_pipe, +                                       unsigned num, +                                       struct pipe_sampler_view **views)  {     struct trace_context *tr_ctx = trace_context(_pipe); -   struct trace_texture *tr_tex; +   struct trace_sampler_view *tr_view;     struct pipe_context *pipe = tr_ctx->pipe; -   struct pipe_texture *unwrapped_textures[PIPE_MAX_VERTEX_SAMPLERS]; +   struct pipe_sampler_view *unwrapped_views[PIPE_MAX_VERTEX_SAMPLERS];     unsigned i; -   tr_ctx->curr.num_vert_texs = num_textures; -   for(i = 0; i < num_textures; ++i) { -      tr_tex = trace_texture(textures[i]); -      tr_ctx->curr.vert_tex[i] = tr_tex; -      unwrapped_textures[i] = tr_tex ? tr_tex->texture : NULL; +   tr_ctx->curr.num_vert_sampler_views = num; +   for(i = 0; i < num; ++i) { +      tr_view = trace_sampler_view(views[i]); +      tr_ctx->curr.vert_sampler_views[i] = tr_view; +      unwrapped_views[i] = tr_view ? tr_view->sampler_view : NULL;     } -   textures = unwrapped_textures; +   views = unwrapped_views; -   trace_dump_call_begin("pipe_context", "set_vertex_sampler_textures"); +   trace_dump_call_begin("pipe_context", "set_vertex_sampler_views");     trace_dump_arg(ptr, pipe); -   trace_dump_arg(uint, num_textures); -   trace_dump_arg_array(ptr, textures, num_textures); +   trace_dump_arg(uint, num); +   trace_dump_arg_array(ptr, views, num); -   pipe->set_vertex_sampler_textures(pipe, num_textures, textures); +   pipe->set_vertex_sampler_views(pipe, num, views);     trace_dump_call_end();  } @@ -1355,8 +1412,10 @@ trace_context_create(struct trace_screen *tr_scr,     tr_ctx->base.set_polygon_stipple = trace_context_set_polygon_stipple;     tr_ctx->base.set_scissor_state = trace_context_set_scissor_state;     tr_ctx->base.set_viewport_state = trace_context_set_viewport_state; -   tr_ctx->base.set_fragment_sampler_textures = trace_context_set_fragment_sampler_textures; -   tr_ctx->base.set_vertex_sampler_textures = trace_context_set_vertex_sampler_textures; +   tr_ctx->base.set_fragment_sampler_views = trace_context_set_fragment_sampler_views; +   tr_ctx->base.set_vertex_sampler_views = trace_context_set_vertex_sampler_views; +   tr_ctx->base.create_sampler_view = trace_create_sampler_view; +   tr_ctx->base.sampler_view_destroy = trace_sampler_view_destroy;     tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers;     if (pipe->surface_copy)        tr_ctx->base.surface_copy = trace_context_surface_copy; diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h index 1428423248..feec9b6bbf 100644 --- a/src/gallium/drivers/trace/tr_context.h +++ b/src/gallium/drivers/trace/tr_context.h @@ -53,11 +53,11 @@ struct trace_context        struct trace_shader *fs;        struct trace_shader *vs; -      struct trace_texture *tex[PIPE_MAX_SAMPLERS]; -      unsigned num_texs; +      struct trace_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; +      unsigned num_sampler_views; -      struct trace_texture *vert_tex[PIPE_MAX_VERTEX_SAMPLERS]; -      unsigned num_vert_texs; +      struct trace_sampler_view *vert_sampler_views[PIPE_MAX_VERTEX_SAMPLERS]; +      unsigned num_vert_sampler_views;        unsigned nr_cbufs;        struct trace_texture *cbufs[PIPE_MAX_COLOR_BUFS]; @@ -68,7 +68,7 @@ struct trace_context        struct trace_shader *fs;        struct trace_shader *vs; -      struct trace_texture *tex; +      struct trace_sampler_view *sampler_view;        struct trace_texture *surf;        int blocker; diff --git a/src/gallium/drivers/trace/tr_rbug.c b/src/gallium/drivers/trace/tr_rbug.c index a43adac694..07f9de253e 100644 --- a/src/gallium/drivers/trace/tr_rbug.c +++ b/src/gallium/drivers/trace/tr_rbug.c @@ -313,12 +313,12 @@ trace_rbug_context_info(struct trace_rbug *tr_rbug, struct rbug_header *header,     for (i = 0; i < tr_ctx->curr.nr_cbufs; i++)        cbufs[i] = VOID2U64(tr_ctx->curr.cbufs[i]); -   for (i = 0; i < tr_ctx->curr.num_texs; i++) -      texs[i] = VOID2U64(tr_ctx->curr.tex[i]); +   for (i = 0; i < tr_ctx->curr.num_sampler_views; i++) +      texs[i] = VOID2U64(tr_ctx->curr.sampler_views[i]);     rbug_send_context_info_reply(tr_rbug->con, serial,                                  VOID2U64(tr_ctx->curr.vs), VOID2U64(tr_ctx->curr.fs), -                                texs, tr_ctx->curr.num_texs, +                                texs, tr_ctx->curr.num_sampler_views,                                  cbufs, tr_ctx->curr.nr_cbufs,                                  VOID2U64(tr_ctx->curr.zsbuf),                                  tr_ctx->draw_blocker, tr_ctx->draw_blocked, NULL); @@ -444,7 +444,7 @@ trace_rbug_context_draw_rule(struct trace_rbug *tr_rbug, struct rbug_header *hea     pipe_mutex_lock(tr_ctx->draw_mutex);     tr_ctx->draw_rule.vs = U642VOID(rule->vertex);     tr_ctx->draw_rule.fs = U642VOID(rule->fragment); -   tr_ctx->draw_rule.tex = U642VOID(rule->texture); +   tr_ctx->draw_rule.sampler_view = U642VOID(rule->texture);     tr_ctx->draw_rule.surf = U642VOID(rule->surface);     tr_ctx->draw_rule.blocker = rule->block;     tr_ctx->draw_blocker |= RBUG_BLOCK_RULE; diff --git a/src/gallium/drivers/trace/tr_texture.h b/src/gallium/drivers/trace/tr_texture.h index 395e523e73..3a99dcdaec 100644 --- a/src/gallium/drivers/trace/tr_texture.h +++ b/src/gallium/drivers/trace/tr_texture.h @@ -55,6 +55,14 @@ struct trace_surface  }; +struct trace_sampler_view +{ +   struct pipe_sampler_view base; + +   struct pipe_sampler_view *sampler_view; +}; + +  struct trace_transfer  {     struct pipe_transfer base; @@ -87,6 +95,15 @@ trace_surface(struct pipe_surface *surface)  } +static INLINE struct trace_sampler_view * +trace_sampler_view(struct pipe_sampler_view *sampler_view) +{ +   if (!sampler_view) +      return NULL; +   return (struct trace_sampler_view *)sampler_view; +} + +  static INLINE struct trace_transfer *  trace_transfer(struct pipe_transfer *transfer)  { diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 376b01aa69..17fad1fa24 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -214,13 +214,13 @@ struct pipe_context {     void (*set_viewport_state)( struct pipe_context *,                                 const struct pipe_viewport_state * ); -   void (*set_fragment_sampler_textures)(struct pipe_context *, -                                         unsigned num_textures, -                                         struct pipe_texture **); +   void (*set_fragment_sampler_views)(struct pipe_context *, +                                      unsigned num_views, +                                      struct pipe_sampler_view **); -   void (*set_vertex_sampler_textures)(struct pipe_context *, -                                       unsigned num_textures, -                                       struct pipe_texture **); +   void (*set_vertex_sampler_views)(struct pipe_context *, +                                    unsigned num_views, +                                    struct pipe_sampler_view **);     void (*set_vertex_buffers)( struct pipe_context *,                                 unsigned num_buffers, @@ -306,6 +306,16 @@ struct pipe_context {      */     unsigned int (*is_buffer_referenced)(struct pipe_context *pipe,  					struct pipe_buffer *buf); + +   /** +    * Create a view on a texture to be used by a shader stage. +    */ +   struct pipe_sampler_view * (*create_sampler_view)(struct pipe_context *ctx, +                                                     struct pipe_texture *texture, +                                                     const struct pipe_sampler_view *templat); + +   void (*sampler_view_destroy)(struct pipe_context *ctx, +                                struct pipe_sampler_view *view);  }; diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 5c97dc87e8..c1e291b9da 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -370,6 +370,17 @@ enum pipe_transfer_usage {  /** + * Texture swizzles + */ +#define PIPE_SWIZZLE_RED   0 +#define PIPE_SWIZZLE_GREEN 1 +#define PIPE_SWIZZLE_BLUE  2 +#define PIPE_SWIZZLE_ALPHA 3 +#define PIPE_SWIZZLE_ZERO  4 +#define PIPE_SWIZZLE_ONE   5 + + +/**   * Implementation capabilities/limits which are queried through   * pipe_screen::get_param() and pipe_screen::get_paramf().   */ diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 3a97d888ce..3c7c0a5261 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -300,6 +300,24 @@ struct pipe_surface  /** + * A view into a texture that can be bound to a shader stage. + */ +struct pipe_sampler_view +{ +   struct pipe_reference reference; +   enum pipe_format format;      /**< typed PIPE_FORMAT_x */ +   struct pipe_texture *texture; /**< texture into which this is a view  */ +   struct pipe_context *context; /**< context this view belongs to */ +   unsigned first_level:8;       /**< first mipmap level */ +   unsigned num_levels:8;        /**< number of mipamp levels */ +   unsigned swizzle_r:3;         /**< PIPE_SWIZZLE_x for red component */ +   unsigned swizzle_g:3;         /**< PIPE_SWIZZLE_x for green component */ +   unsigned swizzle_b:3;         /**< PIPE_SWIZZLE_x for blue component */ +   unsigned swizzle_a:3;         /**< PIPE_SWIZZLE_x for alpha component */ +}; + + +/**   * Transfer object.  For data transfer to/from a texture.   */  struct pipe_transfer diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index ffb084e358..632d71ccbe 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -49,6 +49,7 @@  #include "util/u_format.h"  #include "util/u_dump.h"  #include "util/u_memory.h" +#include "util/u_sampler.h"  #include "cso_cache/cso_context.h"  #include "tgsi/tgsi_text.h"  #include "tgsi/tgsi_dump.h" diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index 5c44462e80..df700bc663 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -169,22 +169,39 @@ struct st_context {     void set_fragment_sampler_texture(unsigned index,                                       struct pipe_texture *texture) { +      struct pipe_sampler_view templ; +        if(!texture)           texture = $self->default_texture; -      pipe_texture_reference(&$self->fragment_sampler_textures[index], texture); -      $self->pipe->set_fragment_sampler_textures($self->pipe, -                                                 PIPE_MAX_SAMPLERS, -                                                 $self->fragment_sampler_textures); +      pipe_sampler_view_reference(&$self->fragment_sampler_views[index], NULL); +      u_sampler_view_default_template(&templ, +                                      texture, +                                      texture->format); +      $self->fragment_sampler_views[index] = $self->pipe->create_sampler_view($self->pipe, +                                                                              texture, +                                                                              &templ); +      $self->pipe->set_fragment_sampler_views($self->pipe, +                                              PIPE_MAX_SAMPLERS, +                                              $self->fragment_sampler_views);     }     void set_vertex_sampler_texture(unsigned index,                                     struct pipe_texture *texture) { +      struct pipe_sampler_view templ; +        if(!texture)           texture = $self->default_texture; -      pipe_texture_reference(&$self->vertex_sampler_textures[index], texture); -      $self->pipe->set_vertex_sampler_textures($self->pipe, -                                               PIPE_MAX_VERTEX_SAMPLERS, -                                               $self->vertex_sampler_textures); +      pipe_sampler_view_reference(&$self->vertex_sampler_views[index], NULL); +      u_sampler_view_default_template(&templ, +                                      texture, +                                      texture->format); +      $self->vertex_sampler_views[index] = $self->pipe->create_sampler_view($self->pipe, +                                                                            texture, +                                                                            &templ); +       +      $self->pipe->set_vertex_sampler_views($self->pipe, +                                            PIPE_MAX_VERTEX_SAMPLERS, +                                            $self->vertex_sampler_views);     }     void set_vertex_buffer(unsigned index, diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index 335e8e7f0d..0d87c705e7 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -33,6 +33,7 @@  #include "cso_cache/cso_context.h"  #include "util/u_math.h"  #include "util/u_memory.h" +#include "util/u_sampler.h"  #include "util/u_simple_shaders.h"  #include "trace/tr_public.h" @@ -124,9 +125,9 @@ st_context_destroy(struct st_context *st_ctx)           st_ctx->pipe->destroy(st_ctx->pipe);        for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) -         pipe_texture_reference(&st_ctx->fragment_sampler_textures[i], NULL); +         pipe_sampler_view_reference(&st_ctx->fragment_sampler_views[i], NULL);        for(i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; ++i) -         pipe_texture_reference(&st_ctx->vertex_sampler_textures[i], NULL); +         pipe_sampler_view_reference(&st_ctx->vertex_sampler_views[i], NULL);        pipe_texture_reference(&st_ctx->default_texture, NULL);        FREE(st_ctx); @@ -230,6 +231,8 @@ st_context_create(struct st_device *st_dev)        struct pipe_screen *screen = st_dev->screen;        struct pipe_texture templat;        struct pipe_transfer *transfer; +      struct pipe_sampler_view view_templ; +      struct pipe_sampler_view *view;        unsigned i;        memset( &templat, 0, sizeof( templat ) ); @@ -259,14 +262,27 @@ st_context_create(struct st_device *st_dev)              screen->tex_transfer_destroy(transfer);           }        } -    + +      u_sampler_view_default_template(&view_templ, +                                      st_ctx->default_texture, +                                      st_ctx->default_texture->format); +      view = st_ctx->pipe->create_sampler_view(st_ctx->pipe, +                                               st_ctx->default_texture, +                                               &view_templ); +        for (i = 0; i < PIPE_MAX_SAMPLERS; i++) -         pipe_texture_reference(&st_ctx->fragment_sampler_textures[i], st_ctx->default_texture); +         pipe_sampler_view_reference(&st_ctx->fragment_sampler_views[i], view);        for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) -         pipe_texture_reference(&st_ctx->vertex_sampler_textures[i], st_ctx->default_texture); -       -      cso_set_sampler_textures(st_ctx->cso, PIPE_MAX_SAMPLERS, st_ctx->fragment_sampler_textures); -      cso_set_vertex_sampler_textures(st_ctx->cso, PIPE_MAX_VERTEX_SAMPLERS, st_ctx->vertex_sampler_textures); +         pipe_sampler_view_reference(&st_ctx->vertex_sampler_views[i], view); + +      st_ctx->pipe->set_fragment_sampler_views(st_ctx->pipe, +                                               PIPE_MAX_SAMPLERS, +                                               st_ctx->fragment_sampler_views); +      st_ctx->pipe->set_vertex_sampler_views(st_ctx->pipe, +                                             PIPE_MAX_VERTEX_SAMPLERS, +                                             st_ctx->vertex_sampler_views); + +      pipe_sampler_view_reference(&view, NULL);     }     /* vertex shader */ diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h index 6ec7409b11..dcd0dc6e27 100644 --- a/src/gallium/state_trackers/python/st_device.h +++ b/src/gallium/state_trackers/python/st_device.h @@ -60,8 +60,8 @@ struct st_context     void *gs;     struct pipe_texture *default_texture; -   struct pipe_texture *fragment_sampler_textures[PIPE_MAX_SAMPLERS]; -   struct pipe_texture *vertex_sampler_textures[PIPE_MAX_VERTEX_SAMPLERS]; +   struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; +   struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS];     unsigned num_vertex_buffers;     struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index c609435a15..d542c996d0 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -589,10 +589,10 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,        struct pipe_texture *textures[2];        textures[0] = pt;        textures[1] = st->pixel_xfer.pixelmap_texture; -      pipe->set_fragment_sampler_textures(pipe, 2, textures); +      cso_set_sampler_textures(cso, 2, textures);     }     else { -      pipe->set_fragment_sampler_textures(pipe, 1, &pt); +      cso_set_sampler_textures(cso, 1, &pt);     }     /* Compute window coords (y=0=bottom) with pixel zoom. | 
