gallium: implement CSO save/restore functions for use by meta operations (blit, gen...
authorBrian <brian.paul@tungstengraphics.com>
Wed, 19 Mar 2008 17:12:48 +0000 (11:12 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Wed, 19 Mar 2008 17:14:18 +0000 (11:14 -0600)
Also, additional cso_set_*() functions for viewport, framebuffer, blend color,
etc. state.

14 files changed:
src/gallium/auxiliary/cso_cache/cso_context.c
src/gallium/auxiliary/cso_cache/cso_context.h
src/gallium/auxiliary/util/u_blit.c
src/gallium/auxiliary/util/u_blit.h
src/gallium/auxiliary/util/u_gen_mipmap.c
src/gallium/auxiliary/util/u_gen_mipmap.h
src/mesa/state_tracker/st_atom_blend.c
src/mesa/state_tracker/st_atom_framebuffer.c
src/mesa/state_tracker/st_atom_viewport.c
src/mesa/state_tracker/st_cb_blit.c
src/mesa/state_tracker/st_cb_clear.c
src/mesa/state_tracker/st_cb_drawpixels.c
src/mesa/state_tracker/st_context.h
src/mesa/state_tracker/st_gen_mipmap.c

index 294ac82281e64b9936e51ea98e463051e5e00f18..53d05ae6ce0fc23122d9fa862b63f56f61ca1611 100644 (file)
@@ -52,11 +52,27 @@ struct cso_context {
    void *samplers[PIPE_MAX_SAMPLERS];
    unsigned nr_samplers;
 
-   void *blend;
-   void *depth_stencil;
-   void *rasterizer;
-   void *fragment_shader;
-   void *vertex_shader;
+   void *samplers_saved[PIPE_MAX_SAMPLERS];
+   unsigned nr_samplers_saved;
+
+   struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
+   uint nr_textures;
+
+   struct pipe_texture *textures_saved[PIPE_MAX_SAMPLERS];
+   uint nr_textures_saved;
+
+   /** Current and saved state.
+    * The saved state is used as a 1-deep stack.
+    */
+   void *blend, *blend_saved;
+   void *depth_stencil, *depth_stencil_saved;
+   void *rasterizer, *rasterizer_saved;
+   void *fragment_shader, *fragment_shader_saved;
+   void *vertex_shader, *vertex_shader_saved;
+
+   struct pipe_framebuffer_state fb, fb_saved;
+   struct pipe_viewport_state vp, vp_saved;
+   struct pipe_blend_color blend_color;
 };
 
 
@@ -149,12 +165,23 @@ void cso_set_blend(struct cso_context *ctx,
    }
 }
 
-void cso_unset_blend(struct cso_context *ctx)
+void cso_save_blend(struct cso_context *ctx)
+{
+   assert(!ctx->blend_saved);
+   ctx->blend_saved = ctx->blend;
+}
+
+void cso_restore_blend(struct cso_context *ctx)
 {
-   ctx->blend = NULL;
+   if (ctx->blend != ctx->blend_saved) {
+      ctx->blend = ctx->blend_saved;
+      ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend_saved);
+   }
+   ctx->blend_saved = NULL;
 }
 
 
+
 void cso_single_sampler(struct cso_context *ctx,
                         unsigned idx,
                         const struct pipe_sampler_state *templ)
@@ -226,13 +253,48 @@ void cso_set_samplers( struct cso_context *ctx,
    cso_single_sampler_done( ctx );
 }
 
-void cso_unset_samplers( struct cso_context *ctx )
+void cso_save_samplers(struct cso_context *ctx)
+{
+   ctx->nr_samplers_saved = ctx->nr_samplers;
+   memcpy(ctx->samplers_saved, ctx->samplers, sizeof(ctx->samplers));
+}
+
+void cso_restore_samplers(struct cso_context *ctx)
+{
+   cso_set_samplers(ctx, ctx->nr_samplers_saved,
+                    (const struct pipe_sampler_state **) ctx->samplers_saved);
+}
+
+
+void cso_set_sampler_textures( struct cso_context *ctx,
+                               uint count,
+                               struct pipe_texture **textures )
 {
    uint i;
-   for (i = 0; i < ctx->nr_samplers; i++)
-      ctx->samplers[i] = NULL;
+
+   ctx->nr_textures = count;
+
+   for (i = 0; i < count; i++)
+      ctx->textures[i] = textures[i];
+   for ( ; i < PIPE_MAX_SAMPLERS; i++)
+      ctx->textures[i] = NULL;
+
+   ctx->pipe->set_sampler_textures(ctx->pipe, count, textures);
 }
 
+void cso_save_sampler_textures( struct cso_context *ctx )
+{
+   ctx->nr_textures_saved = ctx->nr_textures;
+   memcpy(ctx->textures_saved, ctx->textures, sizeof(ctx->textures));
+}
+
+void cso_restore_sampler_textures( struct cso_context *ctx )
+{
+   cso_set_sampler_textures(ctx, ctx->nr_textures_saved, ctx->textures_saved);
+   ctx->nr_textures_saved = 0;
+}
+
+
 
 
 void cso_set_depth_stencil_alpha(struct cso_context *ctx,
@@ -267,15 +329,25 @@ void cso_set_depth_stencil_alpha(struct cso_context *ctx,
    }
 }
 
-void cso_unset_depth_stencil_alpha(struct cso_context *ctx)
+void cso_save_depth_stencil_alpha(struct cso_context *ctx)
 {
-   ctx->depth_stencil = NULL;
+   assert(!ctx->depth_stencil_saved);
+   ctx->depth_stencil_saved = ctx->depth_stencil;
+}
+
+void cso_restore_depth_stencil_alpha(struct cso_context *ctx)
+{
+   if (ctx->depth_stencil != ctx->depth_stencil_saved) {
+      ctx->depth_stencil = ctx->depth_stencil_saved;
+      ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->depth_stencil_saved);
+   }
+   ctx->depth_stencil_saved = NULL;
 }
 
 
 
 void cso_set_rasterizer(struct cso_context *ctx,
-                              const struct pipe_rasterizer_state *templ)
+                        const struct pipe_rasterizer_state *templ)
 {
    unsigned hash_key = cso_construct_key((void*)templ,
                                          sizeof(struct pipe_rasterizer_state));
@@ -305,11 +377,20 @@ void cso_set_rasterizer(struct cso_context *ctx,
    }
 }
 
-void cso_unset_rasterizer(struct cso_context *ctx)
+void cso_save_rasterizer(struct cso_context *ctx)
 {
-   ctx->rasterizer = NULL;
+   assert(!ctx->rasterizer_saved);
+   ctx->rasterizer_saved = ctx->rasterizer;
 }
 
+void cso_restore_rasterizer(struct cso_context *ctx)
+{
+   if (ctx->rasterizer != ctx->rasterizer_saved) {
+      ctx->rasterizer = ctx->rasterizer_saved;
+      ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rasterizer_saved);
+   }
+   ctx->rasterizer_saved = NULL;
+}
 
 
 void cso_set_fragment_shader(struct cso_context *ctx,
@@ -343,11 +424,23 @@ void cso_set_fragment_shader(struct cso_context *ctx,
    }
 }
 
-void cso_unset_fragment_shader(struct cso_context *ctx)
+void cso_save_fragment_shader(struct cso_context *ctx)
 {
-   ctx->fragment_shader = NULL;
+   assert(!ctx->fragment_shader_saved);
+   ctx->fragment_shader_saved = ctx->fragment_shader;
 }
 
+void cso_restore_fragment_shader(struct cso_context *ctx)
+{
+   assert(ctx->fragment_shader_saved);
+   if (ctx->fragment_shader_saved != ctx->fragment_shader) {
+      ctx->pipe->bind_fs_state(ctx->pipe, ctx->fragment_shader_saved);
+      ctx->fragment_shader = ctx->fragment_shader_saved;
+   }
+   ctx->fragment_shader_saved = NULL;
+}
+
+
 
 void cso_set_vertex_shader(struct cso_context *ctx,
                            const struct pipe_shader_state *templ)
@@ -380,7 +473,78 @@ void cso_set_vertex_shader(struct cso_context *ctx,
    }
 }
 
-void cso_unset_vertex_shader(struct cso_context *ctx)
+void cso_save_vertex_shader(struct cso_context *ctx)
 {
-   ctx->vertex_shader = NULL;
+   assert(!ctx->vertex_shader_saved);
+   ctx->vertex_shader_saved = ctx->vertex_shader;
+}
+
+void cso_restore_vertex_shader(struct cso_context *ctx)
+{
+   assert(ctx->vertex_shader_saved);
+   if (ctx->vertex_shader_saved != ctx->vertex_shader) {
+      ctx->pipe->bind_fs_state(ctx->pipe, ctx->vertex_shader_saved);
+      ctx->vertex_shader = ctx->vertex_shader_saved;
+   }
+   ctx->vertex_shader_saved = NULL;
+}
+
+
+
+void cso_set_framebuffer(struct cso_context *ctx,
+                         const struct pipe_framebuffer_state *fb)
+{
+   if (memcmp(&ctx->fb, fb, sizeof(*fb))) {
+      ctx->fb = *fb;
+      ctx->pipe->set_framebuffer_state(ctx->pipe, fb);
+   }
+}
+
+void cso_save_framebuffer(struct cso_context *ctx)
+{
+   ctx->fb_saved = ctx->fb;
+}
+
+void cso_restore_framebuffer(struct cso_context *ctx)
+{
+   if (memcmp(&ctx->fb, &ctx->fb_saved, sizeof(ctx->fb))) {
+      ctx->fb = ctx->fb_saved;
+      ctx->pipe->set_framebuffer_state(ctx->pipe, &ctx->fb);
+   }
+}
+
+
+void cso_set_viewport(struct cso_context *ctx,
+                      const struct pipe_viewport_state *vp)
+{
+   if (memcmp(&ctx->vp, vp, sizeof(*vp))) {
+      ctx->vp = *vp;
+      ctx->pipe->set_viewport_state(ctx->pipe, vp);
+   }
+}
+
+void cso_save_viewport(struct cso_context *ctx)
+{
+   ctx->vp_saved = ctx->vp;
+}
+
+
+void cso_restore_viewport(struct cso_context *ctx)
+{
+   if (memcmp(&ctx->vp, &ctx->vp_saved, sizeof(ctx->vp))) {
+      ctx->vp = ctx->vp_saved;
+      ctx->pipe->set_viewport_state(ctx->pipe, &ctx->vp);
+   }
+}
+
+
+
+
+void cso_set_blend_color(struct cso_context *ctx,
+                         const struct pipe_blend_color *bc)
+{
+   if (memcmp(&ctx->blend_color, bc, sizeof(ctx->blend_color))) {
+      ctx->blend_color = *bc;
+      ctx->pipe->set_blend_color(ctx->pipe, bc);
+   }
 }
index 6aa619abf5637ed48b2b0f4a498a934f17ba426b..665e8d99110f18be5101ae816bc28fd30e31e650 100644 (file)
@@ -41,27 +41,36 @@ struct cso_context;
 
 struct cso_context *cso_create_context( struct pipe_context *pipe );
 
+void cso_destroy_context( struct cso_context *cso );
+
+
+
 void cso_set_blend( struct cso_context *cso,
                     const struct pipe_blend_state *blend );
+void cso_save_blend(struct cso_context *cso);
+void cso_restore_blend(struct cso_context *cso);
+
 
-void cso_unset_blend(struct cso_context *cso);
 
 void cso_set_depth_stencil_alpha( struct cso_context *cso,
                                   const struct pipe_depth_stencil_alpha_state *dsa );
+void cso_save_depth_stencil_alpha(struct cso_context *cso);
+void cso_restore_depth_stencil_alpha(struct cso_context *cso);
+
 
-void cso_unset_depth_stencil_alpha( struct cso_context *cso );
 
 void cso_set_rasterizer( struct cso_context *cso,
                          const struct pipe_rasterizer_state *rasterizer );
+void cso_save_rasterizer(struct cso_context *cso);
+void cso_restore_rasterizer(struct cso_context *cso);
+
 
-void cso_unset_rasterizer( struct cso_context *cso );
 
 void cso_set_samplers( struct cso_context *cso,
                        unsigned count,
                        const struct pipe_sampler_state **states );
-
-void cso_unset_samplers( struct cso_context *cso );
-
+void cso_save_samplers(struct cso_context *cso);
+void cso_restore_samplers(struct cso_context *cso);
 
 /* Alternate interface to support state trackers that like to modify
  * samplers one at a time:
@@ -73,6 +82,15 @@ void cso_single_sampler( struct cso_context *cso,
 void cso_single_sampler_done( struct cso_context *cso );
 
 
+
+void cso_set_sampler_textures( struct cso_context *cso,
+                               uint count,
+                               struct pipe_texture **textures );
+void cso_save_sampler_textures( struct cso_context *cso );
+void cso_restore_sampler_textures( struct cso_context *cso );
+
+
+
 /* These aren't really sensible -- most of the time the api provides
  * object semantics for shaders anyway, and the cases where it doesn't
  * (eg mesa's internall-generated texenv programs), it will be up to
@@ -80,15 +98,32 @@ void cso_single_sampler_done( struct cso_context *cso );
  */
 void cso_set_fragment_shader( struct cso_context *cso,
                               const struct pipe_shader_state *shader );
+void cso_save_fragment_shader(struct cso_context *cso);
+void cso_restore_fragment_shader(struct cso_context *cso);
+
 
-void cso_unset_fragment_shader( struct cso_context *cso );
 
 void cso_set_vertex_shader( struct cso_context *cso,
                             const struct pipe_shader_state *shader );
+void cso_save_vertex_shader(struct cso_context *cso);
+void cso_restore_vertex_shader(struct cso_context *cso);
 
-void cso_unset_vertex_shader( struct cso_context *cso );
 
-void cso_destroy_context( struct cso_context *cso );
+
+void cso_set_framebuffer(struct cso_context *cso,
+                         const struct pipe_framebuffer_state *fb);
+void cso_save_framebuffer(struct cso_context *cso);
+void cso_restore_framebuffer(struct cso_context *cso);
+
+
+void cso_set_viewport(struct cso_context *cso,
+                      const struct pipe_viewport_state *vp);
+void cso_save_viewport(struct cso_context *cso);
+void cso_restore_viewport(struct cso_context *cso);
+
+
+void cso_set_blend_color(struct cso_context *cso,
+                         const struct pipe_blend_color *bc);
 
 
 #ifdef __cplusplus
index 4b4ab8185f27591a27a459cd598a11baf46f5e2e..123304fe68e2b81cfcfde808759f3d9357be1da6 100644 (file)
 #include "util/u_blit.h"
 #include "util/u_simple_shaders.h"
 
+#include "cso_cache/cso_context.h"
+
 
 struct blit_state
 {
    struct pipe_context *pipe;
+   struct cso_context *cso;
 
-   void *blend;
-   void *depthstencil;
-   void *rasterizer;
-   void *samplers[2];  /* one for linear, one for nearest sampling */
+   struct pipe_blend_state blend;
+   struct pipe_depth_stencil_alpha_state depthstencil;
+   struct pipe_rasterizer_state rasterizer;
+   struct pipe_sampler_state sampler;
 
    /*struct pipe_viewport_state viewport;*/
    struct pipe_sampler_state *vs;
@@ -66,56 +69,44 @@ struct blit_state
  * Intended to be created once and re-used for many blit() calls.
  */
 struct blit_state *
-util_create_blit(struct pipe_context *pipe)
+util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
 {
-   struct pipe_blend_state blend;
-   struct pipe_depth_stencil_alpha_state depthstencil;
-   struct pipe_rasterizer_state rasterizer;
    struct blit_state *ctx;
-   struct pipe_sampler_state sampler;
 
    ctx = CALLOC_STRUCT(blit_state);
    if (!ctx)
       return NULL;
 
    ctx->pipe = pipe;
+   ctx->cso = cso;
 
-   /* we don't use blending, but need to set valid values */
-   memset(&blend, 0, sizeof(blend));
-   blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
-   blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
-   blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
-   blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
-   blend.colormask = PIPE_MASK_RGBA;
-   ctx->blend = pipe->create_blend_state(pipe, &blend);
+   /* disabled blending/masking */
+   memset(&ctx->blend, 0, sizeof(ctx->blend));
+   ctx->blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+   ctx->blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+   ctx->blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+   ctx->blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+   ctx->blend.colormask = PIPE_MASK_RGBA;
 
-   /* depth/stencil/alpha */
-   memset(&depthstencil, 0, sizeof(depthstencil));
-   ctx->depthstencil = pipe->create_depth_stencil_alpha_state(pipe, &depthstencil);
+   /* no-op depth/stencil/alpha */
+   memset(&ctx->depthstencil, 0, sizeof(ctx->depthstencil));
 
    /* rasterizer */
-   memset(&rasterizer, 0, sizeof(rasterizer));
-   rasterizer.front_winding = PIPE_WINDING_CW;
-   rasterizer.cull_mode = PIPE_WINDING_NONE;
-   rasterizer.bypass_clipping = 1;  /* bypasses viewport too */
-   /*rasterizer.bypass_vs = 1;*/
-   ctx->rasterizer = pipe->create_rasterizer_state(pipe, &rasterizer);
+   memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer));
+   ctx->rasterizer.front_winding = PIPE_WINDING_CW;
+   ctx->rasterizer.cull_mode = PIPE_WINDING_NONE;
+   ctx->rasterizer.bypass_clipping = 1;  /* bypasses viewport too */
+   /*ctx->rasterizer.bypass_vs = 1;*/
 
    /* samplers */
-   memset(&sampler, 0, sizeof(sampler));
-   sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
-   sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
-   sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
-   sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
-   sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
-   sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
-   sampler.normalized_coords = 1;
-   ctx->samplers[0] = pipe->create_sampler_state(pipe, &sampler);
-
-   sampler.min_img_filter = PIPE_TEX_MIPFILTER_LINEAR;
-   sampler.mag_img_filter = PIPE_TEX_MIPFILTER_LINEAR;
-   ctx->samplers[1] = pipe->create_sampler_state(pipe, &sampler);
-
+   memset(&ctx->sampler, 0, sizeof(ctx->sampler));
+   ctx->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+   ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+   ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+   ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+   ctx->sampler.min_img_filter = 0; /* set later */
+   ctx->sampler.mag_img_filter = 0; /* set later */
+   ctx->sampler.normalized_coords = 1;
 
 #if 0
    /* viewport */
@@ -153,12 +144,6 @@ util_destroy_blit(struct blit_state *ctx)
 {
    struct pipe_context *pipe = ctx->pipe;
 
-   pipe->delete_blend_state(pipe, ctx->blend);
-   pipe->delete_depth_stencil_alpha_state(pipe, ctx->depthstencil);
-   pipe->delete_rasterizer_state(pipe, ctx->rasterizer);
-   pipe->delete_sampler_state(pipe, ctx->samplers[0]);
-   pipe->delete_sampler_state(pipe, ctx->samplers[1]);
-
    pipe->delete_vs_state(pipe, ctx->vs);
    pipe->delete_fs_state(pipe, ctx->fs);
 
@@ -236,17 +221,24 @@ util_blit_pixels(struct blit_state *ctx,
                       src, srcLeft, srcTop, /* src */
                       srcW, srcH);     /* size */
 
-   /* drawing dest */
-   memset(&fb, 0, sizeof(fb));
-   fb.num_cbufs = 1;
-   fb.cbufs[0] = dst;
-   pipe->set_framebuffer_state(pipe, &fb);
+   /* save state (restored below) */
+   cso_save_blend(ctx->cso);
+   cso_save_depth_stencil_alpha(ctx->cso);
+   cso_save_rasterizer(ctx->cso);
+   cso_save_samplers(ctx->cso);
+   cso_save_sampler_textures(ctx->cso);
+   cso_save_framebuffer(ctx->cso);
+
+   /* set misc state we care about */
+   cso_set_blend(ctx->cso, &ctx->blend);
+   cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
+   cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
 
    /* sampler */
-   if (filter == PIPE_TEX_MIPFILTER_NEAREST)
-      pipe->bind_sampler_states(pipe, 1, &ctx->samplers[0]);
-   else
-      pipe->bind_sampler_states(pipe, 1, &ctx->samplers[1]);
+   ctx->sampler.min_img_filter = filter;
+   ctx->sampler.mag_img_filter = filter;
+   cso_single_sampler(ctx->cso, 0, &ctx->sampler);
+   cso_single_sampler_done(ctx->cso);
 
    /* texture */
    pipe->set_sampler_textures(pipe, 1, &tex);
@@ -255,22 +247,25 @@ util_blit_pixels(struct blit_state *ctx,
    pipe->bind_fs_state(pipe, ctx->fs);
    pipe->bind_vs_state(pipe, ctx->vs);
 
-   /* misc state */
-   pipe->bind_blend_state(pipe, ctx->blend);
-   pipe->bind_depth_stencil_alpha_state(pipe, ctx->depthstencil);
-   pipe->bind_rasterizer_state(pipe, ctx->rasterizer);
+   /* drawing dest */
+   memset(&fb, 0, sizeof(fb));
+   fb.num_cbufs = 1;
+   fb.cbufs[0] = dst;
+   cso_set_framebuffer(ctx->cso, &fb);
 
    /* draw quad */
    util_draw_texquad(pipe, dstX0, dstY0, dstX1, dstY1, z);
 
-   /* unbind */
-   pipe->set_sampler_textures(pipe, 0, NULL);
-   pipe->bind_sampler_states(pipe, 0, NULL);
+   /* restore state we changed */
+   cso_restore_blend(ctx->cso);
+   cso_restore_depth_stencil_alpha(ctx->cso);
+   cso_restore_rasterizer(ctx->cso);
+   cso_restore_samplers(ctx->cso);
+   cso_restore_sampler_textures(ctx->cso);
+   cso_restore_framebuffer(ctx->cso);
 
-   /* free stuff */
+   /* free the texture */
    pipe_surface_reference(&texSurf, NULL);
    screen->texture_release(screen, &tex);
-
-   /* Note: caller must restore pipe/gallium state at this time */
 }
 
index a349be99ad8249ae907626964d4f288b77e5ada9..61f1d9bb32a850e88fc9878152c86968b0b14034 100644 (file)
 #define U_BLIT_H
 
 
+
 struct pipe_context;
 struct pipe_surface;
+struct cso_context;
 
 
 struct blit_state;
 
-
 extern struct blit_state *
-util_create_blit(struct pipe_context *pipe);
+util_create_blit(struct pipe_context *pipe, struct cso_context *cso);
 
 
 extern void
index e18f8ab72ac244a283fb9b2daeaf8edc8023b527..27141c4d13f63d92e4c5cbb670a3daa9169e6860 100644 (file)
 #include "tgsi/util/tgsi_dump.h"
 #include "tgsi/util/tgsi_parse.h"
 
+#include "cso_cache/cso_context.h"
+
 
 struct gen_mipmap_state
 {
    struct pipe_context *pipe;
+   struct cso_context *cso;
 
-   void *blend;
-   void *depthstencil;
-   void *rasterizer;
+   struct pipe_blend_state blend;
+   struct pipe_depth_stencil_alpha_state depthstencil;
+   struct pipe_rasterizer_state rasterizer;
+   struct pipe_sampler_state sampler;
    /*struct pipe_viewport_state viewport;*/
    struct pipe_sampler_state *vs;
    struct pipe_sampler_state *fs;
@@ -675,11 +679,9 @@ fallback_gen_mipmap(struct gen_mipmap_state *ctx,
  * generate a mipmap.
  */
 struct gen_mipmap_state *
-util_create_gen_mipmap(struct pipe_context *pipe)
+util_create_gen_mipmap(struct pipe_context *pipe,
+                       struct cso_context *cso)
 {
-   struct pipe_blend_state blend;
-   struct pipe_depth_stencil_alpha_state depthstencil;
-   struct pipe_rasterizer_state rasterizer;
    struct gen_mipmap_state *ctx;
 
    ctx = CALLOC_STRUCT(gen_mipmap_state);
@@ -687,27 +689,36 @@ util_create_gen_mipmap(struct pipe_context *pipe)
       return NULL;
 
    ctx->pipe = pipe;
+   ctx->cso = cso;
 
-   /* we don't use blending, but need to set valid values */
-   memset(&blend, 0, sizeof(blend));
-   blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
-   blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
-   blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
-   blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
-   blend.colormask = PIPE_MASK_RGBA;
-   ctx->blend = pipe->create_blend_state(pipe, &blend);
+   /* disabled blending/masking */
+   memset(&ctx->blend, 0, sizeof(ctx->blend));
+   ctx->blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+   ctx->blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+   ctx->blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+   ctx->blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+   ctx->blend.colormask = PIPE_MASK_RGBA;
 
-   /* depth/stencil/alpha */
-   memset(&depthstencil, 0, sizeof(depthstencil));
-   ctx->depthstencil = pipe->create_depth_stencil_alpha_state(pipe, &depthstencil);
+   /* no-op depth/stencil/alpha */
+   memset(&ctx->depthstencil, 0, sizeof(ctx->depthstencil));
 
    /* rasterizer */
-   memset(&rasterizer, 0, sizeof(rasterizer));
-   rasterizer.front_winding = PIPE_WINDING_CW;
-   rasterizer.cull_mode = PIPE_WINDING_NONE;
-   rasterizer.bypass_clipping = 1;  /* bypasses viewport too */
-   //rasterizer.bypass_vs = 1;
-   ctx->rasterizer = pipe->create_rasterizer_state(pipe, &rasterizer);
+   memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer));
+   ctx->rasterizer.front_winding = PIPE_WINDING_CW;
+   ctx->rasterizer.cull_mode = PIPE_WINDING_NONE;
+   ctx->rasterizer.bypass_clipping = 1;  /* bypasses viewport too */
+   /*ctx->rasterizer.bypass_vs = 1;*/
+
+   /* sampler state */
+   memset(&ctx->sampler, 0, sizeof(ctx->sampler));
+   ctx->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+   ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+   ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+   ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
+   ctx->sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
+   ctx->sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
+   ctx->sampler.normalized_coords = 1;
+
 
 #if 0
    /* viewport */
@@ -745,9 +756,6 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx)
 {
    struct pipe_context *pipe = ctx->pipe;
 
-   pipe->delete_blend_state(pipe, ctx->blend);
-   pipe->delete_depth_stencil_alpha_state(pipe, ctx->depthstencil);
-   pipe->delete_rasterizer_state(pipe, ctx->rasterizer);
    pipe->delete_vs_state(pipe, ctx->vs);
    pipe->delete_fs_state(pipe, ctx->fs);
 
@@ -792,8 +800,6 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
    struct pipe_context *pipe = ctx->pipe;
    struct pipe_screen *screen = pipe->screen;
    struct pipe_framebuffer_state fb;
-   struct pipe_sampler_state sampler;
-   void *sampler_cso;
    uint dstLevel;
    uint zslice = 0;
 
@@ -803,30 +809,29 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
       return;
    }
 
-   /* init framebuffer state */
-   memset(&fb, 0, sizeof(fb));
-   fb.num_cbufs = 1;
-
-   /* sampler state */
-   memset(&sampler, 0, sizeof(sampler));
-   sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
-   sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
-   sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
-   sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
-   sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
-   sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
-   sampler.normalized_coords = 1;
+   /* save state (restored below) */
+   cso_save_blend(ctx->cso);
+   cso_save_depth_stencil_alpha(ctx->cso);
+   cso_save_rasterizer(ctx->cso);
+   cso_save_samplers(ctx->cso);
+   cso_save_sampler_textures(ctx->cso);
+   cso_save_framebuffer(ctx->cso);
 
    /* bind our state */
-   pipe->bind_blend_state(pipe, ctx->blend);
-   pipe->bind_depth_stencil_alpha_state(pipe, ctx->depthstencil);
-   pipe->bind_rasterizer_state(pipe, ctx->rasterizer);
+   cso_set_blend(ctx->cso, &ctx->blend);
+   cso_set_depth_stencil_alpha(ctx->cso, &ctx->depthstencil);
+   cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
+
    pipe->bind_vs_state(pipe, ctx->vs);
    pipe->bind_fs_state(pipe, ctx->fs);
 #if 0
    pipe->set_viewport_state(pipe, &ctx->viewport);
 #endif
 
+   /* init framebuffer state */
+   memset(&fb, 0, sizeof(fb));
+   fb.num_cbufs = 1;
+
    /*
     * XXX for small mipmap levels, it may be faster to use the software
     * fallback path...
@@ -838,7 +843,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
        * Setup framebuffer / dest surface
        */
       fb.cbufs[0] = screen->get_tex_surface(screen, pt, face, dstLevel, zslice);
-      pipe->set_framebuffer_state(pipe, &fb);
+      cso_set_framebuffer(ctx->cso, &fb);
 
       /*
        * Setup sampler state
@@ -847,11 +852,10 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
        * has trouble with min clamping so we also set the lod_bias to
        * try to work around that.
        */
-      sampler.min_lod = sampler.max_lod = (float) srcLevel;
-      sampler.lod_bias = (float) srcLevel;
-      sampler_cso = pipe->create_sampler_state(pipe, &sampler);
-      pipe->bind_sampler_states(pipe, 1, &sampler_cso);
-
+      ctx->sampler.min_lod = ctx->sampler.max_lod = (float) srcLevel;
+      ctx->sampler.lod_bias = (float) srcLevel;
+      cso_single_sampler(ctx->cso, 0, &ctx->sampler);
+      cso_single_sampler_done(ctx->cso);
 #if 0
       simple_viewport(pipe, pt->width[dstLevel], pt->height[dstLevel]);
 #endif
@@ -869,9 +873,13 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
       pipe->flush(pipe, PIPE_FLUSH_WAIT);
 
       /*pipe->texture_update(pipe, pt);  not really needed */
-
-      pipe->delete_sampler_state(pipe, sampler_cso);
    }
 
-   /* Note: caller must restore pipe/gallium state at this time */
+   /* restore state we changed */
+   cso_restore_blend(ctx->cso);
+   cso_restore_depth_stencil_alpha(ctx->cso);
+   cso_restore_rasterizer(ctx->cso);
+   cso_restore_samplers(ctx->cso);
+   cso_restore_sampler_textures(ctx->cso);
+   cso_restore_framebuffer(ctx->cso);
 }
index 80496140a24a845f437c4bb4f40b9d2d6cb193bb..eeabf3bf075f2af5cfab893c09e68eef4a6e3723 100644 (file)
 #include "pipe/p_state.h"
 
 
+struct pipe_context;
+struct pipe_texture;
+struct cso_context;
+
 struct gen_mipmap_state;
 
 
 extern struct gen_mipmap_state *
-util_create_gen_mipmap(struct pipe_context *pipe);
+util_create_gen_mipmap(struct pipe_context *pipe, struct cso_context *cso);
 
 
 extern void
index 6c13fc814158e4d14ad7a1b085130d245df9078c..2a0e92245c89b953db7ffb6d837ec9a40bc7ad50 100644 (file)
@@ -39,6 +39,7 @@
 #include "pipe/p_defines.h"
 #include "cso_cache/cso_context.h"
 
+#include "main/macros.h"
 
 /**
  * Convert GLenum blend tokens to pipe tokens.
@@ -213,13 +214,10 @@ update_blend( struct st_context *st )
 
    cso_set_blend(st->cso_context, blend);
 
-   if (memcmp(st->ctx->Color.BlendColor, &st->state.blend_color, 4 * sizeof(GLfloat)) != 0) {
-      /* state has changed */
-      st->state.blend_color.color[0] = st->ctx->Color.BlendColor[0];
-      st->state.blend_color.color[1] = st->ctx->Color.BlendColor[1];
-      st->state.blend_color.color[2] = st->ctx->Color.BlendColor[2];
-      st->state.blend_color.color[3] = st->ctx->Color.BlendColor[3];
-      st->pipe->set_blend_color(st->pipe, (struct pipe_blend_color *) st->ctx->Color.BlendColor);
+   {
+      struct pipe_blend_color bc;
+      COPY_4FV(bc.color, st->ctx->Color.BlendColor);
+      cso_set_blend_color(st->cso_context, &bc);
    }
 }
 
index 3e58d49f1fbde6e9bb0bbe2c832fda2c68d7aca3..c8fa0cbdfb6150d65d3fe0197b103317e56325a8 100644 (file)
@@ -35,6 +35,7 @@
 #include "st_atom.h"
 #include "st_cb_fbo.h"
 #include "pipe/p_context.h"
+#include "cso_cache/cso_context.h"
 
 
 /**
@@ -76,13 +77,7 @@ update_framebuffer_state( struct st_context *st )
       }
    }
 
-   /* XXX: The memcmp is insufficient for eliminating redundant state changes,
-    * but we should probably do more work here to that end.
-    */
-   if (1 /*memcmp(&framebuffer, &st->state.framebuffer, sizeof(framebuffer)) != 0*/) {
-      st->state.framebuffer = framebuffer;
-      st->pipe->set_framebuffer_state( st->pipe, &framebuffer );
-   }
+   cso_set_framebuffer(st->cso_context, &framebuffer);
 }
 
 
index 147aa3c51a76517e30319750da4c55e745af5c08..eb3f62cfbeae41ee1d68585574ec092443dcdb8a 100644 (file)
@@ -29,9 +29,9 @@
 #include "context.h"
 #include "colormac.h"
 #include "st_context.h"
-#include "pipe/p_context.h"
 #include "st_atom.h"
-
+#include "pipe/p_context.h"
+#include "cso_cache/cso_context.h"
 
 /**
  * Update the viewport transformation matrix.  Depends on:
@@ -65,22 +65,18 @@ update_viewport( struct st_context *st )
       GLfloat half_width = ctx->Viewport.Width / 2.0;
       GLfloat half_height = ctx->Viewport.Height / 2.0;
       GLfloat half_depth = (ctx->Viewport.Far - ctx->Viewport.Near) / 2.0;
-      struct pipe_viewport_state vp;
       
-      vp.scale[0] = half_width;
-      vp.scale[1] = half_height * yScale;
-      vp.scale[2] = half_depth;
-      vp.scale[3] = 1.0;
+      st->state.viewport.scale[0] = half_width;
+      st->state.viewport.scale[1] = half_height * yScale;
+      st->state.viewport.scale[2] = half_depth;
+      st->state.viewport.scale[3] = 1.0;
 
-      vp.translate[0] = half_width + x;
-      vp.translate[1] = (half_height + y) * yScale + yBias;
-      vp.translate[2] = half_depth + z;
-      vp.translate[3] = 0.0;
+      st->state.viewport.translate[0] = half_width + x;
+      st->state.viewport.translate[1] = (half_height + y) * yScale + yBias;
+      st->state.viewport.translate[2] = half_depth + z;
+      st->state.viewport.translate[3] = 0.0;
 
-      if (memcmp(&vp, &st->state.viewport, sizeof(vp)) != 0) {
-        st->state.viewport = vp;
-        st->pipe->set_viewport_state(st->pipe, &vp);
-      }
+      cso_set_viewport(st->cso_context, &st->state.viewport);
    }
 }
 
index dfa79c975c11e8e7f7c745c2ec88fdfcaa642815..64314a5078f3964c3d56568bb05187fce79c8dcc 100644 (file)
@@ -52,7 +52,7 @@
 void
 st_init_blit(struct st_context *st)
 {
-   st->blit = util_create_blit(st->pipe);
+   st->blit = util_create_blit(st->pipe, st->cso_context);
 }
 
 
@@ -98,22 +98,9 @@ st_BlitFramebuffer(GLcontext *ctx,
 
    }
 
-#if 0
-   /* XXX is this sufficient? */
-   st_invalidate_state(ctx, _NEW_COLOR | _NEW_TEXTURE);
-#else
-   /* need to "unset" cso state because we went behind the back of the cso
-    * tracker.  Without unset, the _set_ calls would be no-ops.
-    */
-   cso_unset_blend(st->cso_context);
-   cso_unset_depth_stencil_alpha(st->cso_context);
-   cso_unset_rasterizer(st->cso_context);
-   cso_set_blend(st->cso_context, &st->state.blend);
-   cso_set_depth_stencil_alpha(st->cso_context, &st->state.depth_stencil);
-   cso_set_rasterizer(st->cso_context, &st->state.rasterizer);
+   /* shaders don't go through CSO yet */
    pipe->bind_fs_state(pipe, st->fp->driver_shader);
    pipe->bind_vs_state(pipe, st->vp->driver_shader);
-#endif
 }
 
 
index 693cddedf7580e9d2b9e9f118925702b9cb29ff1..c23938dc6814b6f85e69a7d1c800cd16dc1fb07f 100644 (file)
@@ -247,10 +247,19 @@ clear_with_quad(GLcontext *ctx,
          x1, y1);
    */
 
+   cso_save_blend(st->cso_context);
+   cso_save_depth_stencil_alpha(st->cso_context);
+   cso_save_rasterizer(st->cso_context);
+   cso_save_viewport(st->cso_context);
+
    /* blend state: RGBA masking */
    {
       struct pipe_blend_state blend;
       memset(&blend, 0, sizeof(blend));
+      blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+      blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+      blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+      blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
       if (color) {
          if (ctx->Color.ColorMask[0])
             blend.colormask |= PIPE_MASK_R;
@@ -294,13 +303,6 @@ clear_with_quad(GLcontext *ctx,
    {
       struct pipe_rasterizer_state raster;
       memset(&raster, 0, sizeof(raster));
-#if 0
-      /* don't do per-pixel scissor; we'll just draw a PIPE_PRIM_QUAD
-       * that matches the scissor bounds.
-       */
-      if (ctx->Scissor.Enabled)
-         raster.scissor = 1;
-#endif
 #if TEST_DRAW_PASSTHROUGH
       raster.bypass_clipping = 1;
       raster.bypass_vs = 1;
@@ -342,28 +344,21 @@ clear_with_quad(GLcontext *ctx,
       vp.translate[1] = 0.5 * height;
       vp.translate[2] = 0.0;
       vp.translate[3] = 0.0;
-      pipe->set_viewport_state(pipe, &vp);
+      cso_set_viewport(st->cso_context, &vp);
    }
 #endif
 
    /* draw quad matching scissor rect (XXX verify coord round-off) */
    draw_quad(ctx, x0, y0, x1, y1, ctx->Depth.Clear, ctx->Color.ClearColor);
 
-#if 0
-   /* Can't depend on old state objects still existing -- may have
-    * been deleted to make room in the hash, etc.  (Should get
-    * fixed...)
-    */
-   st_invalidate_state(ctx, _NEW_COLOR | _NEW_DEPTH | _NEW_STENCIL);
-#else
    /* Restore pipe state */
-   cso_set_blend(st->cso_context, &st->state.blend);
-   cso_set_depth_stencil_alpha(st->cso_context, &st->state.depth_stencil);
-   cso_set_rasterizer(st->cso_context, &st->state.rasterizer);
+   cso_restore_blend(st->cso_context);
+   cso_restore_depth_stencil_alpha(st->cso_context);
+   cso_restore_rasterizer(st->cso_context);
+   cso_restore_viewport(st->cso_context);
+   /* these don't go through cso yet */
    pipe->bind_fs_state(pipe, st->fp->driver_shader);
    pipe->bind_vs_state(pipe, st->vp->driver_shader);
-#endif
-   pipe->set_viewport_state(pipe, &st->state.viewport);
 }
 
 
index 18ec9645c447b412a5dc78331e694ca2278feb58..33d34445ee0f975c9caa2e1fd85200d0b5cf64e0 100644 (file)
@@ -650,6 +650,9 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
    assert(width <= maxSize);
    assert(height <= maxSize);
 
+   cso_save_rasterizer(cso);
+   cso_save_viewport(cso);
+
    /* setup state: just scissor */
    {
       struct pipe_rasterizer_state  setup;
@@ -696,7 +699,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
       vp.translate[1] = 0.5 * height;
       vp.translate[2] = 0.0;
       vp.translate[3] = 0.0;
-      pipe->set_viewport_state(pipe, &vp);
+      cso_set_viewport(cso, &vp);
    }
 
    /* texture state: */
@@ -719,26 +722,18 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
    else
       draw_quad(ctx, x0, y0, z, x1, y1, invertTex);
 
-   /* restore GL state */
-   pipe->set_sampler_textures(pipe, ctx->st->state.num_textures,
-                              ctx->st->state.sampler_texture);
-
-   pipe->set_viewport_state(pipe, &ctx->st->state.viewport);
-
-#if 0
-   /* Can't depend on old state objects still existing -- may have
-    * been deleted to make room in the hash, etc.  (Should get
-    * fixed...)
-    */
-   st_invalidate_state(ctx, _NEW_COLOR | _NEW_TEXTURE);
-#else
    /* restore state */
+   cso_restore_rasterizer(cso);
+   cso_restore_viewport(cso);
+   /* shaders don't go through cso yet */
    pipe->bind_fs_state(pipe, st->fp->driver_shader);
    pipe->bind_vs_state(pipe, st->vp->driver_shader);
+
    cso_set_rasterizer(cso, &st->state.rasterizer);
    cso_set_samplers(cso, PIPE_MAX_SAMPLERS,
                  (const struct pipe_sampler_state **) st->state.sampler_list);
-#endif
+   pipe->set_sampler_textures(pipe, ctx->st->state.num_textures,
+                              ctx->st->state.sampler_texture);
 }
 
 
index 63150dbeaf6c21cc52086a16c628d46b9427782d..ca8307c4ba0224f06d4395abae95ed414c5893bd 100644 (file)
@@ -82,7 +82,6 @@ struct st_context
       struct pipe_rasterizer_state          rasterizer;
       struct pipe_sampler_state             samplers[PIPE_MAX_SAMPLERS];
       struct pipe_sampler_state             *sampler_list[PIPE_MAX_SAMPLERS];
-      struct pipe_blend_color  blend_color;
       struct pipe_clip_state clip;
       struct pipe_constant_buffer constants[2];
       struct pipe_framebuffer_state framebuffer;
index 6c3afca1ba165a0f5cc79b2e3c10dd9d772e4473..61e1d9621c15110c424c03945610a6fab7539db0 100644 (file)
@@ -59,7 +59,7 @@
 void
 st_init_generate_mipmap(struct st_context *st)
 {
-   st->gen_mipmap = util_create_gen_mipmap(st->pipe);
+   st->gen_mipmap = util_create_gen_mipmap(st->pipe, st->cso_context);
 }
 
 
@@ -94,19 +94,11 @@ st_render_mipmap(struct st_context *st,
 
    util_gen_mipmap(st->gen_mipmap, pt, face, baseLevel, lastLevel);
 
-   /* restore pipe state */
-#if 0
-   cso_set_rasterizer(st->cso_context, &st->state.rasterizer);
-   cso_set_samplers(st->cso_context, st->state.samplers_list);
-   pipe->bind_fs_state(pipe, st->fp->shader_program);
-   pipe->bind_vs_state(pipe, st->vp->shader_program);
-   pipe->set_sampler_textures(pipe, st->state.num_textures,
-                              st->state.sampler_texture);
-   pipe->set_viewport_state(pipe, &st->state.viewport);
-#else
-   /* XXX is this sufficient? */
-   st_invalidate_state(st->ctx, _NEW_COLOR | _NEW_TEXTURE);
-#endif
+   /* shaders don't go through CSO yet */
+   if (st->fp)
+      pipe->bind_fs_state(pipe, st->fp->driver_shader);
+   if (st->vp)
+      pipe->bind_vs_state(pipe, st->vp->driver_shader);
 
    return TRUE;
 }