/**********************************************************
 * Copyright 2008-2009 VMware, Inc.  All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 **********************************************************/

#include "svga_cmd.h"

#include "pipe/p_state.h"
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
#include "os/os_thread.h"
#include "util/u_bitmask.h"
#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"

#include "svga_format.h"
#include "svga_screen.h"
#include "svga_context.h"
#include "svga_sampler_view.h"
#include "svga_resource_texture.h"
#include "svga_surface.h"
#include "svga_debug.h"

static void svga_mark_surface_dirty(struct pipe_surface *surf);

void
svga_texture_copy_handle(struct svga_context *svga,
                         struct svga_winsys_surface *src_handle,
                         unsigned src_x, unsigned src_y, unsigned src_z,
                         unsigned src_level, unsigned src_layer,
                         struct svga_winsys_surface *dst_handle,
                         unsigned dst_x, unsigned dst_y, unsigned dst_z,
                         unsigned dst_level, unsigned dst_layer,
                         unsigned width, unsigned height, unsigned depth)
{
   struct svga_surface dst, src;
   enum pipe_error ret;
   SVGA3dCopyBox box, *boxes;

   assert(svga);

   src.handle = src_handle;
   src.real_level = src_level;
   src.real_layer = src_layer;
   src.real_zslice = 0;

   dst.handle = dst_handle;
   dst.real_level = dst_level;
   dst.real_layer = dst_layer;
   dst.real_zslice = 0;

   box.x = dst_x;
   box.y = dst_y;
   box.z = dst_z;
   box.w = width;
   box.h = height;
   box.d = depth;
   box.srcx = src_x;
   box.srcy = src_y;
   box.srcz = src_z;

/*
   SVGA_DBG(DEBUG_VIEWS, "mipcopy src: %p %u (%ux%ux%u), dst: %p %u (%ux%ux%u)\n",
            src_handle, src_level, src_x, src_y, src_z,
            dst_handle, dst_level, dst_x, dst_y, dst_z);
*/

   ret = SVGA3D_BeginSurfaceCopy(svga->swc,
                                 &src.base,
                                 &dst.base,
                                 &boxes, 1);
   if (ret != PIPE_OK) {
      svga_context_flush(svga, NULL);
      ret = SVGA3D_BeginSurfaceCopy(svga->swc,
                                    &src.base,
                                    &dst.base,
                                    &boxes, 1);
      assert(ret == PIPE_OK);
   }
   *boxes = box;
   SVGA_FIFOCommitAll(svga->swc);
}


/* A helper function to sync up the two surface handles.
 */
static void
svga_texture_copy_handle_resource(struct svga_context *svga,
                                  struct svga_texture *src_tex,
                                  struct svga_winsys_surface *dst,
                                  unsigned int numMipLevels,
                                  unsigned int numLayers,
                                  int zslice_pick,
                                  unsigned int mipoffset,
                                  unsigned int layeroffset)
{
   unsigned int i, j;
   unsigned int zoffset = 0;

   /* A negative zslice_pick implies zoffset at 0, and depth to copy is
    * from the depth of the texture at the particular mipmap level.
    */
   if (zslice_pick >= 0)
      zoffset = zslice_pick;

   for (i = 0; i < numMipLevels; i++) {
      unsigned int miplevel = i + mipoffset;

      for (j = 0; j < numLayers; j++) {
         if (svga_is_texture_level_defined(src_tex, j+layeroffset, miplevel)) {
            unsigned depth = (zslice_pick < 0 ?
                              u_minify(src_tex->b.b.depth0, miplevel) : 1);

            svga_texture_copy_handle(svga,
                                     src_tex->handle,
                                     0, 0, zoffset,
                                     miplevel,
                                     j + layeroffset,
                                     dst, 0, 0, 0, i, j,
                                     u_minify(src_tex->b.b.width0, miplevel),
                                     u_minify(src_tex->b.b.height0, miplevel),
                                     depth);
         }
      }
   }
}


struct svga_winsys_surface *
svga_texture_view_surface(struct svga_context *svga,
                          struct svga_texture *tex,
                          unsigned bind_flags,
                          SVGA3dSurfaceFlags flags,
                          SVGA3dSurfaceFormat format,
                          unsigned start_mip,
                          unsigned num_mip,
                          int layer_pick,
                          unsigned num_layers,
                          int zslice_pick,
                          boolean cacheable,
                          struct svga_host_surface_cache_key *key) /* OUT */
{
   struct svga_screen *ss = svga_screen(svga->pipe.screen);
   struct svga_winsys_surface *handle = NULL;
   boolean validated;
   boolean needCopyResource;

   SVGA_DBG(DEBUG_PERF,
            "svga: Create surface view: layer %d zslice %d mips %d..%d\n",
            layer_pick, zslice_pick, start_mip, start_mip+num_mip-1);

   SVGA_STATS_TIME_PUSH(ss->sws, SVGA_STATS_TIME_EMULATESURFACEVIEW);

   key->flags = flags;
   key->format = format;
   key->numMipLevels = num_mip;
   key->size.width = u_minify(tex->b.b.width0, start_mip);
   key->size.height = u_minify(tex->b.b.height0, start_mip);
   key->size.depth = zslice_pick < 0 ? u_minify(tex->b.b.depth0, start_mip) : 1;
   key->cachable = 1;
   key->arraySize = 1;
   key->numFaces = 1;

   /* single sample surface can be treated as non-multisamples surface */
   key->sampleCount = tex->b.b.nr_samples > 1 ? tex->b.b.nr_samples : 0;

   if (key->sampleCount > 1) {
      key->flags |= SVGA3D_SURFACE_MASKABLE_ANTIALIAS;
   }

   if (tex->b.b.target == PIPE_TEXTURE_CUBE && layer_pick < 0) {
      key->flags |= SVGA3D_SURFACE_CUBEMAP;
      key->numFaces = 6;
   } else if (tex->b.b.target == PIPE_TEXTURE_1D_ARRAY ||
              tex->b.b.target == PIPE_TEXTURE_2D_ARRAY) {
      key->arraySize = num_layers;
   }

   if (key->format == SVGA3D_FORMAT_INVALID) {
      key->cachable = 0;
      goto done;
   }

   if (cacheable && tex->backed_handle &&
       memcmp(key, &tex->backed_key, sizeof *key) == 0) {
      handle = tex->backed_handle;
      needCopyResource = tex->backed_age < tex->age;
   } else {
      SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n");
      handle = svga_screen_surface_create(ss, bind_flags, PIPE_USAGE_DEFAULT,
                                          &validated, key);
      needCopyResource = TRUE;

      if (cacheable && !tex->backed_handle) {
         tex->backed_handle = handle;
         memcpy(&tex->backed_key, key, sizeof *key);
      }
   }

   if (!handle) {
      key->cachable = 0;
      goto done;
   }

   SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture view)\n", handle);

   if (layer_pick < 0)
      layer_pick = 0;

   if (needCopyResource) {
      svga_texture_copy_handle_resource(svga, tex, handle,
                                        key->numMipLevels,
                                        key->numFaces * key->arraySize,
                                        zslice_pick, start_mip, layer_pick);
      tex->backed_age = tex->age;
   }

done:
   SVGA_STATS_TIME_POP(ss->sws);

   return handle;
}


/**
 * 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;
   struct pipe_surface *retVal = NULL;

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

   SVGA_STATS_TIME_PUSH(ss->sws, SVGA_STATS_TIME_CREATESURFACEVIEW);

   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) {
      /* imported resource (a window) */
      format = tex->key.format;
      if (util_format_is_srgb(surf_tmpl->format)) {
         /* sRGB rendering to window */
         format = svga_linear_to_srgb(format);
      }
   }
   else {
      format = svga_translate_format(ss, surf_tmpl->format, bind);
   }

   assert(format != SVGA3D_FORMAT_INVALID);

   if (view) {
      SVGA_DBG(DEBUG_VIEWS,
               "New backed surface view: resource %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,
                                            TRUE, &s->key);
      if (!s->handle) {
         FREE(s);
         goto done;
      }

      s->key.format = format;
      s->real_layer = 0;
      s->real_level = 0;
      s->real_zslice = 0;
   } else {
      SVGA_DBG(DEBUG_VIEWS,
               "New surface view: resource %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++;
   retVal = &s->base;

done:
   SVGA_STATS_TIME_POP(ss->sws);
   return retVal;
}


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 pipe_screen *screen = pipe->screen;
   struct pipe_surface *surf = NULL;
   boolean view = FALSE;

   SVGA_STATS_TIME_PUSH(svga_sws(svga), SVGA_STATS_TIME_CREATESURFACE);

   if (svga_screen(screen)->debug.force_surface_view)
      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_have_vgpu10(svga) || svga_screen(screen)->debug.no_surface_view)
      view = FALSE;

   surf = svga_create_surface_view(pipe, pt, surf_tmpl, view);

   SVGA_STATS_TIME_POP(svga_sws(svga));

   return surf;
}


/**
 * Clone the surface view and its associated resource.
 */
static struct svga_surface *
create_backed_surface_view(struct svga_context *svga, struct svga_surface *s)
{
   struct svga_texture *tex = svga_texture(s->base.texture);

   if (!s->backed) {
      struct pipe_surface *backed_view;

      SVGA_STATS_TIME_PUSH(svga_sws(svga),
                           SVGA_STATS_TIME_CREATEBACKEDSURFACEVIEW);

      backed_view = svga_create_surface_view(&svga->pipe,
                                             &tex->b.b,
                                             &s->base,
                                             TRUE);
      if (!backed_view)
         goto done;

      s->backed = svga_surface(backed_view);

      SVGA_STATS_TIME_POP(svga_sws(svga));
   }
   else if (s->backed->age < tex->age) {
      /*
       * There is already an existing backing surface, but we still need to
       * sync the backing resource if the original resource has been modified
       * since the last copy.
       */
      struct svga_surface *bs = s->backed;
      unsigned int layer, zslice;

      assert(bs->handle);

      switch (tex->b.b.target) {
      case PIPE_TEXTURE_CUBE:
      case PIPE_TEXTURE_1D_ARRAY:
      case PIPE_TEXTURE_2D_ARRAY:
         layer = s->base.u.tex.first_layer;
         zslice = 0;
         break;
      default:
         layer = 0;
         zslice = s->base.u.tex.first_layer;
      }

      svga_texture_copy_handle_resource(svga, tex, bs->handle,
                                        bs->key.numMipLevels,
                                        bs->key.numFaces * bs->key.arraySize,
                                        zslice, s->base.u.tex.level, layer);
   }

   svga_mark_surface_dirty(&s->backed->base);
   s->backed->age = tex->age;

done:
   return s->backed;
}

/**
 * Create a DX RenderTarget/DepthStencil View for the given surface,
 * if needed.
 */
struct pipe_surface *
svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s)
{
   enum pipe_error ret = PIPE_OK;
   enum pipe_shader_type shader;

   assert(svga_have_vgpu10(svga));
   assert(s);

   SVGA_STATS_TIME_PUSH(svga_sws(svga),
                        SVGA_STATS_TIME_VALIDATESURFACEVIEW);

   /**
    * DX spec explicitly specifies that no resource can be bound to a render
    * target view and a shader resource view simultanously.
    * So first check if the resource bound to this surface view collides with
    * a sampler view. If so, then we will clone this surface view and its
    * associated resource. We will then use the cloned surface view for
    * render target.
    */
   for (shader = PIPE_SHADER_VERTEX; shader <= PIPE_SHADER_GEOMETRY; shader++) {
      if (svga_check_sampler_view_resource_collision(svga, s->handle, shader)) {
         SVGA_DBG(DEBUG_VIEWS,
                  "same resource used in shaderResource and renderTarget 0x%x\n",
                  s->handle);
         s = create_backed_surface_view(svga, s);

         if (s)
            svga->state.hw_draw.has_backed_views = TRUE;

         /* s may be null here if the function failed */
         break;
      }
   }

   if (s && s->view_id == SVGA3D_INVALID_ID) {
      SVGA3dResourceType resType;
      SVGA3dRenderTargetViewDesc desc;
      struct svga_texture *stex = svga_texture(s->base.texture);

      if (stex->validated == FALSE) {
         assert(stex->handle);

         /* We are about to render into a surface that has not been validated.
          * First invalidate the surface so that the device does not
          * need to update the host-side copy with the invalid
          * content when the associated mob is first bound to the surface.
          */
         if (svga->swc->surface_invalidate(svga->swc, stex->handle) != PIPE_OK) {
            svga_context_flush(svga, NULL);
            ret = svga->swc->surface_invalidate(svga->swc, stex->handle);
            assert(ret == PIPE_OK);
         }
         stex->validated = TRUE;
      }

      desc.tex.mipSlice = s->real_level;
      desc.tex.firstArraySlice = s->real_layer + s->real_zslice;
      desc.tex.arraySize =
         s->base.u.tex.last_layer - s->base.u.tex.first_layer + 1;

      s->view_id = util_bitmask_add(svga->surface_view_id_bm);

      resType = svga_resource_type(s->base.texture->target);

      if (util_format_is_depth_or_stencil(s->base.format)) {
         ret = SVGA3D_vgpu10_DefineDepthStencilView(svga->swc,
                                                    s->view_id,
                                                    s->handle,
                                                    s->key.format,
                                                    resType,
                                                    &desc);
      }
      else {
         SVGA3dSurfaceFormat view_format = s->key.format;
         const struct svga_texture *stex = svga_texture(s->base.texture);

         /* Can't create RGBA render target view of a RGBX surface so adjust
          * the view format.  We do something similar for texture samplers in
          * svga_validate_pipe_sampler_view().
          */
         if (view_format == SVGA3D_B8G8R8A8_UNORM &&
             (stex->key.format == SVGA3D_B8G8R8X8_UNORM ||
              stex->key.format == SVGA3D_B8G8R8X8_TYPELESS)) {
            view_format = SVGA3D_B8G8R8X8_UNORM;
         }

         ret = SVGA3D_vgpu10_DefineRenderTargetView(svga->swc,
                                                    s->view_id,
                                                    s->handle,
                                                    view_format,
                                                    resType,
                                                    &desc);
      }

      if (ret != PIPE_OK) {
         util_bitmask_clear(svga->surface_view_id_bm, s->view_id);
         s->view_id = SVGA3D_INVALID_ID;
         s = NULL;
      }
   }
   
   SVGA_STATS_TIME_POP(svga_sws(svga));

   return s ? &s->base : NULL;
}



static void
svga_surface_destroy(struct pipe_context *pipe,
                     struct pipe_surface *surf)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_surface *s = svga_surface(surf);
   struct svga_texture *t = svga_texture(surf->texture);
   struct svga_screen *ss = svga_screen(surf->texture->screen);
   enum pipe_error ret = PIPE_OK;

   SVGA_STATS_TIME_PUSH(ss->sws, SVGA_STATS_TIME_DESTROYSURFACE);

   /* Destroy the backed view surface if it exists */
   if (s->backed) {
      svga_surface_destroy(pipe, &s->backed->base);
      s->backed = NULL;
   }

   /* Destroy the surface handle if this is a backed handle and
    * it is not being cached in the texture.
    */
   if (s->handle != t->handle && s->handle != t->backed_handle) {
      SVGA_DBG(DEBUG_DMA, "unref sid %p (tex surface)\n", s->handle);
      svga_screen_surface_destroy(ss, &s->key, &s->handle);
   }

   if (s->view_id != SVGA3D_INVALID_ID) {
      unsigned try;

      /* The SVGA3D device will generate a device error if the
       * render target view or depth stencil view is destroyed from
       * a context other than the one it was created with.
       * Similar to shader resource view, in this case, we will skip
       * the destroy for now.
       */
      if (surf->context != pipe) {
         _debug_printf("context mismatch in %s\n", __func__);
      }
      else {
         assert(svga_have_vgpu10(svga));
         for (try = 0; try < 2; try++) {
            if (util_format_is_depth_or_stencil(s->base.format)) {
               ret = SVGA3D_vgpu10_DestroyDepthStencilView(svga->swc, s->view_id);
            }
            else {
               ret = SVGA3D_vgpu10_DestroyRenderTargetView(svga->swc, s->view_id);
            }
            if (ret == PIPE_OK)
               break;
            svga_context_flush(svga, NULL);
         }
         assert(ret == PIPE_OK);
         util_bitmask_clear(svga->surface_view_id_bm, s->view_id);
      }
   }

   pipe_resource_reference(&surf->texture, NULL);
   FREE(surf);

   svga->hud.num_surface_views--;
   SVGA_STATS_TIME_POP(ss->sws);
}


static void
svga_mark_surface_dirty(struct pipe_surface *surf)
{
   struct svga_surface *s = svga_surface(surf);
   struct svga_texture *tex = svga_texture(surf->texture);

   if (!s->dirty) {
      s->dirty = TRUE;

      if (s->handle == tex->handle) {
         /* hmm so 3d textures always have all their slices marked ? */
         svga_define_texture_level(tex, surf->u.tex.first_layer,
                                   surf->u.tex.level);
      }
      else {
         /* this will happen later in svga_propagate_surface */
      }
   }

   /* Increment the view_age and texture age for this surface's mipmap
    * level so that any sampler views into the texture are re-validated too.
    * Note: we age the texture for backed surface view only when the
    *       backed surface is propagated to the original surface.
    */
   if (s->handle == tex->handle)
      svga_age_texture_view(tex, surf->u.tex.level);
}


void
svga_mark_surfaces_dirty(struct svga_context *svga)
{
   unsigned i;
   struct svga_hw_clear_state *hw = &svga->state.hw_clear;

   if (svga_have_vgpu10(svga)) {

      /* For VGPU10, mark the dirty bit in the rendertarget/depth stencil view surface.
       * This surface can be the backed surface.
       */
      for (i = 0; i < hw->num_rendertargets; i++) {
         if (hw->rtv[i])
            svga_mark_surface_dirty(hw->rtv[i]);
      }
      if (hw->dsv)
         svga_mark_surface_dirty(hw->dsv);
   } else {
      for (i = 0; i < svga->curr.framebuffer.nr_cbufs; i++) {
         if (svga->curr.framebuffer.cbufs[i])
            svga_mark_surface_dirty(svga->curr.framebuffer.cbufs[i]);
      }
      if (svga->curr.framebuffer.zsbuf)
         svga_mark_surface_dirty(svga->curr.framebuffer.zsbuf);
   }
}


/**
 * Progagate any changes from surfaces to texture.
 * pipe is optional context to inline the blit command in.
 */
void
svga_propagate_surface(struct svga_context *svga, struct pipe_surface *surf,
                       boolean reset)
{
   struct svga_surface *s = svga_surface(surf);
   struct svga_texture *tex = svga_texture(surf->texture);
   struct svga_screen *ss = svga_screen(surf->texture->screen);

   if (!s->dirty)
      return;

   SVGA_STATS_TIME_PUSH(ss->sws, SVGA_STATS_TIME_PROPAGATESURFACE);

   /* Reset the dirty flag if specified. This is to ensure that
    * the dirty flag will not be reset and stay unset when the backing
    * surface is still being bound and rendered to.
    * The reset flag will be set to TRUE when the surface is propagated
    * and will be unbound.
    */
   s->dirty = !reset;

   ss->texture_timestamp++;
   svga_age_texture_view(tex, surf->u.tex.level);

   if (s->handle != tex->handle) {
      unsigned zslice, layer;
      unsigned nlayers = 1;
      unsigned i;

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

      SVGA_DBG(DEBUG_VIEWS,
               "Propagate surface %p to resource %p, level %u\n",
               surf, tex, surf->u.tex.level);
      for (i = 0; i < nlayers; i++) {
         svga_texture_copy_handle(svga,
                                  s->handle, 0, 0, 0, s->real_level,
                                  s->real_layer + i,
                                  tex->handle, 0, 0, zslice, surf->u.tex.level,
                                  layer + i,
                                  u_minify(tex->b.b.width0, surf->u.tex.level),
                                  u_minify(tex->b.b.height0, surf->u.tex.level),
                                  1);
         svga_define_texture_level(tex, layer + i, surf->u.tex.level);
      }

      /* Sync the surface view age with the texture age */
      s->age = tex->age;

      /* If this backed surface is cached in the texture,
       * update the backed age as well.
       */
      if (tex->backed_handle == s->handle) {
         tex->backed_age = tex->age;
      }
   }

   SVGA_STATS_TIME_POP(ss->sws);
}


/**
 * If any of the render targets are in backing texture views, propagate any
 * changes to them back to the original texture.
 */
void
svga_propagate_rendertargets(struct svga_context *svga)
{
   unsigned i;

   /* Early exit if there is no backing texture views in use */
   if (!svga->state.hw_draw.has_backed_views)
      return;

   /* Note that we examine the svga->state.hw_draw.framebuffer surfaces,
    * not the svga->curr.framebuffer surfaces, because it's the former
    * surfaces which may be backing surface views (the actual render targets).
    */
   for (i = 0; i < svga->state.hw_clear.num_rendertargets; i++) {
      struct pipe_surface *s = svga->state.hw_clear.rtv[i];
      if (s) {
         svga_propagate_surface(svga, s, FALSE);
      }
   }

   if (svga->state.hw_clear.dsv) {
      svga_propagate_surface(svga, svga->state.hw_clear.dsv, FALSE);
   }
}


/**
 * Check if we should call svga_propagate_surface on the surface.
 */
boolean
svga_surface_needs_propagation(const struct pipe_surface *surf)
{
   const struct svga_surface *s = svga_surface_const(surf);
   struct svga_texture *tex = svga_texture(surf->texture);

   return s->dirty && s->handle != tex->handle;
}


static void
svga_get_sample_position(struct pipe_context *context,
                         unsigned sample_count, unsigned sample_index,
                         float *pos_out)
{
   /* We can't actually query the device to learn the sample positions.
    * These were grabbed from nvidia's driver.
    */
   static const float pos1[1][2] = {
      { 0.5, 0.5 }
   };
   static const float pos4[4][2] = {
      { 0.375000, 0.125000 },
      { 0.875000, 0.375000 },
      { 0.125000, 0.625000 },
      { 0.625000, 0.875000 }
   };
   static const float pos8[8][2] = {
      { 0.562500, 0.312500 },
      { 0.437500, 0.687500 },
      { 0.812500, 0.562500 },
      { 0.312500, 0.187500 },
      { 0.187500, 0.812500 },
      { 0.062500, 0.437500 },
      { 0.687500, 0.937500 },
      { 0.937500, 0.062500 }
   };
   static const float pos16[16][2] = {
      { 0.187500, 0.062500 },
      { 0.437500, 0.187500 },
      { 0.062500, 0.312500 },
      { 0.312500, 0.437500 },
      { 0.687500, 0.062500 },
      { 0.937500, 0.187500 },
      { 0.562500, 0.312500 },
      { 0.812500, 0.437500 },
      { 0.187500, 0.562500 },
      { 0.437500, 0.687500 },
      { 0.062500, 0.812500 },
      { 0.312500, 0.937500 },
      { 0.687500, 0.562500 },
      { 0.937500, 0.687500 },
      { 0.562500, 0.812500 },
      { 0.812500, 0.937500 }
   };
   const float (*positions)[2];

   switch (sample_count) {
   case 4:
      positions = pos4;
      break;
   case 8:
      positions = pos8;
      break;
   case 16:
      positions = pos16;
      break;
   default:
      positions = pos1;
   }

   pos_out[0] = positions[sample_index][0];
   pos_out[1] = positions[sample_index][1];
}


void
svga_init_surface_functions(struct svga_context *svga)
{
   svga->pipe.create_surface = svga_create_surface;
   svga->pipe.surface_destroy = svga_surface_destroy;
   svga->pipe.get_sample_position = svga_get_sample_position;
}
