svga: add 'start' parameter to bind_sampler_states/views()
authorBrian Paul <brianp@vmware.com>
Fri, 10 Aug 2012 02:59:44 +0000 (20:59 -0600)
committerBrian Paul <brianp@vmware.com>
Thu, 16 Aug 2012 15:01:31 +0000 (09:01 -0600)
src/gallium/drivers/svga/svga_pipe_sampler.c

index 7675daac5abecab4354e98fb914e8834a87b2b0e..0d2745e25eff9ed3e649699bec0e912bb2464c0c 100644 (file)
@@ -146,31 +146,52 @@ svga_create_sampler_state(struct pipe_context *pipe,
 }
 
 static void
-svga_bind_fragment_sampler_states(struct pipe_context *pipe,
-                                  unsigned num, void **sampler)
+svga_bind_sampler_states(struct pipe_context *pipe,
+                         unsigned shader,
+                         unsigned start,
+                         unsigned num,
+                         void **samplers)
 {
    struct svga_context *svga = svga_context(pipe);
    unsigned i;
 
-   assert(num <= PIPE_MAX_SAMPLERS);
+   assert(shader < PIPE_SHADER_TYPES);
+   assert(start + num <= PIPE_MAX_SAMPLERS);
+
+   /* we only support fragment shader samplers at this time */
+   if (shader != PIPE_SHADER_FRAGMENT)
+      return;
 
    /* Check for no-op */
-   if (num == svga->curr.num_samplers &&
-       !memcmp(svga->curr.sampler, sampler, num * sizeof(void *))) {
+   if (start + num <= svga->curr.num_samplers &&
+       !memcmp(svga->curr.sampler + start, samplers, num * sizeof(void *))) {
       if (0) debug_printf("sampler noop\n");
       return;
    }
 
    for (i = 0; i < num; i++)
-      svga->curr.sampler[i] = sampler[i];
+      svga->curr.sampler[start + i] = samplers[i];
 
-   for (i = num; i < svga->curr.num_samplers; i++)
-      svga->curr.sampler[i] = NULL;
+   /* find highest non-null sampler_views[] entry */
+   {
+      unsigned j = MAX2(svga->curr.num_samplers, start + num);
+      while (j > 0 && svga->curr.sampler[j - 1] == NULL)
+         j--;
+      svga->curr.num_samplers = j;
+   }
 
-   svga->curr.num_samplers = num;
    svga->dirty |= SVGA_NEW_SAMPLER;
 }
 
+
+static void
+svga_bind_fragment_sampler_states(struct pipe_context *pipe,
+                                  unsigned num, void **sampler)
+{
+   svga_bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, num, sampler);
+}
+
+
 static void svga_delete_sampler_state(struct pipe_context *pipe,
                                       void *sampler)
 {
@@ -206,49 +227,61 @@ svga_sampler_view_destroy(struct pipe_context *pipe,
 }
 
 static void
-svga_set_fragment_sampler_views(struct pipe_context *pipe,
-                                unsigned num,
-                                struct pipe_sampler_view **views)
+svga_set_sampler_views(struct pipe_context *pipe,
+                       unsigned shader,
+                       unsigned start,
+                       unsigned num,
+                       struct pipe_sampler_view **views)
 {
    struct svga_context *svga = svga_context(pipe);
    unsigned flag_1d = 0;
    unsigned flag_srgb = 0;
    uint i;
 
-   assert(num <= PIPE_MAX_SAMPLERS);
+   assert(shader < PIPE_SHADER_TYPES);
+   assert(start + num <= Elements(svga->curr.sampler_views));
+
+   /* we only support fragment shader sampler views at this time */
+   if (shader != PIPE_SHADER_FRAGMENT)
+      return;
 
    /* Check for no-op */
-   if (num == svga->curr.num_sampler_views &&
-       !memcmp(svga->curr.sampler_views, views, num * sizeof(struct pipe_sampler_view *))) {
+   if (start + num <= svga->curr.num_sampler_views &&
+       !memcmp(svga->curr.sampler_views + start, views,
+               num * sizeof(struct pipe_sampler_view *))) {
       if (0) debug_printf("texture noop\n");
       return;
    }
 
    for (i = 0; i < num; i++) {
-      if (svga->curr.sampler_views[i] != views[i]) {
+      if (svga->curr.sampler_views[start + i] != views[i]) {
          /* Note: we're using pipe_sampler_view_release() here to work around
           * a possible crash when the old view belongs to another context that
           * was already destroyed.
           */
-         pipe_sampler_view_release(pipe, &svga->curr.sampler_views[i]);
-         pipe_sampler_view_reference(&svga->curr.sampler_views[i], views[i]);
+         pipe_sampler_view_release(pipe, &svga->curr.sampler_views[start + i]);
+         pipe_sampler_view_reference(&svga->curr.sampler_views[start + i],
+                                     views[i]);
       }
 
       if (!views[i])
          continue;
 
       if (util_format_is_srgb(views[i]->format))
-         flag_srgb |= 1 << i;
+         flag_srgb |= 1 << (start + i);
 
       if (views[i]->texture->target == PIPE_TEXTURE_1D)
-         flag_1d |= 1 << i;
+         flag_1d |= 1 << (start + i);
    }
 
-   for (i = num; i < svga->curr.num_sampler_views; i++)
-      pipe_sampler_view_reference(&svga->curr.sampler_views[i],
-                                  NULL);
+   /* find highest non-null sampler_views[] entry */
+   {
+      unsigned j = MAX2(svga->curr.num_sampler_views, start + num);
+      while (j > 0 && svga->curr.sampler_views[j - 1] == NULL)
+         j--;
+      svga->curr.num_sampler_views = j;
+   }
 
-   svga->curr.num_sampler_views = num;
    svga->dirty |= SVGA_NEW_TEXTURE_BINDING;
 
    if (flag_srgb != svga->curr.tex_flags.flag_srgb ||
@@ -261,6 +294,14 @@ svga_set_fragment_sampler_views(struct pipe_context *pipe,
 }
 
 
+static void
+svga_set_fragment_sampler_views(struct pipe_context *pipe,
+                                unsigned num,
+                                struct pipe_sampler_view **views)
+{
+   svga_set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, num, views);
+}
+
 
 void svga_init_sampler_functions( struct svga_context *svga )
 {