Exemplo n.º 1
0
/**
 * Copy an image between textures with the vgpu10 CopyRegion command.
 */
static void
copy_region_vgpu10(struct svga_context *svga, struct pipe_resource *src_tex,
                    unsigned src_x, unsigned src_y, unsigned src_z,
                    unsigned src_level, unsigned src_layer_face,
                    struct pipe_resource *dst_tex,
                    unsigned dst_x, unsigned dst_y, unsigned dst_z,
                    unsigned dst_level, unsigned dst_layer_face,
                    unsigned width, unsigned height, unsigned depth)
{
   uint32 srcSubResource, dstSubResource;
   struct svga_texture *dtex, *stex;

   stex = svga_texture(src_tex);
   dtex = svga_texture(dst_tex);

   svga_surfaces_flush(svga);

   srcSubResource = src_layer_face * (src_tex->last_level + 1) + src_level;
   dstSubResource = dst_layer_face * (dst_tex->last_level + 1) + dst_level;

   svga_texture_copy_region(svga, stex->handle, srcSubResource,
                            src_x, src_y, src_z,
                            dtex->handle, dstSubResource,
                            dst_x, dst_y, dst_z,
                            width, height, depth);

   /* Mark the texture subresource as defined. */
   svga_define_texture_level(dtex, dst_layer_face, dst_level);

   /* Mark the texture subresource as rendered-to. */
   svga_set_texture_rendered_to(dtex, dst_layer_face, dst_level);
}
Exemplo n.º 2
0
/**
 * Check whether we can blit using the intra_surface_copy command.
 */
static bool
can_blit_via_intra_surface_copy(struct svga_context *svga,
                                const struct pipe_blit_info *blit_info)
{
   struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
   struct svga_texture *dtex, *stex;

   if (!svga_have_vgpu10(svga))
      return false;

   /* src surface cannot be multisample */
   if (blit_info->src.resource->nr_samples > 1)
      return false;

   if (!sws->have_intra_surface_copy)
      return false;

   if (svga->render_condition && blit_info->render_condition_enable)
      return false;

   if (blit_info->src.level != blit_info->dst.level)
      return false;

   if (has_layer_face_index_in_z(blit_info->src.resource->target)){
      if (blit_info->src.box.z != blit_info->dst.box.z)
         return false;
   }

   stex = svga_texture(blit_info->src.resource);
   dtex = svga_texture(blit_info->dst.resource);

   return (stex->handle == dtex->handle);
}
Exemplo n.º 3
0
static boolean
svga_texture_get_handle(struct pipe_screen *screen,
                        struct pipe_resource *texture,
                        struct winsys_handle *whandle)
{
    struct svga_winsys_screen *sws = svga_winsys_screen(texture->screen);
    unsigned stride;

    assert(svga_texture(texture)->key.cachable == 0);
    svga_texture(texture)->key.cachable = 0;
    stride = util_format_get_nblocksx(texture->format, texture->width0) *
             util_format_get_blocksize(texture->format);
    return sws->surface_get_handle(sws, svga_texture(texture)->handle, stride, whandle);
}
Exemplo n.º 4
0
static INLINE void 
svga_mark_surface_dirty(struct pipe_surface *surf)
{
   struct svga_surface *s = svga_surface(surf);

   if (!s->dirty) {
      struct svga_texture *tex = svga_texture(surf->texture);

      s->dirty = TRUE;

      if (s->handle == tex->handle) {
         /* hmm so 3d textures always have all their slices marked ? */
         if (surf->texture->target == PIPE_TEXTURE_CUBE)
            svga_define_texture_level(tex, surf->u.tex.first_layer,
                                      surf->u.tex.level);
         else
            svga_define_texture_level(tex, 0, 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.
       */
      svga_age_texture_view(tex, surf->u.tex.level);
   }
}
Exemplo n.º 5
0
static void
svga_texture_destroy(struct pipe_screen *screen,
		     struct pipe_resource *pt)
{
   struct svga_screen *ss = svga_screen(screen);
   struct svga_texture *tex = svga_texture(pt);

   ss->texture_timestamp++;

   svga_sampler_view_reference(&tex->cached_view, NULL);

   /*
     DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
   */
   SVGA_DBG(DEBUG_DMA, "unref sid %p (texture)\n", tex->handle);
   svga_screen_surface_destroy(ss, &tex->key, &tex->handle);

   ss->hud.total_resource_bytes -= tex->size;

   FREE(tex->defined);
   FREE(tex->rendered_to);
   FREE(tex);

   assert(ss->hud.num_resources > 0);
   if (ss->hud.num_resources > 0)
      ss->hud.num_resources--;
}
Exemplo n.º 6
0
static void
svga_texture_transfer_destroy(struct pipe_context *pipe,
                              struct pipe_transfer *transfer)
{
    struct svga_context *svga = svga_context(pipe);
    struct svga_texture *tex = svga_texture(transfer->resource);
    struct svga_screen *ss = svga_screen(pipe->screen);
    struct svga_winsys_screen *sws = ss->sws;
    struct svga_transfer *st = svga_transfer(transfer);

    if (st->base.usage & PIPE_TRANSFER_WRITE) {
        SVGA3dSurfaceDMAFlags flags;

        memset(&flags, 0, sizeof flags);
        if (transfer->usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
            flags.discard = TRUE;
        }
        if (transfer->usage & PIPE_TRANSFER_UNSYNCHRONIZED) {
            flags.unsynchronized = TRUE;
        }

        svga_transfer_dma(svga, st, SVGA3D_WRITE_HOST_VRAM, flags);
        ss->texture_timestamp++;
        tex->view_age[transfer->level] = ++(tex->age);
        if (transfer->resource->target == PIPE_TEXTURE_CUBE)
            tex->defined[transfer->box.z][transfer->level] = TRUE;
        else
            tex->defined[0][transfer->level] = TRUE;
    }

    pipe_resource_reference(&st->base.resource, NULL);
    FREE(st->swbuf);
    sws->buffer_destroy(sws, st->hwbuf);
    FREE(st);
}
Exemplo n.º 7
0
/**
 * Determine if we need to read back a texture image before mapping it.
 */
static boolean
need_tex_readback(struct pipe_transfer *transfer)
{
   struct svga_texture *t = svga_texture(transfer->resource);

   if (transfer->usage & PIPE_TRANSFER_READ)
      return TRUE;

   if ((transfer->usage & PIPE_TRANSFER_WRITE) &&
       ((transfer->usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) == 0)) {
      unsigned face;

      if (transfer->resource->target == PIPE_TEXTURE_CUBE) {
         assert(transfer->box.depth == 1);
         face = transfer->box.z;
      }
      else {
         face = 0;
      }
      if (svga_was_texture_rendered_to(t, face, transfer->level)) {
         return TRUE;
      }
   }

   return FALSE;
}
Exemplo n.º 8
0
/**
 * Check if we should call svga_propagate_surface on the surface.
 */
boolean
svga_surface_needs_propagation(struct pipe_surface *surf)
{
   struct svga_surface *s = svga_surface(surf);
   struct svga_texture *tex = svga_texture(surf->texture);

   return s->dirty && s->handle != tex->handle;
}
/**
 * unmap direct map transfer request
 */
static void
svga_texture_transfer_unmap_direct(struct svga_context *svga,
                                   struct svga_transfer *st)
{
   struct pipe_transfer *transfer = &st->base;
   struct svga_texture *tex = svga_texture(transfer->resource);

   svga_texture_surface_unmap(svga, transfer);

   /* Now send an update command to update the content in the backend. */
   if (st->base.usage & PIPE_TRANSFER_WRITE) {
      struct svga_winsys_surface *surf = tex->handle;
      enum pipe_error ret;

      assert(svga_have_gb_objects(svga));

      /* update the effected region */
      SVGA3dBox box = st->box;
      unsigned nlayers;

      switch (tex->b.b.target) {
      case PIPE_TEXTURE_2D_ARRAY:
      case PIPE_TEXTURE_CUBE_ARRAY:
      case PIPE_TEXTURE_1D_ARRAY:
         nlayers = box.d;
         box.d = 1;
         break;
      default:
         nlayers = 1;
         break;
      }


      if (0)
         debug_printf("%s %d, %d, %d  %d x %d x %d\n",
                      __FUNCTION__,
                      box.x, box.y, box.z,
                      box.w, box.h, box.d);

      if (svga_have_vgpu10(svga)) {
         unsigned i;

         for (i = 0; i < nlayers; i++) {
            ret = update_image_vgpu10(svga, surf, &box,
                                      st->slice + i, transfer->level,
                                      tex->b.b.last_level + 1);
            assert(ret == PIPE_OK);
         }
      } else {
         assert(nlayers == 1);
         ret = update_image_vgpu9(svga, surf, &box, st->slice, transfer->level);
         assert(ret == PIPE_OK);
      }
      (void) ret;
   }
}
Exemplo n.º 10
0
/** Get resource handle for a texture or buffer */
static inline struct svga_winsys_surface *
svga_resource_handle(struct pipe_resource *res)
{
   if (res->target == PIPE_BUFFER) {
      return svga_buffer(res)->handle;
   }
   else {
      return svga_texture(res)->handle;
   }
}
Exemplo n.º 11
0
enum pipe_error
SVGA3D_SurfaceDMA(struct svga_winsys_context *swc,
                  struct svga_transfer *st,         // IN
                  SVGA3dTransferType transfer,      // IN
                  const SVGA3dCopyBox *boxes,       // IN
                  uint32 numBoxes,                  // IN
                  SVGA3dSurfaceDMAFlags flags)      // IN
{
   struct svga_texture *texture = svga_texture(st->base.resource); 
   SVGA3dCmdSurfaceDMA *cmd;
   SVGA3dCmdSurfaceDMASuffix *pSuffix;
   uint32 boxesSize = sizeof *boxes * numBoxes;
   unsigned region_flags;
   unsigned surface_flags;
   
   if(transfer == SVGA3D_WRITE_HOST_VRAM) {
      region_flags = SVGA_RELOC_READ;
      surface_flags = SVGA_RELOC_WRITE;
   }
   else if(transfer == SVGA3D_READ_HOST_VRAM) {
      region_flags = SVGA_RELOC_WRITE;
      surface_flags = SVGA_RELOC_READ;
   }
   else {
      assert(0);
      return PIPE_ERROR_BAD_INPUT;
   }
   
   cmd = SVGA3D_FIFOReserve(swc,
                            SVGA_3D_CMD_SURFACE_DMA,
                            sizeof *cmd + boxesSize + sizeof *pSuffix,
                            2);
   if(!cmd)
      return PIPE_ERROR_OUT_OF_MEMORY;

   swc->region_relocation(swc, &cmd->guest.ptr, st->hwbuf, 0, region_flags);
   cmd->guest.pitch = st->base.stride;

   swc->surface_relocation(swc, &cmd->host.sid, texture->handle, surface_flags);
   cmd->host.face = st->face; /* PIPE_TEX_FACE_* and SVGA3D_CUBEFACE_* match */
   cmd->host.mipmap = st->base.level;

   cmd->transfer = transfer;

   memcpy(&cmd[1], boxes, boxesSize);
   
   pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + boxesSize);
   pSuffix->suffixSize = sizeof *pSuffix;
   pSuffix->maximumOffset = st->hw_nblocksy*st->base.stride;
   pSuffix->flags = flags;

   swc->commit(swc);

   return PIPE_OK;
}
Exemplo n.º 12
0
/**
 * Check whether we can blit using the surface_copy command.
 */
static bool
can_blit_via_surface_copy(struct svga_context *svga,
                          const struct pipe_blit_info *blit_info)
{
   struct svga_texture *dtex, *stex;

   /* Mimic the format tests in util_can_blit_via_copy_region(), but
    * skip the other tests that have already been performed.
    */
   if (blit_info->src.format != blit_info->dst.format) {
      const struct util_format_description *src_desc, *dst_desc;

      src_desc = util_format_description(blit_info->src.resource->format);
      dst_desc = util_format_description(blit_info->dst.resource->format);

      if (blit_info->src.resource->format != blit_info->src.format ||
          blit_info->dst.resource->format != blit_info->dst.format ||
          !util_is_format_compatible(src_desc, dst_desc))
         return false;
   }

   if (svga->render_condition && blit_info->render_condition_enable)
      return false;

   /* can't copy between different resource types */
   if (svga_resource_type(blit_info->src.resource->target) !=
       svga_resource_type(blit_info->dst.resource->target))
      return false;

   stex = svga_texture(blit_info->src.resource);
   dtex = svga_texture(blit_info->dst.resource);

   if (stex->handle == dtex->handle)
      return false;

   /*
    * This is what we've been using before, but it can probably be
    * relaxed. The device checks are less stringent.
    */
   return (stex->b.b.format == dtex->b.b.format);
}
Exemplo n.º 13
0
/**
 * Determine if we need to read back a texture image before mapping it.
 */
static inline boolean
need_tex_readback(struct svga_transfer *st)
{
   if (st->base.usage & PIPE_TRANSFER_READ)
      return TRUE;

   if ((st->base.usage & PIPE_TRANSFER_WRITE) &&
       ((st->base.usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) == 0)) {
      return svga_was_texture_rendered_to(svga_texture(st->base.resource),
                                          st->slice, st->base.level);
   }

   return FALSE;
}
Exemplo n.º 14
0
/**
 * The state tracker implements some resource copies with blits (for
 * GL_ARB_copy_image).  This function checks if we should really do the blit
 * with a VGPU10 CopyRegion command or software fallback (for incompatible
 * src/dst formats).
 */
static bool
can_blit_via_copy_region_vgpu10(struct svga_context *svga,
                                const struct pipe_blit_info *blit_info)
{
   struct svga_texture *dtex, *stex;

   /* can't copy between different resource types */
   if (svga_resource_type(blit_info->src.resource->target) !=
       svga_resource_type(blit_info->dst.resource->target))
      return false;

   stex = svga_texture(blit_info->src.resource);
   dtex = svga_texture(blit_info->dst.resource);

   if (!svga_have_vgpu10(svga))
      return false;

   if (stex->handle == dtex->handle)
      return false;

   return formats_compatible(svga_screen(svga->pipe.screen),
                             stex->key.format,
                             dtex->key.format);
}
Exemplo n.º 15
0
static void
svga_tex_surface_destroy(struct pipe_surface *surf)
{
   struct svga_surface *s = svga_surface(surf);
   struct svga_texture *t = svga_texture(surf->texture);
   struct svga_screen *ss = svga_screen(surf->texture->screen);

   if(s->handle != t->handle) {
      SVGA_DBG(DEBUG_DMA, "unref sid %p (tex surface)\n", s->handle);
      svga_screen_surface_destroy(ss, &s->key, &s->handle);
   }

   pipe_resource_reference(&surf->texture, NULL);
   FREE(surf);
}
Exemplo n.º 16
0
static INLINE void
svga_transfer_dma_band(struct svga_context *svga,
                       struct svga_transfer *st,
                       SVGA3dTransferType transfer,
                       unsigned y, unsigned h, unsigned srcy,
                       SVGA3dSurfaceDMAFlags flags)
{
    struct svga_texture *texture = svga_texture(st->base.resource);
    SVGA3dCopyBox box;
    enum pipe_error ret;

    box.x = st->base.box.x;
    box.y = y;
    box.z = st->base.box.z;
    box.w = st->base.box.width;
    box.h = h;
    box.d = 1;
    box.srcx = 0;
    box.srcy = srcy;
    box.srcz = 0;

    if (st->base.resource->target == PIPE_TEXTURE_CUBE) {
        st->face = st->base.box.z;
        box.z = 0;
    }
    else
        st->face = 0;

    SVGA_DBG(DEBUG_DMA, "dma %s sid %p, face %u, (%u, %u, %u) - (%u, %u, %u), %ubpp\n",
             transfer == SVGA3D_WRITE_HOST_VRAM ? "to" : "from",
             texture->handle,
             st->face,
             st->base.box.x,
             y,
             box.z,
             st->base.box.x + st->base.box.width,
             y + h,
             box.z + 1,
             util_format_get_blocksize(texture->b.b.format) * 8 /
             (util_format_get_blockwidth(texture->b.b.format)*util_format_get_blockheight(texture->b.b.format)));

    ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags);
    if(ret != PIPE_OK) {
        svga_context_flush(svga, NULL);
        ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags);
        assert(ret == PIPE_OK);
    }
}
Exemplo n.º 17
0
static void
svga_transfer_dma_band(struct svga_context *svga,
                       struct svga_transfer *st,
                       SVGA3dTransferType transfer,
                       unsigned x, unsigned y, unsigned z,
                       unsigned w, unsigned h, unsigned d,
                       unsigned srcx, unsigned srcy, unsigned srcz,
                       SVGA3dSurfaceDMAFlags flags)
{
   struct svga_texture *texture = svga_texture(st->base.resource);
   SVGA3dCopyBox box;
   enum pipe_error ret;

   assert(!st->use_direct_map);

   box.x = x;
   box.y = y;
   box.z = z;
   box.w = w;
   box.h = h;
   box.d = d;
   box.srcx = srcx;
   box.srcy = srcy;
   box.srcz = srcz;

   SVGA_DBG(DEBUG_DMA, "dma %s sid %p, face %u, (%u, %u, %u) - "
            "(%u, %u, %u), %ubpp\n",
            transfer == SVGA3D_WRITE_HOST_VRAM ? "to" : "from",
            texture->handle,
            st->slice,
            x,
            y,
            z,
            x + w,
            y + h,
            z + 1,
            util_format_get_blocksize(texture->b.b.format) * 8 /
            (util_format_get_blockwidth(texture->b.b.format)
             * util_format_get_blockheight(texture->b.b.format)));

   ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags);
   if (ret != PIPE_OK) {
      svga_context_flush(svga, NULL);
      ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags);
      assert(ret == PIPE_OK);
   }
}
Exemplo n.º 18
0
static INLINE void 
svga_mark_surface_dirty(struct pipe_surface *surf)
{
   struct svga_surface *s = svga_surface(surf);

   if(!s->dirty) {
      struct svga_texture *tex = svga_texture(surf->texture);

      s->dirty = TRUE;

      if (s->handle == tex->handle)
         tex->defined[surf->face][surf->level] = TRUE;
      else {
         /* this will happen later in svga_propagate_surface */
      }
   }
}
Exemplo n.º 19
0
void
svga_destroy_sampler_view_priv(struct svga_sampler_view *v)
{
   struct svga_texture *tex = svga_texture(v->texture);

   if (v->handle != tex->handle) {
      struct svga_screen *ss = svga_screen(v->texture->screen);
      SVGA_DBG(DEBUG_DMA, "unref sid %p (sampler view)\n", v->handle);
      svga_screen_surface_destroy(ss, &v->key, &v->handle);
   }

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

   FREE(v);
}
Exemplo n.º 20
0
/**
 * Copy when src texture and dst texture are same with IntraSurfaceCopy
 * command.
 */
static void
intra_surface_copy(struct svga_context *svga, struct pipe_resource *tex,
                    unsigned src_x, unsigned src_y, unsigned src_z,
                    unsigned level, unsigned layer_face,
                    unsigned dst_x, unsigned dst_y, unsigned dst_z,
                    unsigned width, unsigned height, unsigned depth)
{
   enum pipe_error ret;
   SVGA3dCopyBox box;
   struct svga_texture *stex;

   /*
    * Makes sure we have flushed all buffered draw operations and also
    * synchronizes all surfaces with any emulated surface views.
    */
   svga_surfaces_flush(svga);

   stex = svga_texture(tex);

   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;

   ret = SVGA3D_vgpu10_IntraSurfaceCopy(svga->swc,
                                 stex->handle, level, layer_face,  &box);
   if (ret != PIPE_OK) {
      svga_context_flush(svga, NULL);
   ret = SVGA3D_vgpu10_IntraSurfaceCopy(svga->swc,
                                 stex->handle, level, layer_face, &box);
      assert(ret == PIPE_OK);
   }

   /* Mark the texture subresource as rendered-to. */
   svga_set_texture_rendered_to(stex, layer_face, level);
}
Exemplo n.º 21
0
static void
svga_texture_transfer_unmap(struct pipe_context *pipe,
                            struct pipe_transfer *transfer)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_screen *ss = svga_screen(pipe->screen);
   struct svga_winsys_screen *sws = ss->sws;
   struct svga_transfer *st = svga_transfer(transfer);
   struct svga_texture *tex = svga_texture(transfer->resource);

   SVGA_STATS_TIME_PUSH(sws, SVGA_STATS_TIME_TEXTRANSFERUNMAP);

   if (!st->use_direct_map) {
      svga_texture_transfer_unmap_dma(svga, st);
   }
   else if (st->upload.buf) {
      svga_texture_transfer_unmap_upload(svga, st);
   }
   else {
      svga_texture_transfer_unmap_direct(svga, st);
   }

   if (st->base.usage & PIPE_TRANSFER_WRITE) {
      svga->hud.num_resource_updates++;

      /* Mark the texture level as dirty */
      ss->texture_timestamp++;
      svga_age_texture_view(tex, transfer->level);
      if (transfer->resource->target == PIPE_TEXTURE_CUBE)
         svga_define_texture_level(tex, st->slice, transfer->level);
      else
         svga_define_texture_level(tex, 0, transfer->level);
   }

   pipe_resource_reference(&st->base.resource, NULL);
   FREE(st);
   SVGA_STATS_TIME_POP(sws);
   (void) sws;
}
static unsigned int
svga_texture_is_referenced( struct pipe_context *pipe,
			    struct pipe_resource *texture,
			    unsigned face, unsigned level)
{
   struct svga_texture *tex = svga_texture(texture);
   struct svga_screen *ss = svga_screen(pipe->screen);

   /**
    * The screen does not cache texture writes.
    */

   if (!tex->handle || ss->sws->surface_is_flushed(ss->sws, tex->handle))
      return PIPE_UNREFERENCED;

   /**
    * sws->surface_is_flushed() does not distinguish between read references
    * and write references. So assume a reference is both.
    */

   return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
}
static void
svga_texture_transfer_destroy(struct pipe_context *pipe,
			      struct pipe_transfer *transfer)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_texture *tex = svga_texture(transfer->resource);
   struct svga_screen *ss = svga_screen(pipe->screen);
   struct svga_winsys_screen *sws = ss->sws;
   struct svga_transfer *st = svga_transfer(transfer);

   if (st->base.usage & PIPE_TRANSFER_WRITE) {
      svga_transfer_dma(svga, st, SVGA3D_WRITE_HOST_VRAM);
      ss->texture_timestamp++;
      tex->view_age[transfer->sr.level] = ++(tex->age);
      tex->defined[transfer->sr.face][transfer->sr.level] = TRUE;
   }

   pipe_resource_reference(&st->base.resource, NULL);
   FREE(st->swbuf);
   sws->buffer_destroy(sws, st->hwbuf);
   FREE(st);
}
Exemplo n.º 24
0
/**
 * Unmap a GB texture surface.
 */
static void
svga_texture_surface_unmap(struct svga_context *svga,
                           struct pipe_transfer *transfer)
{
   struct svga_winsys_surface *surf = svga_texture(transfer->resource)->handle;
   struct svga_winsys_context *swc = svga->swc;
   boolean rebind;

   assert(surf);

   swc->surface_unmap(swc, surf, &rebind);
   if (rebind) {
      enum pipe_error ret;
      ret = SVGA3D_BindGBSurface(swc, surf);
      if (ret != PIPE_OK) {
         /* flush and retry */
         svga_context_flush(svga, NULL);
         ret = SVGA3D_BindGBSurface(swc, surf);
         assert(ret == PIPE_OK);
      }
   }
}
Exemplo n.º 25
0
void
svga_validate_sampler_view(struct svga_context *svga,
                           struct svga_sampler_view *v)
{
   struct svga_texture *tex = svga_texture(v->texture);
   unsigned numFaces;
   unsigned age = 0;
   int i;
   unsigned k;

   assert(svga);
   assert(!svga_have_vgpu10(svga));

   if (v->handle == tex->handle)
      return;

   age = tex->age;

   if (tex->b.b.target == PIPE_TEXTURE_CUBE)
      numFaces = 6;
   else
      numFaces = 1;

   for (i = v->min_lod; i <= v->max_lod; i++) {
      for (k = 0; k < numFaces; k++) {
         assert(i < ARRAY_SIZE(tex->view_age));
         if (v->age < tex->view_age[i])
            svga_texture_copy_handle(svga,
                                     tex->handle, 0, 0, 0, i, k,
                                     v->handle, 0, 0, 0, i - v->min_lod, k,
                                     u_minify(tex->b.b.width0, i),
                                     u_minify(tex->b.b.height0, i),
                                     u_minify(tex->b.b.depth0, i));
      }
   }

   v->age = age;
}
Exemplo n.º 26
0
/**
 * 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_surface *bs = s->backed;

   if (!bs) {
      struct svga_texture *tex = svga_texture(s->base.texture);
      struct pipe_surface *backed_view;

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

      bs = svga_surface(backed_view);
      s->backed = bs;
   }

   svga_mark_surface_dirty(&bs->base);

   return bs;
}
Exemplo n.º 27
0
/**
 * 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)
{
   struct svga_surface *s = svga_surface(surf);
   struct svga_texture *tex = svga_texture(surf->texture);
   struct svga_screen *ss = svga_screen(surf->texture->screen);
   unsigned zslice, face;

   if (!s->dirty)
      return;

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

   s->dirty = FALSE;
   ss->texture_timestamp++;
   svga_age_texture_view(tex, surf->u.tex.level);

   if (s->handle != tex->handle) {
      SVGA_DBG(DEBUG_VIEWS,
               "svga: Surface propagate: tex %p, level %u, from %p\n",
               tex, surf->u.tex.level, surf);
      svga_texture_copy_handle(svga,
                               s->handle, 0, 0, 0, s->real_level, s->real_face,
                               tex->handle, 0, 0, zslice, surf->u.tex.level, face,
                               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, face, surf->u.tex.level);
   }
}
Exemplo n.º 28
0
/**
 * Progagate any changes from surfaces to texture.
 * pipe is optional context to inline the blit command in.
 */
void
svga_propagate_surface(struct pipe_context *pipe, struct pipe_surface *surf)
{
   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;

   s->dirty = FALSE;
   ss->texture_timestamp++;
   tex->view_age[surf->level] = ++(tex->age);

   if (s->handle != tex->handle) {
      SVGA_DBG(DEBUG_VIEWS, "svga: Surface propagate: tex %p, level %u, from %p\n", tex, surf->level, surf);
      svga_texture_copy_handle(svga_context(pipe),
                               s->handle, 0, 0, 0, s->real_level, s->real_face,
                               tex->handle, 0, 0, surf->zslice, surf->level, surf->face,
                               u_minify(tex->b.b.width0, surf->level),
                               u_minify(tex->b.b.height0, surf->level), 1);
      tex->defined[surf->face][surf->level] = TRUE;
   }
}
Exemplo n.º 29
0
static void
svga_transfer_dma(struct svga_context *svga,
                  struct svga_transfer *st,
                  SVGA3dTransferType transfer,
                  SVGA3dSurfaceDMAFlags flags)
{
   struct svga_texture *texture = svga_texture(st->base.resource);
   struct svga_screen *screen = svga_screen(texture->b.b.screen);
   struct svga_winsys_screen *sws = screen->sws;
   struct pipe_fence_handle *fence = NULL;

   assert(!st->use_direct_map);

   if (transfer == SVGA3D_READ_HOST_VRAM) {
      SVGA_DBG(DEBUG_PERF, "%s: readback transfer\n", __FUNCTION__);
   }

   /* Ensure any pending operations on host surfaces are queued on the command
    * buffer first.
    */
   svga_surfaces_flush( svga );

   if (!st->swbuf) {
      /* Do the DMA transfer in a single go */
      svga_transfer_dma_band(svga, st, transfer,
                             st->base.box.y, st->base.box.height, 0,
                             flags);

      if (transfer == SVGA3D_READ_HOST_VRAM) {
         svga_context_flush(svga, &fence);
         sws->fence_finish(sws, fence, 0);
         sws->fence_reference(sws, &fence, NULL);
      }
   }
   else {
      int y, h, srcy;
      unsigned blockheight =
         util_format_get_blockheight(st->base.resource->format);

      h = st->hw_nblocksy * blockheight;
      srcy = 0;

      for (y = 0; y < st->base.box.height; y += h) {
         unsigned offset, length;
         void *hw, *sw;

         if (y + h > st->base.box.height)
            h = st->base.box.height - y;

         /* Transfer band must be aligned to pixel block boundaries */
         assert(y % blockheight == 0);
         assert(h % blockheight == 0);

         offset = y * st->base.stride / blockheight;
         length = h * st->base.stride / blockheight;

         sw = (uint8_t *) st->swbuf + offset;

         if (transfer == SVGA3D_WRITE_HOST_VRAM) {
            unsigned usage = PIPE_TRANSFER_WRITE;

            /* Wait for the previous DMAs to complete */
            /* TODO: keep one DMA (at half the size) in the background */
            if (y) {
               svga_context_flush(svga, NULL);
               usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
            }

            hw = sws->buffer_map(sws, st->hwbuf, usage);
            assert(hw);
            if (hw) {
               memcpy(hw, sw, length);
               sws->buffer_unmap(sws, st->hwbuf);
            }
         }

         svga_transfer_dma_band(svga, st, transfer, y, h, srcy, flags);

         /*
          * Prevent the texture contents to be discarded on the next band
          * upload.
          */
         flags.discard = FALSE;

         if (transfer == SVGA3D_READ_HOST_VRAM) {
            svga_context_flush(svga, &fence);
            sws->fence_finish(sws, fence, 0);

            hw = sws->buffer_map(sws, st->hwbuf, PIPE_TRANSFER_READ);
            assert(hw);
            if (hw) {
               memcpy(sw, hw, length);
               sws->buffer_unmap(sws, st->hwbuf);
            }
         }
      }
   }
}
Exemplo n.º 30
0
static void
svga_texture_transfer_unmap(struct pipe_context *pipe,
			    struct pipe_transfer *transfer)
{
   struct svga_context *svga = svga_context(pipe);
   struct svga_screen *ss = svga_screen(pipe->screen);
   struct svga_winsys_screen *sws = ss->sws;
   struct svga_transfer *st = svga_transfer(transfer);
   struct svga_texture *tex = svga_texture(transfer->resource);

   if (!st->swbuf) {
      if (st->use_direct_map) {
         svga_texture_surface_unmap(svga, transfer);
      }
      else {
         sws->buffer_unmap(sws, st->hwbuf);
      }
   }

   if (!st->use_direct_map && (st->base.usage & PIPE_TRANSFER_WRITE)) {
      /* Use DMA to transfer texture data */
      SVGA3dSurfaceDMAFlags flags;

      memset(&flags, 0, sizeof flags);
      if (transfer->usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
         flags.discard = TRUE;
      }
      if (transfer->usage & PIPE_TRANSFER_UNSYNCHRONIZED) {
         flags.unsynchronized = TRUE;
      }

      svga_transfer_dma(svga, st, SVGA3D_WRITE_HOST_VRAM, flags);
   } else if (transfer->usage & PIPE_TRANSFER_WRITE) {
      struct svga_winsys_surface *surf =
	 svga_texture(transfer->resource)->handle;
      SVGA3dBox box;
      enum pipe_error ret;

      assert(svga_have_gb_objects(svga));

      /* update the effected region */
      box.x = transfer->box.x;
      box.y = transfer->box.y;
      switch (tex->b.b.target) {
      case PIPE_TEXTURE_CUBE:
      case PIPE_TEXTURE_2D_ARRAY:
         box.z = 0;
         break;
      case PIPE_TEXTURE_1D_ARRAY:
         box.y = box.z = 0;
         break;
      default:
         box.z = transfer->box.z;
         break;
      }
      box.w = transfer->box.width;
      box.h = transfer->box.height;
      box.d = transfer->box.depth;

      if (0)
         debug_printf("%s %d, %d, %d  %d x %d x %d\n",
                      __FUNCTION__,
                      box.x, box.y, box.z,
                      box.w, box.h, box.d);

      if (svga_have_vgpu10(svga)) {
         ret = update_image_vgpu10(svga, surf, &box, st->slice, transfer->level,
                                   tex->b.b.last_level + 1);
      } else {
         ret = update_image_vgpu9(svga, surf, &box, st->slice, transfer->level);
      }

      assert(ret == PIPE_OK);
      (void) ret;
   }

   ss->texture_timestamp++;
   svga_age_texture_view(tex, transfer->level);
   if (transfer->resource->target == PIPE_TEXTURE_CUBE)
      svga_define_texture_level(tex, st->slice, transfer->level);
   else
      svga_define_texture_level(tex, 0, transfer->level);

   pipe_resource_reference(&st->base.resource, NULL);

   FREE(st->swbuf);
   if (!st->use_direct_map) {
      sws->buffer_destroy(sws, st->hwbuf);
   }
   FREE(st);
}