nir: Add nir_foreach_shader_in/out_variable helpers
[mesa.git] / src / mesa / state_tracker / st_sampler_view.c
index 17c209c867fd91af79be3925ed7ddd981812e087..a31e573c01a3dec0371ddcbbf94d306c3ccbc6b5 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "pipe/p_context.h"
-#include "util/u_format.h"
+#include "util/format/u_format.h"
 #include "util/u_inlines.h"
 
 #include "main/context.h"
@@ -74,7 +74,7 @@ st_texture_set_sampler_view(struct st_context *st,
       if (sv->view) {
          /* check if the context matches */
          if (sv->view->context == st->pipe) {
-            pipe_sampler_view_release(st->pipe, &sv->view);
+            pipe_sampler_view_reference(&sv->view, NULL);
             goto found;
          }
       } else {
@@ -94,13 +94,13 @@ st_texture_set_sampler_view(struct st_context *st,
 
          if (new_max < views->max ||
              new_max > (UINT_MAX - sizeof(*views)) / sizeof(views->views[0])) {
-            pipe_sampler_view_release(st->pipe, &view);
+            pipe_sampler_view_reference(&view, NULL);
             goto out;
          }
 
          struct st_sampler_views *new_views = malloc(new_size);
          if (!new_views) {
-            pipe_sampler_view_release(st->pipe, &view);
+            pipe_sampler_view_reference(&view, NULL);
             goto out;
          }
 
@@ -150,6 +150,7 @@ found:
    sv->glsl130_or_later = glsl130_or_later;
    sv->srgb_skip_decode = srgb_skip_decode;
    sv->view = view;
+   sv->st = st;
 
 out:
    simple_mtx_unlock(&stObj->validate_mutex);
@@ -213,8 +214,6 @@ void
 st_texture_release_all_sampler_views(struct st_context *st,
                                      struct st_texture_object *stObj)
 {
-   GLuint i;
-
    /* TODO: This happens while a texture is deleted, because the Driver API
     * is asymmetric: the driver allocates the texture object memory, but
     * mesa/main frees it.
@@ -224,22 +223,41 @@ st_texture_release_all_sampler_views(struct st_context *st,
 
    simple_mtx_lock(&stObj->validate_mutex);
    struct st_sampler_views *views = stObj->sampler_views;
-   for (i = 0; i < views->count; ++i)
-      pipe_sampler_view_release(st->pipe, &views->views[i].view);
+   for (unsigned i = 0; i < views->count; ++i) {
+      struct st_sampler_view *stsv = &views->views[i];
+      if (stsv->view) {
+         if (stsv->st && stsv->st != st) {
+            /* Transfer this reference to the zombie list.  It will
+             * likely be freed when the zombie list is freed.
+             */
+            st_save_zombie_sampler_view(stsv->st, stsv->view);
+            stsv->view = NULL;
+         } else {
+            pipe_sampler_view_reference(&stsv->view, NULL);
+         }
+      }
+   }
+   views->count = 0;
    simple_mtx_unlock(&stObj->validate_mutex);
 }
 
 
 /*
- * Free the texture's st_sampler_views objects.  This should be called
- * after st_texture_release_all_sampler_views().
+ * Delete the texture's sampler views and st_sampler_views containers.
+ * This is to be called just before a texture is deleted.
  */
 void
-st_texture_free_sampler_views(struct st_texture_object *stObj)
+st_delete_texture_sampler_views(struct st_context *st,
+                                struct st_texture_object *stObj)
 {
+   st_texture_release_all_sampler_views(st, stObj);
+
+   /* Free the container of the current per-context sampler views */
+   assert(stObj->sampler_views->count == 0);
    free(stObj->sampler_views);
    stObj->sampler_views = NULL;
 
+   /* Free old sampler view containers */
    while (stObj->sampler_views_old) {
       struct st_sampler_views *views = stObj->sampler_views_old;
       stObj->sampler_views_old = views->next;
@@ -409,7 +427,7 @@ get_texture_format_swizzle(const struct st_context *st,
  *
  * \param stObj  the st texture object,
  */
-MAYBE_UNUSED static boolean
+ASSERTED static boolean
 check_sampler_swizzle(const struct st_context *st,
                       const struct st_texture_object *stObj,
                       const struct pipe_sampler_view *sv,
@@ -471,12 +489,30 @@ get_sampler_view_format(struct st_context *st,
    if (srgb_skip_decode)
       format = util_format_linear(format);
 
+   /* if resource format matches then YUV wasn't lowered */
+   if (format == stObj->pt->format)
+      return format;
+
    /* Use R8_UNORM for video formats */
    switch (format) {
    case PIPE_FORMAT_NV12:
    case PIPE_FORMAT_IYUV:
       format = PIPE_FORMAT_R8_UNORM;
       break;
+   case PIPE_FORMAT_P010:
+   case PIPE_FORMAT_P016:
+      format = PIPE_FORMAT_R16_UNORM;
+      break;
+   case PIPE_FORMAT_YUYV:
+   case PIPE_FORMAT_UYVY:
+      format = PIPE_FORMAT_R8G8_UNORM;
+      break;
+   case PIPE_FORMAT_AYUV:
+      format = PIPE_FORMAT_RGBA8888_UNORM;
+      break;
+   case PIPE_FORMAT_XYUV:
+      format = PIPE_FORMAT_RGBX8888_UNORM;
+      break;
    default:
       break;
    }
@@ -496,13 +532,13 @@ st_create_texture_sampler_view_from_stobj(struct st_context *st,
 
    templ.format = format;
 
-   if (stObj->level_override) {
+   if (stObj->level_override >= 0) {
       templ.u.tex.first_level = templ.u.tex.last_level = stObj->level_override;
    } else {
       templ.u.tex.first_level = stObj->base.MinLevel + stObj->base.BaseLevel;
       templ.u.tex.last_level = last_level(stObj);
    }
-   if (stObj->layer_override) {
+   if (stObj->layer_override >= 0) {
       templ.u.tex.first_layer = templ.u.tex.last_layer = stObj->layer_override;
    } else {
       templ.u.tex.first_layer = stObj->base.MinLayer;
@@ -547,12 +583,12 @@ st_get_texture_sampler_view_from_stobj(struct st_context *st,
       assert(!check_sampler_swizzle(st, stObj, view, glsl130_or_later));
       assert(get_sampler_view_format(st, stObj, srgb_skip_decode) == view->format);
       assert(gl_target_to_pipe(stObj->base.Target) == view->target);
-      assert(stObj->level_override ||
+      assert(stObj->level_override >= 0 ||
              stObj->base.MinLevel + stObj->base.BaseLevel == view->u.tex.first_level);
-      assert(stObj->level_override || last_level(stObj) == view->u.tex.last_level);
-      assert(stObj->layer_override || stObj->base.MinLayer == view->u.tex.first_layer);
-      assert(stObj->layer_override || last_layer(stObj) == view->u.tex.last_layer);
-      assert(!stObj->layer_override ||
+      assert(stObj->level_override >= 0 || last_level(stObj) == view->u.tex.last_level);
+      assert(stObj->layer_override >= 0 || stObj->base.MinLayer == view->u.tex.first_layer);
+      assert(stObj->layer_override >= 0 || last_layer(stObj) == view->u.tex.last_layer);
+      assert(stObj->layer_override < 0 ||
              (stObj->layer_override == view->u.tex.first_layer &&
               stObj->layer_override == view->u.tex.last_layer));
       return view;
@@ -598,8 +634,8 @@ st_get_buffer_sampler_view_from_stobj(struct st_context *st,
                                               stObj->base._BufferObjectFormat)
              == view->format);
          assert(view->target == PIPE_BUFFER);
-         unsigned base = stObj->base.BufferOffset;
-         MAYBE_UNUSED unsigned size = MIN2(buf->width0 - base,
+         ASSERTED unsigned base = stObj->base.BufferOffset;
+         ASSERTED unsigned size = MIN2(buf->width0 - base,
                            (unsigned) stObj->base.BufferSize);
          assert(view->u.buf.offset == base);
          assert(view->u.buf.size == size);