util: Include missing header in u_simple_shaders.c.
[mesa.git] / src / gallium / auxiliary / cso_cache / cso_context.c
index 8568a0052d0a334fdf278a697dae327066c71903..58b022d531db97916aeb1948b9f638ba9c8cb9dc 100644 (file)
   */
 
 #include "pipe/p_state.h"
+#include "util/u_framebuffer.h"
 #include "util/u_inlines.h"
+#include "util/u_math.h"
 #include "util/u_memory.h"
-#include "util/u_sampler.h"
 #include "tgsi/tgsi_parse.h"
 
 #include "cso_cache/cso_context.h"
@@ -70,20 +71,16 @@ struct cso_context {
    unsigned nr_vertex_samplers_saved;
    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;
+   uint nr_fragment_sampler_views;
+   struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS];
 
-   struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
+   uint nr_vertex_sampler_views;
    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_fragment_sampler_views_saved;
+   struct pipe_sampler_view *fragment_sampler_views_saved[PIPE_MAX_SAMPLERS];
 
-   uint nr_vertex_textures_saved;
-   struct pipe_texture *vertex_textures_saved[PIPE_MAX_VERTEX_SAMPLERS];
+   uint nr_vertex_sampler_views_saved;
    struct pipe_sampler_view *vertex_sampler_views_saved[PIPE_MAX_VERTEX_SAMPLERS];
 
    /** Current and saved state.
@@ -102,14 +99,11 @@ struct cso_context {
    struct pipe_framebuffer_state fb, fb_saved;
    struct pipe_viewport_state vp, vp_saved;
    struct pipe_blend_color blend_color;
+   unsigned sample_mask;
    struct pipe_stencil_ref stencil_ref, stencil_ref_saved;
 };
 
 
-static void
-free_framebuffer_state(struct pipe_framebuffer_state *fb);
-
-
 static boolean delete_blend_state(struct cso_context *ctx, void *state)
 {
    struct cso_blend *cso = (struct cso_blend *)state;
@@ -295,24 +289,23 @@ void cso_release_all( struct cso_context *ctx )
       ctx->pipe->bind_fs_state( ctx->pipe, NULL );
       ctx->pipe->bind_vs_state( ctx->pipe, NULL );
       ctx->pipe->bind_vertex_elements_state( ctx->pipe, NULL );
+      ctx->pipe->set_fragment_sampler_views(ctx->pipe, 0, NULL);
+      if (ctx->pipe->set_vertex_sampler_views)
+         ctx->pipe->set_vertex_sampler_views(ctx->pipe, 0, NULL);
    }
 
    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);
+      pipe_sampler_view_reference(&ctx->fragment_sampler_views[i], NULL);
+      pipe_sampler_view_reference(&ctx->fragment_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);
-   free_framebuffer_state(&ctx->fb_saved);
+   util_unreference_framebuffer_state(&ctx->fb);
+   util_unreference_framebuffer_state(&ctx->fb_saved);
 
    if (ctx->cache) {
       cso_cache_delete( ctx->cache );
@@ -321,10 +314,13 @@ void cso_release_all( struct cso_context *ctx )
 }
 
 
+/**
+ * Free the CSO context.  NOTE: the state tracker should have previously called
+ * cso_release_all().
+ */
 void cso_destroy_context( struct cso_context *ctx )
 {
    if (ctx) {
-      /*cso_release_all( ctx );*/
       FREE( ctx );
    }
 }
@@ -357,6 +353,7 @@ enum pipe_error cso_set_blend(struct cso_context *ctx,
       if (!cso)
          return PIPE_ERROR_OUT_OF_MEMORY;
 
+      memset(&cso->state, 0, sizeof cso->state);
       memcpy(&cso->state, templ, key_size);
       cso->data = ctx->pipe->create_blend_state(ctx->pipe, &cso->state);
       cso->delete_state = (cso_state_callback)ctx->pipe->delete_blend_state;
@@ -625,163 +622,6 @@ cso_restore_vertex_samplers(struct cso_context *ctx)
 }
 
 
-enum pipe_error cso_set_sampler_textures( struct cso_context *ctx,
-                                          uint count,
-                                          struct pipe_texture **textures )
-{
-   uint i;
-
-   ctx->nr_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->textures[i], textures[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_views(ctx->pipe,
-                                         count,
-                                         ctx->sampler_views);
-
-   return PIPE_OK;
-}
-
-void cso_save_sampler_textures( struct cso_context *ctx )
-{
-   uint i;
-
-   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]);
-   }
-}
-
-void cso_restore_sampler_textures( struct cso_context *ctx )
-{
-   uint i;
-
-   ctx->nr_textures = ctx->nr_textures_saved;
-
-   for (i = 0; i < ctx->nr_textures; i++) {
-      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++) {
-      pipe_texture_reference(&ctx->textures[i], NULL);
-      pipe_sampler_view_reference(&ctx->sampler_views[i], NULL);
-   }
-
-   ctx->pipe->set_fragment_sampler_views(ctx->pipe,
-                                         ctx->nr_textures,
-                                         ctx->sampler_views);
-
-   ctx->nr_textures_saved = 0;
-}
-
-
-
-enum pipe_error
-cso_set_vertex_sampler_textures(struct cso_context *ctx,
-                                uint count,
-                                struct pipe_texture **textures)
-{
-   uint i;
-
-   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_views(ctx->pipe,
-                                       count,
-                                       ctx->vertex_sampler_views);
-
-   return PIPE_OK;
-}
-
-void
-cso_save_vertex_sampler_textures(struct cso_context *ctx)
-{
-   uint i;
-
-   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]);
-   }
-}
-
-void
-cso_restore_vertex_sampler_textures(struct cso_context *ctx)
-{
-   uint i;
-
-   ctx->nr_vertex_textures = ctx->nr_vertex_textures_saved;
-
-   for (i = 0; i < ctx->nr_vertex_textures; i++) {
-      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_views(ctx->pipe,
-                                       ctx->nr_vertex_textures,
-                                       ctx->vertex_sampler_views);
-
-   ctx->nr_vertex_textures_saved = 0;
-}
-
-
-
 enum pipe_error cso_set_depth_stencil_alpha(struct cso_context *ctx,
                                             const struct pipe_depth_stencil_alpha_state *templ)
 {
@@ -1057,42 +897,11 @@ void cso_restore_vertex_shader(struct cso_context *ctx)
 }
 
 
-/**
- * Copy framebuffer state from src to dst with refcounting of surfaces.
- */
-static void
-copy_framebuffer_state(struct pipe_framebuffer_state *dst,
-                       const struct pipe_framebuffer_state *src)
-{
-   uint i;
-
-   dst->width = src->width;
-   dst->height = src->height;
-   dst->nr_cbufs = src->nr_cbufs;
-   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
-      pipe_surface_reference(&dst->cbufs[i], src->cbufs[i]);
-   }
-   pipe_surface_reference(&dst->zsbuf, src->zsbuf);
-}
-
-
-static void
-free_framebuffer_state(struct pipe_framebuffer_state *fb)
-{
-   uint i;
-
-   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
-      pipe_surface_reference(&fb->cbufs[i], NULL);
-   }
-   pipe_surface_reference(&fb->zsbuf, NULL);
-}
-
-
 enum pipe_error cso_set_framebuffer(struct cso_context *ctx,
                                     const struct pipe_framebuffer_state *fb)
 {
    if (memcmp(&ctx->fb, fb, sizeof(*fb)) != 0) {
-      copy_framebuffer_state(&ctx->fb, fb);
+      util_copy_framebuffer_state(&ctx->fb, fb);
       ctx->pipe->set_framebuffer_state(ctx->pipe, fb);
    }
    return PIPE_OK;
@@ -1100,15 +909,15 @@ enum pipe_error cso_set_framebuffer(struct cso_context *ctx,
 
 void cso_save_framebuffer(struct cso_context *ctx)
 {
-   copy_framebuffer_state(&ctx->fb_saved, &ctx->fb);
+   util_copy_framebuffer_state(&ctx->fb_saved, &ctx->fb);
 }
 
 void cso_restore_framebuffer(struct cso_context *ctx)
 {
    if (memcmp(&ctx->fb, &ctx->fb_saved, sizeof(ctx->fb))) {
-      copy_framebuffer_state(&ctx->fb, &ctx->fb_saved);
+      util_copy_framebuffer_state(&ctx->fb, &ctx->fb_saved);
       ctx->pipe->set_framebuffer_state(ctx->pipe, &ctx->fb);
-      free_framebuffer_state(&ctx->fb_saved);
+      util_unreference_framebuffer_state(&ctx->fb_saved);
    }
 }
 
@@ -1148,6 +957,16 @@ enum pipe_error cso_set_blend_color(struct cso_context *ctx,
    return PIPE_OK;
 }
 
+enum pipe_error cso_set_sample_mask(struct cso_context *ctx,
+                                    unsigned sample_mask)
+{
+   if (ctx->sample_mask != sample_mask) {
+      ctx->sample_mask = sample_mask;
+      ctx->pipe->set_sample_mask(ctx->pipe, sample_mask);
+   }
+   return PIPE_OK;
+}
+
 enum pipe_error cso_set_stencil_ref(struct cso_context *ctx,
                                     const struct pipe_stencil_ref *sr)
 {
@@ -1213,6 +1032,7 @@ static INLINE void
 clip_state_cpy(struct pipe_clip_state *dst,
                const struct pipe_clip_state *src)
 {
+   dst->depth_clamp = src->depth_clamp;
    dst->nr = src->nr;
    if (src->nr) {
       memcpy(dst->ucp, src->ucp, src->nr * sizeof(src->ucp[0]));
@@ -1223,6 +1043,9 @@ static INLINE int
 clip_state_cmp(const struct pipe_clip_state *a,
                const struct pipe_clip_state *b)
 {
+   if (a->depth_clamp != b->depth_clamp) {
+      return 1;
+   }
    if (a->nr != b->nr) {
       return 1;
    }
@@ -1319,3 +1142,122 @@ void cso_restore_vertex_elements(struct cso_context *ctx)
    }
    ctx->velements_saved = NULL;
 }
+
+/* fragment sampler view state */
+
+void
+cso_set_fragment_sampler_views(struct cso_context *cso,
+                               uint count,
+                               struct pipe_sampler_view **views)
+{
+   uint i;
+
+   for (i = 0; i < count; i++) {
+      pipe_sampler_view_reference(&cso->fragment_sampler_views[i], views[i]);
+   }
+   for (; i < cso->nr_fragment_sampler_views; i++) {
+      pipe_sampler_view_reference(&cso->fragment_sampler_views[i], NULL);
+   }
+
+   cso->pipe->set_fragment_sampler_views(cso->pipe,
+                                         MAX2(count, cso->nr_fragment_sampler_views),
+                                         cso->fragment_sampler_views);
+
+   cso->nr_fragment_sampler_views = count;
+}
+
+void
+cso_save_fragment_sampler_views(struct cso_context *cso)
+{
+   uint i;
+
+   cso->nr_fragment_sampler_views_saved = cso->nr_fragment_sampler_views;
+
+   for (i = 0; i < cso->nr_fragment_sampler_views; i++) {
+      assert(!cso->fragment_sampler_views_saved[i]);
+
+      pipe_sampler_view_reference(&cso->fragment_sampler_views_saved[i],
+                                  cso->fragment_sampler_views[i]);
+   }
+}
+
+void
+cso_restore_fragment_sampler_views(struct cso_context *cso)
+{
+   uint i;
+
+   for (i = 0; i < cso->nr_fragment_sampler_views_saved; i++) {
+      pipe_sampler_view_reference(&cso->fragment_sampler_views[i], cso->fragment_sampler_views_saved[i]);
+      pipe_sampler_view_reference(&cso->fragment_sampler_views_saved[i], NULL);
+   }
+   for (; i < cso->nr_fragment_sampler_views; i++) {
+      pipe_sampler_view_reference(&cso->fragment_sampler_views[i], NULL);
+   }
+
+   cso->pipe->set_fragment_sampler_views(cso->pipe,
+                                         MAX2(cso->nr_fragment_sampler_views, cso->nr_fragment_sampler_views_saved),
+                                         cso->fragment_sampler_views);
+
+   cso->nr_fragment_sampler_views = cso->nr_fragment_sampler_views_saved;
+   cso->nr_fragment_sampler_views_saved = 0;
+}
+
+
+/* vertex sampler view state */
+
+void
+cso_set_vertex_sampler_views(struct cso_context *cso,
+                             uint count,
+                             struct pipe_sampler_view **views)
+{
+   uint i;
+
+   for (i = 0; i < count; i++) {
+      pipe_sampler_view_reference(&cso->vertex_sampler_views[i], views[i]);
+   }
+   for (; i < cso->nr_vertex_sampler_views; i++) {
+      pipe_sampler_view_reference(&cso->vertex_sampler_views[i], NULL);
+   }
+
+   cso->pipe->set_vertex_sampler_views(cso->pipe,
+                                       MAX2(count, cso->nr_vertex_sampler_views),
+                                       cso->vertex_sampler_views);
+
+   cso->nr_vertex_sampler_views = count;
+}
+
+void
+cso_save_vertex_sampler_views(struct cso_context *cso)
+{
+   uint i;
+
+   cso->nr_vertex_sampler_views_saved = cso->nr_vertex_sampler_views;
+
+   for (i = 0; i < cso->nr_vertex_sampler_views; i++) {
+      assert(!cso->vertex_sampler_views_saved[i]);
+
+      pipe_sampler_view_reference(&cso->vertex_sampler_views_saved[i],
+                                  cso->vertex_sampler_views[i]);
+   }
+}
+
+void
+cso_restore_vertex_sampler_views(struct cso_context *cso)
+{
+   uint i;
+
+   for (i = 0; i < cso->nr_vertex_sampler_views_saved; i++) {
+      pipe_sampler_view_reference(&cso->vertex_sampler_views[i], cso->vertex_sampler_views_saved[i]);
+      pipe_sampler_view_reference(&cso->vertex_sampler_views_saved[i], NULL);
+   }
+   for (; i < cso->nr_vertex_sampler_views; i++) {
+      pipe_sampler_view_reference(&cso->vertex_sampler_views[i], NULL);
+   }
+
+   cso->pipe->set_vertex_sampler_views(cso->pipe,
+                                       MAX2(cso->nr_vertex_sampler_views, cso->nr_vertex_sampler_views_saved),
+                                       cso->vertex_sampler_views);
+
+   cso->nr_vertex_sampler_views = cso->nr_vertex_sampler_views_saved;
+   cso->nr_vertex_sampler_views_saved = 0;
+}