Ejemplo n.º 1
0
static struct pipe_surface *
svga_get_tex_surface(struct pipe_screen *screen,
                     struct pipe_resource *pt,
                     unsigned face, unsigned level, unsigned zslice,
                     unsigned flags)
{
   struct svga_texture *tex = svga_texture(pt);
   struct svga_surface *s;
   boolean render = (flags & (PIPE_BIND_RENDER_TARGET |
			      PIPE_BIND_DEPTH_STENCIL)) ? TRUE : FALSE;
   boolean view = FALSE;
   SVGA3dSurfaceFormat format;

   s = CALLOC_STRUCT(svga_surface);
   if (!s)
      return NULL;

   pipe_reference_init(&s->base.reference, 1);
   pipe_resource_reference(&s->base.texture, pt);
   s->base.format = pt->format;
   s->base.width = u_minify(pt->width0, level);
   s->base.height = u_minify(pt->height0, level);
   s->base.usage = flags;
   s->base.level = level;
   s->base.face = face;
   s->base.zslice = zslice;

   if (!render)
      format = svga_translate_format(pt->format);
   else
      format = svga_translate_format_render(pt->format);

   assert(format != SVGA3D_FORMAT_INVALID);

   if (svga_screen(screen)->debug.force_surface_view)
      view = TRUE;

   /* Currently only used for compressed textures */
   if (render && 
       format != svga_translate_format(pt->format)) {
      view = TRUE;
   }

   if (level != 0 && 
       svga_screen(screen)->debug.force_level_surface_view)
      view = TRUE;

   if (pt->target == PIPE_TEXTURE_3D)
      view = TRUE;

   if (svga_screen(screen)->debug.no_surface_view)
      view = FALSE;

   if (view) {
      SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: yes %p, level %u face %u z %u, %p\n",
               pt, level, face, zslice, s);

      s->handle = svga_texture_view_surface(NULL, tex, format, level, 1, face, zslice,
                                            &s->key);
      s->real_face = 0;
      s->real_level = 0;
      s->real_zslice = 0;
   } else {
      SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: no %p, level %u, face %u, z %u, %p\n",
               pt, level, face, zslice, s);

      memset(&s->key, 0, sizeof s->key);
      s->handle = tex->handle;
      s->real_face = face;
      s->real_level = level;
      s->real_zslice = zslice;
   }

   return &s->base;
}
Ejemplo n.º 2
0
/**
 * A helper function to create a surface view.
 * The view boolean flag specifies whether svga_texture_view_surface()
 * will be called to create a cloned surface and resource for the view.
 */
static struct pipe_surface *
svga_create_surface_view(struct pipe_context *pipe,
                         struct pipe_resource *pt,
                         const struct pipe_surface *surf_tmpl,
                         boolean view)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_texture *tex = svga_texture(pt);
   struct pipe_screen *screen = pipe->screen;
   struct svga_screen *ss = svga_screen(screen);
   struct svga_surface *s;
   unsigned layer, zslice, bind;
   unsigned nlayers = 1;
   SVGA3dSurfaceFlags flags = 0;
   SVGA3dSurfaceFormat format;

   s = CALLOC_STRUCT(svga_surface);
   if (!s)
      return NULL;

   if (pt->target == PIPE_TEXTURE_CUBE) {
      layer = surf_tmpl->u.tex.first_layer;
      zslice = 0;
   }
   else if (pt->target == PIPE_TEXTURE_1D_ARRAY ||
            pt->target == PIPE_TEXTURE_2D_ARRAY) {
      layer = surf_tmpl->u.tex.first_layer;
      zslice = 0;
      nlayers = surf_tmpl->u.tex.last_layer - surf_tmpl->u.tex.first_layer + 1;
   }
   else {
      layer = 0;
      zslice = surf_tmpl->u.tex.first_layer;
   }

   pipe_reference_init(&s->base.reference, 1);
   pipe_resource_reference(&s->base.texture, pt);
   s->base.context = pipe;
   s->base.format = surf_tmpl->format;
   s->base.width = u_minify(pt->width0, surf_tmpl->u.tex.level);
   s->base.height = u_minify(pt->height0, surf_tmpl->u.tex.level);
   s->base.u.tex.level = surf_tmpl->u.tex.level;
   s->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
   s->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;
   s->view_id = SVGA3D_INVALID_ID;

   s->backed = NULL;

   if (util_format_is_depth_or_stencil(surf_tmpl->format)) {
      flags = SVGA3D_SURFACE_HINT_DEPTHSTENCIL |
              SVGA3D_SURFACE_BIND_DEPTH_STENCIL;
      bind = PIPE_BIND_DEPTH_STENCIL;
   }
   else {
      flags = SVGA3D_SURFACE_HINT_RENDERTARGET |
              SVGA3D_SURFACE_BIND_RENDER_TARGET;
      bind = PIPE_BIND_RENDER_TARGET;
   }

   if (tex->imported)
      format = tex->key.format;
   else
      format = svga_translate_format(ss, surf_tmpl->format, bind);

   assert(format != SVGA3D_FORMAT_INVALID);

   if (view) {
      SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: yes %p, level %u layer %u z %u, %p\n",
               pt, surf_tmpl->u.tex.level, layer, zslice, s);

      if (svga_have_vgpu10(svga)) {
         switch (pt->target) {
         case PIPE_TEXTURE_1D:
            flags |= SVGA3D_SURFACE_1D;
            break;
         case PIPE_TEXTURE_1D_ARRAY:
            flags |= SVGA3D_SURFACE_1D | SVGA3D_SURFACE_ARRAY;
            break;
         case PIPE_TEXTURE_2D_ARRAY:
            flags |= SVGA3D_SURFACE_ARRAY;
            break;
         case PIPE_TEXTURE_3D:
            flags |= SVGA3D_SURFACE_VOLUME;
            break;
         case PIPE_TEXTURE_CUBE:
            if (nlayers == 6)
               flags |= SVGA3D_SURFACE_CUBEMAP;
            break;
         default:
            break;
         }
      }

      /* When we clone the surface view resource, use the format used in
       * the creation of the original resource.
       */
      s->handle = svga_texture_view_surface(svga, tex, bind, flags, tex->key.format,
                                            surf_tmpl->u.tex.level, 1,
                                            layer, nlayers, zslice, &s->key);
      if (!s->handle) {
         FREE(s);
         return NULL;
      }

      s->key.format = format;
      s->real_layer = 0;
      s->real_level = 0;
      s->real_zslice = 0;
   } else {
      SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: no %p, level %u, layer %u, z %u, %p\n",
               pt, surf_tmpl->u.tex.level, layer, zslice, s);

      memset(&s->key, 0, sizeof s->key);
      s->key.format = format;
      s->handle = tex->handle;
      s->real_layer = layer;
      s->real_zslice = zslice;
      s->real_level = surf_tmpl->u.tex.level;
   }

   svga->hud.num_surface_views++;

   return &s->base;
}
Ejemplo n.º 3
0
struct svga_sampler_view *
svga_get_tex_sampler_view(struct pipe_context *pipe,
			  struct pipe_resource *pt,
                          unsigned min_lod, unsigned max_lod)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_screen *ss = svga_screen(pipe->screen);
   struct svga_texture *tex = svga_texture(pt);
   struct svga_sampler_view *sv = NULL;
   SVGA3dSurfaceFlags flags = SVGA3D_SURFACE_HINT_TEXTURE;
   SVGA3dSurfaceFormat format = svga_translate_format(ss, pt->format,
                                                      PIPE_BIND_SAMPLER_VIEW);
   boolean view = TRUE;

   assert(pt);
   assert(min_lod <= max_lod);
   assert(max_lod <= pt->last_level);
   assert(!svga_have_vgpu10(svga));

   /* Is a view needed */
   {
      /*
       * Can't control max lod. For first level views and when we only
       * look at one level we disable mip filtering to achive the same
       * results as a view.
       */
      if (min_lod == 0 && max_lod >= pt->last_level)
         view = FALSE;

      if (ss->debug.no_sampler_view)
         view = FALSE;

      if (ss->debug.force_sampler_view)
         view = TRUE;
   }

   /* First try the cache */
   if (view) {
      mtx_lock(&ss->tex_mutex);
      if (tex->cached_view &&
          tex->cached_view->min_lod == min_lod &&
          tex->cached_view->max_lod == max_lod) {
         svga_sampler_view_reference(&sv, tex->cached_view);
         mtx_unlock(&ss->tex_mutex);
         SVGA_DBG(DEBUG_VIEWS, "svga: Sampler view: reuse %p, %u %u, last %u\n",
                              pt, min_lod, max_lod, pt->last_level);
         svga_validate_sampler_view(svga_context(pipe), sv);
         return sv;
      }
      mtx_unlock(&ss->tex_mutex);
   }

   sv = CALLOC_STRUCT(svga_sampler_view);
   if (!sv)
      return NULL;

   pipe_reference_init(&sv->reference, 1);

   /* Note: we're not refcounting the texture resource here to avoid
    * a circular dependency.
    */
   sv->texture = pt;

   sv->min_lod = min_lod;
   sv->max_lod = max_lod;

   /* No view needed just use the whole texture */
   if (!view) {
      SVGA_DBG(DEBUG_VIEWS,
               "svga: Sampler view: no %p, mips %u..%u, nr %u, size (%ux%ux%u), last %u\n",
               pt, min_lod, max_lod,
               max_lod - min_lod + 1,
               pt->width0,
               pt->height0,
               pt->depth0,
               pt->last_level);
      sv->key.cachable = 0;
      sv->handle = tex->handle;
      debug_reference(&sv->reference,
                      (debug_reference_descriptor)svga_debug_describe_sampler_view, 0);
      return sv;
   }

   SVGA_DBG(DEBUG_VIEWS,
            "svga: Sampler view: yes %p, mips %u..%u, nr %u, size (%ux%ux%u), last %u\n",
            pt, min_lod, max_lod,
            max_lod - min_lod + 1,
            pt->width0,
            pt->height0,
            pt->depth0,
            pt->last_level);

   sv->age = tex->age;
   sv->handle = svga_texture_view_surface(svga, tex,
                                          PIPE_BIND_SAMPLER_VIEW,
                                          flags, format,
                                          min_lod,
                                          max_lod - min_lod + 1,
                                          -1, 1, -1, FALSE,
                                          &sv->key);

   if (!sv->handle) {
      sv->key.cachable = 0;
      sv->handle = tex->handle;
      debug_reference(&sv->reference,
                      (debug_reference_descriptor)
                      svga_debug_describe_sampler_view, 0);
      return sv;
   }

   mtx_lock(&ss->tex_mutex);
   svga_sampler_view_reference(&tex->cached_view, sv);
   mtx_unlock(&ss->tex_mutex);

   debug_reference(&sv->reference,
                   (debug_reference_descriptor)
                   svga_debug_describe_sampler_view, 0);

   return sv;
}
Ejemplo n.º 4
0
static struct pipe_surface *
svga_create_surface(struct pipe_context *pipe,
                    struct pipe_resource *pt,
                    const struct pipe_surface *surf_tmpl)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_texture *tex = svga_texture(pt);
   struct pipe_screen *screen = pipe->screen;
   struct svga_screen *ss = svga_screen(screen);
   struct svga_surface *s;
   unsigned face, zslice;
   boolean view = FALSE;
   SVGA3dSurfaceFlags flags;
   SVGA3dSurfaceFormat format;

   assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);

   s = CALLOC_STRUCT(svga_surface);
   if (!s)
      return NULL;

   if (pt->target == PIPE_TEXTURE_CUBE) {
      face = surf_tmpl->u.tex.first_layer;
      zslice = 0;
   }
   else {
      face = 0;
      zslice = surf_tmpl->u.tex.first_layer;
   }

   pipe_reference_init(&s->base.reference, 1);
   pipe_resource_reference(&s->base.texture, pt);
   s->base.context = pipe;
   s->base.format = surf_tmpl->format;
   s->base.width = u_minify(pt->width0, surf_tmpl->u.tex.level);
   s->base.height = u_minify(pt->height0, surf_tmpl->u.tex.level);
   s->base.u.tex.level = surf_tmpl->u.tex.level;
   s->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
   s->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;

   if (util_format_is_depth_or_stencil(surf_tmpl->format)) {
      flags = SVGA3D_SURFACE_HINT_DEPTHSTENCIL;
   }
   else {
      flags = SVGA3D_SURFACE_HINT_RENDERTARGET;
   }

   format = svga_translate_format(ss, surf_tmpl->format, 0);
   assert(format != SVGA3D_FORMAT_INVALID);

   if (svga_screen(screen)->debug.force_surface_view)
      view = TRUE;

   /* Currently only used for compressed textures */
   if (format != svga_translate_format(ss, surf_tmpl->format, 0)) {
      view = TRUE;
   }

   if (surf_tmpl->u.tex.level != 0 &&
       svga_screen(screen)->debug.force_level_surface_view)
      view = TRUE;

   if (pt->target == PIPE_TEXTURE_3D)
      view = TRUE;

   if (svga_screen(screen)->debug.no_surface_view)
      view = FALSE;

   if (view) {
      SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: yes %p, level %u face %u z %u, %p\n",
               pt, surf_tmpl->u.tex.level, face, zslice, s);

      s->handle = svga_texture_view_surface(svga, tex, flags, format,
                                            surf_tmpl->u.tex.level,
                                            1, face, zslice, &s->key);
      s->real_face = 0;
      s->real_level = 0;
      s->real_zslice = 0;
   } else {
      SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: no %p, level %u, face %u, z %u, %p\n",
               pt, surf_tmpl->u.tex.level, face, zslice, s);

      memset(&s->key, 0, sizeof s->key);
      s->handle = tex->handle;
      s->real_face = face;
      s->real_zslice = zslice;
      s->real_level = surf_tmpl->u.tex.level;
   }

   return &s->base;
}