コード例 #1
0
ファイル: sp_texture.c プロジェクト: venkatarajasekhar/Qt
/**
 * Geta pipe_transfer object which is used for moving data in/out of
 * a resource object.
 * \param pipe  rendering context
 * \param resource  the resource to transfer in/out of
 * \param level  which mipmap level
 * \param usage  bitmask of PIPE_TRANSFER_x flags
 * \param box  the 1D/2D/3D region of interest
 */
static struct pipe_transfer *
softpipe_get_transfer(struct pipe_context *pipe,
                      struct pipe_resource *resource,
                      unsigned level,
                      unsigned usage,
                      const struct pipe_box *box)
{
   struct softpipe_resource *spr = softpipe_resource(resource);
   struct softpipe_transfer *spt;

   assert(resource);
   assert(level <= resource->last_level);

   /* make sure the requested region is in the image bounds */
   assert(box->x + box->width <= u_minify(resource->width0, level));
   if (resource->target == PIPE_TEXTURE_1D_ARRAY) {
      assert(box->y + box->height <= resource->array_size);
   }
   else {
      assert(box->y + box->height <= u_minify(resource->height0, level));
      if (resource->target == PIPE_TEXTURE_2D_ARRAY) {
         assert(box->z + box->depth <= resource->array_size);
      }
      else if (resource->target == PIPE_TEXTURE_CUBE) {
         assert(box->z < 6);
      }
      else {
         assert(box->z + box->depth <= (u_minify(resource->depth0, level)));
      }
   }

   /*
    * Transfers, like other pipe operations, must happen in order, so flush the
    * context if necessary.
    */
   if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
      boolean read_only = !(usage & PIPE_TRANSFER_WRITE);
      boolean do_not_block = !!(usage & PIPE_TRANSFER_DONTBLOCK);
      if (!softpipe_flush_resource(pipe, resource,
                                   level, box->depth > 1 ? -1 : box->z,
                                   0, /* flush_flags */
                                   read_only,
                                   TRUE, /* cpu_access */
                                   do_not_block)) {
         /*
          * It would have blocked, but state tracker requested no to.
          */
         assert(do_not_block);
         return NULL;
      }
   }

   spt = CALLOC_STRUCT(softpipe_transfer);
   if (spt) {
      struct pipe_transfer *pt = &spt->base;
      enum pipe_format format = resource->format;
      const unsigned hgt = u_minify(spr->base.height0, level);
      const unsigned nblocksy = util_format_get_nblocksy(format, hgt);

      pipe_resource_reference(&pt->resource, resource);
      pt->level = level;
      pt->usage = usage;
      pt->box = *box;
      pt->stride = spr->stride[level];
      pt->layer_stride = pt->stride * nblocksy;

      spt->offset = sp_get_tex_image_offset(spr, level, box->z);
 
      spt->offset += 
         box->y / util_format_get_blockheight(format) * spt->base.stride +
         box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);

      return pt;
   }
   return NULL;
}
コード例 #2
0
ファイル: sp_texture.c プロジェクト: gqmelo/mesa
/**
 * Geta pipe_transfer object which is used for moving data in/out of
 * a resource object.
 * \param pipe  rendering context
 * \param resource  the resource to transfer in/out of
 * \param level  which mipmap level
 * \param usage  bitmask of PIPE_TRANSFER_x flags
 * \param box  the 1D/2D/3D region of interest
 */
static void *
softpipe_transfer_map(struct pipe_context *pipe,
                      struct pipe_resource *resource,
                      unsigned level,
                      unsigned usage,
                      const struct pipe_box *box,
                      struct pipe_transfer **transfer)
{
   struct sw_winsys *winsys = softpipe_screen(pipe->screen)->winsys;
   struct softpipe_resource *spr = softpipe_resource(resource);
   struct softpipe_transfer *spt;
   struct pipe_transfer *pt;
   enum pipe_format format = resource->format;
   uint8_t *map;

   assert(resource);
   assert(level <= resource->last_level);

   /* make sure the requested region is in the image bounds */
   assert(box->x + box->width <= (int) u_minify(resource->width0, level));
   if (resource->target == PIPE_TEXTURE_1D_ARRAY) {
      assert(box->y + box->height <= (int) resource->array_size);
   }
   else {
      assert(box->y + box->height <= (int) u_minify(resource->height0, level));
      if (resource->target == PIPE_TEXTURE_2D_ARRAY) {
         assert(box->z + box->depth <= (int) resource->array_size);
      }
      else if (resource->target == PIPE_TEXTURE_CUBE) {
         assert(box->z < 6);
      }
      else if (resource->target == PIPE_TEXTURE_CUBE_ARRAY) {
         assert(box->z <= (int) resource->array_size);
      }
      else {
         assert(box->z + box->depth <= (int) u_minify(resource->depth0, level));
      }
   }

   /*
    * Transfers, like other pipe operations, must happen in order, so flush the
    * context if necessary.
    */
   if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
      boolean read_only = !(usage & PIPE_TRANSFER_WRITE);
      boolean do_not_block = !!(usage & PIPE_TRANSFER_DONTBLOCK);
      if (!softpipe_flush_resource(pipe, resource,
                                   level, box->depth > 1 ? -1 : box->z,
                                   0, /* flush_flags */
                                   read_only,
                                   TRUE, /* cpu_access */
                                   do_not_block)) {
         /*
          * It would have blocked, but state tracker requested no to.
          */
         assert(do_not_block);
         return NULL;
      }
   }

   spt = CALLOC_STRUCT(softpipe_transfer);
   if (!spt)
      return NULL;

   pt = &spt->base;

   pipe_resource_reference(&pt->resource, resource);
   pt->level = level;
   pt->usage = usage;
   pt->box = *box;
   pt->stride = spr->stride[level];
   pt->layer_stride = spr->img_stride[level];

   spt->offset = sp_get_tex_image_offset(spr, level, box->z);

   spt->offset +=
         box->y / util_format_get_blockheight(format) * spt->base.stride +
         box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);

   /* resources backed by display target treated specially:
    */
   if (spr->dt) {
      map = winsys->displaytarget_map(winsys, spr->dt, usage);
   }
   else {
      map = spr->data;
   }

   if (!map) {
      pipe_resource_reference(&pt->resource, NULL);
      FREE(spt);
      return NULL;
   }

   *transfer = pt;
   return map + spt->offset;
}