예제 #1
0
파일: i915_texture.c 프로젝트: aosm/X11libs
/**
 * Special case to deal with scanout textures.
 */
static boolean
i915_scanout_layout(struct i915_texture *tex)
{
   struct pipe_texture *pt = &tex->base;

   if (pt->last_level > 0 || util_format_get_blocksize(pt->format) != 4)
      return FALSE;

   i915_miptree_set_level_info(tex, 0, 1,
                               pt->width0,
                               pt->height0,
                               1);
   i915_miptree_set_image_offset(tex, 0, 0, 0, 0);

   if (pt->width0 >= 240) {
      tex->stride = power_of_two(util_format_get_stride(pt->format, pt->width0));
      tex->total_nblocksy = align(util_format_get_nblocksy(pt->format, pt->height0), 8);
      tex->hw_tiled = INTEL_TILE_X;
   } else if (pt->width0 == 64 && pt->height0 == 64) {
      tex->stride = power_of_two(util_format_get_stride(pt->format, pt->width0));
      tex->total_nblocksy = align(util_format_get_nblocksy(pt->format, pt->height0), 8);
   } else {
      return FALSE;
   }

   debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
      pt->width0, pt->height0, util_format_get_blocksize(pt->format),
      tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy);

   return TRUE;
}
예제 #2
0
파일: i915_texture.c 프로젝트: aosm/X11libs
static void
i915_miptree_layout_2d(struct i915_texture *tex)
{
   struct pipe_texture *pt = &tex->base;
   unsigned level;
   unsigned width = pt->width0;
   unsigned height = pt->height0;
   unsigned nblocksy = util_format_get_nblocksy(pt->format, pt->width0);

   /* used for scanouts that need special layouts */
   if (pt->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
      if (i915_scanout_layout(tex))
         return;

   /* for shared buffers we use something very like scanout */
   if (pt->tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
      if (i915_display_target_layout(tex))
         return;

   tex->stride = align(util_format_get_stride(pt->format, pt->width0), 4);
   tex->total_nblocksy = 0;

   for (level = 0; level <= pt->last_level; level++) {
      i915_miptree_set_level_info(tex, level, 1, width, height, 1);
      i915_miptree_set_image_offset(tex, level, 0, 0, tex->total_nblocksy);

      nblocksy = align(MAX2(2, nblocksy), 2);

      tex->total_nblocksy += nblocksy;

      width = u_minify(width, 1);
      height = u_minify(height, 1);
      nblocksy = util_format_get_nblocksy(pt->format, height);
   }
}
static void r600_compressed_to_blittable(struct pipe_resource *tex,
				   unsigned level,
				   struct texture_orig_info *orig)
{
	struct r600_resource_texture *rtex = (struct r600_resource_texture*)tex;
	struct r600_screen *rscreen = (struct r600_screen *)tex->screen;
	unsigned pixsize = util_format_get_blocksize(rtex->real_format);
	int new_format;
	int new_height, new_width;

	orig->format = tex->format;
	orig->width0 = tex->width0;
	orig->height0 = tex->height0;
	orig->npix0_x = rtex->surface.level[0].npix_x;
	orig->npix0_y = rtex->surface.level[0].npix_y;
	orig->npix_x = rtex->surface.level[level].npix_x;
	orig->npix_y = rtex->surface.level[level].npix_y;

	if (pixsize == 8)
		new_format = PIPE_FORMAT_R16G16B16A16_UINT; /* 64-bit block */
	else
		new_format = PIPE_FORMAT_R32G32B32A32_UINT; /* 128-bit block */

	new_width = util_format_get_nblocksx(tex->format, orig->width0);
	new_height = util_format_get_nblocksy(tex->format, orig->height0);

	tex->width0 = new_width;
	tex->height0 = new_height;
	tex->format = new_format;
	rtex->surface.level[0].npix_x = util_format_get_nblocksx(orig->format, orig->npix0_x);
	rtex->surface.level[0].npix_y = util_format_get_nblocksy(orig->format, orig->npix0_y);
	rtex->surface.level[level].npix_x = util_format_get_nblocksx(orig->format, orig->npix_x);
	rtex->surface.level[level].npix_y = util_format_get_nblocksy(orig->format, orig->npix_y);
}
예제 #4
0
static INLINE void
define_rect(struct pipe_resource *pt, unsigned level, unsigned z,
            unsigned x, unsigned y, unsigned w, unsigned h,
            struct nv30_rect *rect)
{
   struct nv30_miptree *mt = nv30_miptree(pt);
   struct nv30_miptree_level *lvl = &mt->level[level];

   rect->w = u_minify(pt->width0, level) << mt->ms_x;
   rect->w = util_format_get_nblocksx(pt->format, rect->w);
   rect->h = u_minify(pt->height0, level) << mt->ms_y;
   rect->h = util_format_get_nblocksy(pt->format, rect->h);
   rect->d = 1;
   rect->z = 0;
   if (mt->swizzled) {
      if (pt->target == PIPE_TEXTURE_3D) {
         rect->d = u_minify(pt->depth0, level);
         rect->z = z; z = 0;
      }
      rect->pitch = 0;
   } else {
      rect->pitch = lvl->pitch;
   }

   rect->bo     = mt->base.bo;
   rect->domain = NOUVEAU_BO_VRAM;
   rect->offset = layer_offset(pt, level, z);
   rect->cpp    = util_format_get_blocksize(pt->format);

   rect->x0     = util_format_get_nblocksx(pt->format, x) << mt->ms_x;
   rect->y0     = util_format_get_nblocksy(pt->format, y) << mt->ms_y;
   rect->x1     = rect->x0 + (w << mt->ms_x);
   rect->y1     = rect->y0 + (h << mt->ms_y);
}
static void r600_resource_copy_region(struct pipe_context *ctx,
				      struct pipe_resource *dst,
				      unsigned dst_level,
				      unsigned dstx, unsigned dsty, unsigned dstz,
				      struct pipe_resource *src,
				      unsigned src_level,
				      const struct pipe_box *src_box)
{
	struct r600_resource_texture *rsrc = (struct r600_resource_texture*)src;
	struct texture_orig_info orig_info[2];
	struct pipe_box sbox;
	const struct pipe_box *psbox;
	boolean restore_orig[2];

	memset(orig_info, 0, sizeof(orig_info));

	/* Fallback for buffers. */
	if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
		util_resource_copy_region(ctx, dst, dst_level, dstx, dsty, dstz,
                                          src, src_level, src_box);
		return;
	}

	if (rsrc->depth && !rsrc->is_flushing_texture)
		r600_texture_depth_flush(ctx, src, FALSE);

	restore_orig[0] = restore_orig[1] = FALSE;

	if (util_format_is_compressed(src->format)) {
		r600_compressed_to_blittable(src, src_level, &orig_info[0]);
		restore_orig[0] = TRUE;
		sbox.x = util_format_get_nblocksx(orig_info[0].format, src_box->x);
		sbox.y = util_format_get_nblocksy(orig_info[0].format, src_box->y);
		sbox.z = src_box->z;
		sbox.width = util_format_get_nblocksx(orig_info[0].format, src_box->width);
		sbox.height = util_format_get_nblocksy(orig_info[0].format, src_box->height);
		sbox.depth = src_box->depth;
		psbox=&sbox;
	} else
		psbox=src_box;

	if (util_format_is_compressed(dst->format)) {
		r600_compressed_to_blittable(dst, dst_level, &orig_info[1]);
		restore_orig[1] = TRUE;
		/* translate the dst box as well */
		dstx = util_format_get_nblocksx(orig_info[1].format, dstx);
		dsty = util_format_get_nblocksy(orig_info[1].format, dsty);
	}

	r600_hw_copy_region(ctx, dst, dst_level, dstx, dsty, dstz,
			    src, src_level, psbox);

	if (restore_orig[0])
		r600_reset_blittable_to_compressed(src, src_level, &orig_info[0]);

	if (restore_orig[1])
		r600_reset_blittable_to_compressed(dst, dst_level, &orig_info[1]);
}
예제 #6
0
static struct pipe_transfer *
nv30_miptree_transfer_new(struct pipe_context *pipe, struct pipe_resource *pt,
                          unsigned level, unsigned usage,
                          const struct pipe_box *box)
{
   struct nv30_context *nv30 = nv30_context(pipe);
   struct nouveau_device *dev = nv30->screen->base.device;
   struct nv30_transfer *tx;
   int ret;

   tx = CALLOC_STRUCT(nv30_transfer);
   if (!tx)
      return NULL;
   pipe_resource_reference(&tx->base.resource, pt);
   tx->base.level = level;
   tx->base.usage = usage;
   tx->base.box = *box;
   tx->base.stride = util_format_get_nblocksx(pt->format, box->width) *
                     util_format_get_blocksize(pt->format);
   tx->base.layer_stride = util_format_get_nblocksy(pt->format, box->height) *
                           tx->base.stride;

   tx->nblocksx = util_format_get_nblocksx(pt->format, box->width);
   tx->nblocksy = util_format_get_nblocksy(pt->format, box->height);

   define_rect(pt, level, box->z, box->x, box->y,
                   tx->nblocksx, tx->nblocksy, &tx->img);

   ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
                        tx->base.layer_stride, NULL, &tx->tmp.bo);
   if (ret) {
      pipe_resource_reference(&tx->base.resource, NULL);
      FREE(tx);
      return NULL;
   }

   tx->tmp.domain = NOUVEAU_BO_GART;
   tx->tmp.offset = 0;
   tx->tmp.pitch  = tx->base.stride;
   tx->tmp.cpp    = tx->img.cpp;
   tx->tmp.w      = tx->nblocksx;
   tx->tmp.h      = tx->nblocksy;
   tx->tmp.d      = 1;
   tx->tmp.x0     = 0;
   tx->tmp.y0     = 0;
   tx->tmp.x1     = tx->tmp.w;
   tx->tmp.y1     = tx->tmp.h;
   tx->tmp.z      = 0;

   if (usage & PIPE_TRANSFER_READ)
      nv30_transfer_rect(nv30, NEAREST, &tx->img, &tx->tmp);

   return &tx->base;
}
예제 #7
0
static void si_compressed_to_blittable(struct pipe_resource *tex,
				       unsigned level,
				       struct texture_orig_info *orig)
{
	struct r600_texture *rtex = (struct r600_texture*)tex;
	unsigned pixsize = util_format_get_blocksize(rtex->resource.b.b.format);
	int new_format;
	int new_height, new_width;

	orig->format = tex->format;
	orig->width0 = tex->width0;
	orig->height0 = tex->height0;
	orig->npix0_x = rtex->surface.level[0].npix_x;
	orig->npix0_y = rtex->surface.level[0].npix_y;
	orig->npix_x = rtex->surface.level[level].npix_x;
	orig->npix_y = rtex->surface.level[level].npix_y;

	if (pixsize == 8)
		new_format = PIPE_FORMAT_R16G16B16A16_UINT; /* 64-bit block */
	else
		new_format = PIPE_FORMAT_R32G32B32A32_UINT; /* 128-bit block */

	new_width = util_format_get_nblocksx(tex->format, orig->width0);
	new_height = util_format_get_nblocksy(tex->format, orig->height0);

	tex->width0 = new_width;
	tex->height0 = new_height;
	tex->format = new_format;
	rtex->surface.level[0].npix_x = util_format_get_nblocksx(orig->format, orig->npix0_x);
	rtex->surface.level[0].npix_y = util_format_get_nblocksy(orig->format, orig->npix0_y);
	rtex->surface.level[level].npix_x = util_format_get_nblocksx(orig->format, orig->npix_x);
	rtex->surface.level[level].npix_y = util_format_get_nblocksy(orig->format, orig->npix_y);

	/* By dividing the dimensions by 4, we effectively decrement
	 * last_level by 2, therefore the last 2 mipmap levels disappear and
	 * aren't blittable. Note that the last 3 mipmap levels (4x4, 2x2,
	 * 1x1) have equal slice sizes, which is an important assumption
	 * for this to work.
	 *
	 * In order to make the last 2 mipmap levels blittable, we have to
	 * add the slice size of the last mipmap level to the texture
	 * address, so that even though the hw thinks it reads last_level-2,
	 * it will actually read last_level-1, and if we add the slice size*2,
	 * it will read last_level. That's how this workaround works.
	 */
	if (level > rtex->resource.b.b.last_level-2)
		rtex->mipmap_shift = level - (rtex->resource.b.b.last_level-2);
}
예제 #8
0
파일: tr_dump.c 프로젝트: Distrotech/Mesa
void trace_dump_box_bytes(const void *data,
                          struct pipe_resource *resource,
			  const struct pipe_box *box,
			  unsigned stride,
			  unsigned slice_stride)
{
   size_t size;

   /*
    * Only dump buffer transfers to avoid huge files.
    * TODO: Make this run-time configurable
    */
   if (resource->target != PIPE_BUFFER) {
      size = 0;
   } else {
      enum pipe_format format = resource->format;
      if (slice_stride)
         size = box->depth * slice_stride;
      else if (stride)
         size = util_format_get_nblocksy(format, box->height) * stride;
      else {
         size = util_format_get_nblocksx(format, box->width) * util_format_get_blocksize(format);
      }
   }

   trace_dump_bytes(data, size);
}
예제 #9
0
void debug_dump_surface(const char *prefix,
                        struct pipe_surface *surface)     
{
   struct pipe_texture *texture;
   struct pipe_screen *screen;
   struct pipe_transfer *transfer;
   void *data;

   if (!surface)
      return;

   texture = surface->texture;
   screen = texture->screen;

   transfer = screen->get_tex_transfer(screen, texture, surface->face,
                                       surface->level, surface->zslice,
                                       PIPE_TRANSFER_READ, 0, 0, surface->width,
                                       surface->height);
   
   data = screen->transfer_map(screen, transfer);
   if(!data)
      goto error;
   
   debug_dump_image(prefix, 
                    texture->format,
                    util_format_get_blocksize(texture->format), 
                    util_format_get_nblocksx(texture->format, transfer->width),
                    util_format_get_nblocksy(texture->format, transfer->height),
                    transfer->stride,
                    data);
   
   screen->transfer_unmap(screen, transfer);
error:
   screen->tex_transfer_destroy(transfer);
}
예제 #10
0
void
nv50_miptree_transfer_del(struct pipe_context *pcontext,
			  struct pipe_transfer *ptx)
{
	struct nv50_transfer *tx = (struct nv50_transfer *)ptx;
	struct nv50_miptree *mt = nv50_miptree(ptx->resource);
	struct pipe_resource *pt = ptx->resource;

	unsigned nx = util_format_get_nblocksx(pt->format, tx->base.box.width);
	unsigned ny = util_format_get_nblocksy(pt->format, tx->base.box.height);

	if (ptx->usage & PIPE_TRANSFER_WRITE) {
		struct pipe_screen *pscreen = pcontext->screen;

		nv50_transfer_rect_m2mf(pscreen, tx->bo, 0,
					tx->base.stride, tx->bo->tile_mode,
					0, 0, 0,
					tx->nblocksx, tx->nblocksy, 1,
					mt->base.bo, tx->level_offset,
					tx->level_pitch, tx->level_tiling,
					tx->level_x, tx->level_y, tx->level_z,
					tx->nblocksx, tx->nblocksy,
					tx->level_depth,
					util_format_get_blocksize(pt->format), nx, ny,
					NOUVEAU_BO_GART, NOUVEAU_BO_VRAM |
					NOUVEAU_BO_GART);
	}

	nouveau_bo_ref(NULL, &tx->bo);
	pipe_resource_reference(&ptx->resource, NULL);
	FREE(ptx);
}
예제 #11
0
/**
 * Return the size of the resource in bytes.
 */
unsigned
util_resource_size(const struct pipe_resource *res)
{
   unsigned width = res->width0;
   unsigned height = res->height0;
   unsigned depth = res->depth0;
   unsigned size = 0;
   unsigned level;

   for (level = 0; level <= res->last_level; level++) {
      unsigned slices;

      if (res->target == PIPE_TEXTURE_CUBE)
         slices = 6;
      else if (res->target == PIPE_TEXTURE_3D)
         slices = depth;
      else
         slices = res->array_size;

      size += (util_format_get_nblocksy(res->format, height) *
               util_format_get_stride(res->format, width) * slices);

      width  = u_minify(width, 1);
      height = u_minify(height, 1);
      depth = u_minify(depth, 1);
   }

   return size;
}
예제 #12
0
static struct pipe_surface *
nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
			 unsigned face, unsigned level, unsigned zslice,
			 unsigned flags)
{
	struct nv50_miptree *mt = nv50_miptree(pt);
	struct nv50_miptree_level *lvl = &mt->level[level];
	struct pipe_surface *ps;
	unsigned img = 0;

	if (pt->target == PIPE_TEXTURE_CUBE)
		img = face;

	ps = CALLOC_STRUCT(pipe_surface);
	if (!ps)
		return NULL;
	pipe_texture_reference(&ps->texture, pt);
	ps->format = pt->format;
	ps->width = u_minify(pt->width0, level);
	ps->height = u_minify(pt->height0, level);
	ps->usage = flags;
	pipe_reference_init(&ps->reference, 1);
	ps->face = face;
	ps->level = level;
	ps->zslice = zslice;
	ps->offset = lvl->image_offset[img];

	if (pt->target == PIPE_TEXTURE_3D) {
		unsigned nb_h = util_format_get_nblocksy(pt->format, ps->height);
		ps->offset += get_zslice_offset(lvl->tile_mode, zslice,
						lvl->pitch, nb_h);
	}

	return ps;
}
예제 #13
0
static struct sw_displaytarget *
wayland_displaytarget_from_handle(struct sw_winsys *ws,
                                  const struct pipe_resource *templet,
                                  struct winsys_handle *whandle,
                                  unsigned *stride)
{
   struct wayland_sw_displaytarget *wldt;
   unsigned nblocksy;

   if (!wayland_is_displaytarget_format_supported(ws, 0, templet->format))
      return NULL;

   wldt = CALLOC_STRUCT(wayland_sw_displaytarget);
   if (!wldt)
      return NULL;
 
   wldt->fd = whandle->fd;
   wldt->stride = whandle->stride;
   wldt->width = templet->width0;
   wldt->height = templet->height0;
   wldt->format = templet->format;

   nblocksy = util_format_get_nblocksy(wldt->format, wldt->height);

   wldt->size = wldt->stride * nblocksy;

   wldt->map = NULL;

   *stride = wldt->stride;

   return (struct sw_displaytarget *) wldt;
}
예제 #14
0
static unsigned
setup_miptree(struct etna_resource *rsc, unsigned paddingX, unsigned paddingY,
              unsigned msaa_xscale, unsigned msaa_yscale)
{
   struct pipe_resource *prsc = &rsc->base;
   unsigned level, size = 0;
   unsigned width = prsc->width0;
   unsigned height = prsc->height0;
   unsigned depth = prsc->depth0;

   for (level = 0; level <= prsc->last_level; level++) {
      struct etna_resource_level *mip = &rsc->levels[level];

      mip->width = width;
      mip->height = height;
      mip->padded_width = align(width * msaa_xscale, paddingX);
      mip->padded_height = align(height * msaa_yscale, paddingY);
      mip->stride = util_format_get_stride(prsc->format, mip->padded_width);
      mip->offset = size;
      mip->layer_stride = mip->stride * util_format_get_nblocksy(prsc->format, mip->padded_height);
      mip->size = prsc->array_size * mip->layer_stride;

      /* align levels to 64 bytes to be able to render to them */
      size += align(mip->size, ETNA_PE_ALIGNMENT) * depth;

      width = u_minify(width, 1);
      height = u_minify(height, 1);
      depth = u_minify(depth, 1);
   }

   return size;
}
static void
i915_texture_layout_2d(struct i915_texture *tex)
{
   struct pipe_resource *pt = &tex->b.b;
   unsigned level;
   unsigned width = util_next_power_of_two(pt->width0);
   unsigned height = util_next_power_of_two(pt->height0);
   unsigned nblocksy = util_format_get_nblocksy(pt->format, width);
   unsigned align_y = 2;

   if (util_format_is_s3tc(pt->format))
      align_y = 1;

   tex->stride = align(util_format_get_stride(pt->format, width), 4);
   tex->total_nblocksy = 0;

   for (level = 0; level <= pt->last_level; level++) {
      i915_texture_set_level_info(tex, level, 1);
      i915_texture_set_image_offset(tex, level, 0, 0, tex->total_nblocksy);

      tex->total_nblocksy += nblocksy;

      width = u_minify(width, 1);
      height = u_minify(height, 1);
      nblocksy = align_nblocksy(pt->format, height, align_y);
   }
}
static void
i915_texture_layout_3d(struct i915_texture *tex)
{
   struct pipe_resource *pt = &tex->b.b;
   unsigned level;

   unsigned width = util_next_power_of_two(pt->width0);
   unsigned height = util_next_power_of_two(pt->height0);
   unsigned depth = util_next_power_of_two(pt->depth0);
   unsigned nblocksy = util_format_get_nblocksy(pt->format, height);
   unsigned stack_nblocksy = 0;

   /* Calculate the size of a single slice. 
    */
   tex->stride = align(util_format_get_stride(pt->format, width), 4);

   /* XXX: hardware expects/requires 9 levels at minimum.
    */
   for (level = 0; level <= MAX2(8, pt->last_level); level++) {
      i915_texture_set_level_info(tex, level, depth);

      stack_nblocksy += MAX2(2, nblocksy);

      width = u_minify(width, 1);
      height = u_minify(height, 1);
      nblocksy = util_format_get_nblocksy(pt->format, height);
   }

   /* Fixup depth image_offsets: 
    */
   for (level = 0; level <= pt->last_level; level++) {
      unsigned i;
      for (i = 0; i < depth; i++) 
         i915_texture_set_image_offset(tex, level, i, 0, i * stack_nblocksy);

      depth = u_minify(depth, 1);
   }

   /* Multiply slice size by texture depth for total size.  It's
    * remarkable how wasteful of memory the i915 texture layouts
    * are.  They are largely fixed in the i945.
    */
   tex->total_nblocksy = stack_nblocksy * util_next_power_of_two(pt->depth0);
}
예제 #17
0
파일: surface9.c 프로젝트: alesegdia/mesa
static inline uint8_t *
NineSurface9_GetSystemMemPointer(struct NineSurface9 *This, int x, int y)
{
    unsigned x_offset = util_format_get_stride(This->base.info.format, x);

    y = util_format_get_nblocksy(This->base.info.format, y);

    assert(This->data);
    return This->data + (y * This->stride + x_offset);
}
예제 #18
0
파일: volume9.c 프로젝트: alesegdia/mesa
static inline uint8_t *
NineVolume9_GetSystemMemPointer(struct NineVolume9 *This, int x, int y, int z)
{
    unsigned x_offset = util_format_get_stride(This->info.format, x);

    y = util_format_get_nblocksy(This->info.format, y);

    assert(This->data);
    return This->data + (z * This->layer_stride + y * This->stride + x_offset);
}
예제 #19
0
파일: sp_texture.c 프로젝트: chemecse/mesa
/**
 * Conventional allocation path for non-display textures:
 * Use a simple, maximally packed layout.
 */
static boolean
softpipe_resource_layout(struct pipe_screen *screen,
                         struct softpipe_resource *spr,
                         boolean allocate)
{
   struct pipe_resource *pt = &spr->base;
   unsigned level;
   unsigned width = pt->width0;
   unsigned height = pt->height0;
   unsigned depth = pt->depth0;
   uint64_t buffer_size = 0;

   for (level = 0; level <= pt->last_level; level++) {
      unsigned slices, nblocksy;

      nblocksy = util_format_get_nblocksy(pt->format, height);

      if (pt->target == PIPE_TEXTURE_CUBE)
         assert(pt->array_size == 6);

      if (pt->target == PIPE_TEXTURE_3D)
         slices = depth;
      else
         slices = pt->array_size;

      spr->stride[level] = util_format_get_stride(pt->format, width);

      spr->level_offset[level] = buffer_size;

      /* if row_stride * height > SP_MAX_TEXTURE_SIZE */
      if ((uint64_t)spr->stride[level] * nblocksy > SP_MAX_TEXTURE_SIZE) {
         /* image too large */
         return FALSE;
      }

      spr->img_stride[level] = spr->stride[level] * nblocksy;

      buffer_size += (uint64_t) spr->img_stride[level] * slices;

      width  = u_minify(width, 1);
      height = u_minify(height, 1);
      depth = u_minify(depth, 1);
   }

   if (buffer_size > SP_MAX_TEXTURE_SIZE)
      return FALSE;

   if (allocate) {
      spr->data = align_malloc(buffer_size, 64);
      return spr->data != NULL;
   }
   else {
      return TRUE;
   }
}
예제 #20
0
static unsigned r300_texture_get_nblocksy(struct r300_resource *tex,
                                          unsigned level,
                                          boolean *out_aligned_for_cbzb)
{
    unsigned height, tile_height;

    height = u_minify(tex->tex.height0, level);

    /* Mipmapped and 3D textures must have their height aligned to POT. */
    if ((tex->b.b.b.target != PIPE_TEXTURE_1D &&
         tex->b.b.b.target != PIPE_TEXTURE_2D &&
         tex->b.b.b.target != PIPE_TEXTURE_RECT) ||
        tex->b.b.b.last_level != 0) {
        height = util_next_power_of_two(height);
    }

    if (util_format_is_plain(tex->b.b.b.format)) {
        tile_height = r300_get_pixel_alignment(tex->b.b.b.format,
                                               tex->b.b.b.nr_samples,
                                               tex->tex.microtile,
                                               tex->tex.macrotile[level],
                                               DIM_HEIGHT, 0);
        height = align(height, tile_height);

        /* See if the CBZB clear can be used on the buffer,
         * taking the texture size into account. */
        if (out_aligned_for_cbzb) {
            if (tex->tex.macrotile[level]) {
                /* When clearing, the layer (width*height) is horizontally split
                 * into two, and the upper and lower halves are cleared by the CB
                 * and ZB units, respectively. Therefore, the number of macrotiles
                 * in the Y direction must be even. */

                /* Align the height so that there is an even number of macrotiles.
                 * Do so for 3 or more macrotiles in the Y direction. */
                if (level == 0 && tex->b.b.b.last_level == 0 &&
                    (tex->b.b.b.target == PIPE_TEXTURE_1D ||
                     tex->b.b.b.target == PIPE_TEXTURE_2D ||
                     tex->b.b.b.target == PIPE_TEXTURE_RECT) &&
                    height >= tile_height * 3) {
                    height = align(height, tile_height * 2);
                }

                *out_aligned_for_cbzb = height % (tile_height * 2) == 0;
            } else {
                *out_aligned_for_cbzb = FALSE;
            }
        }
    }

    return util_format_get_nblocksy(tex->b.b.b.format, height);
}
예제 #21
0
static struct sw_displaytarget *
wayland_displaytarget_create(struct sw_winsys *ws,
                             unsigned tex_usage,
                             enum pipe_format format,
                             unsigned width, unsigned height,
                             unsigned alignment,
                             unsigned *stride)
{
   struct wayland_sw_displaytarget *wldt;
   unsigned nblocksy, format_stride;
   char filename[] = "/tmp/wayland-shm-XXXXXX";

   if (!wayland_is_displaytarget_format_supported(ws, tex_usage, format))
      return NULL;

   wldt = CALLOC_STRUCT(wayland_sw_displaytarget);
   if (!wldt)
      return NULL;

   wldt->map = NULL;

   wldt->format = format;
   wldt->width = width;
   wldt->height = height;

   format_stride = util_format_get_stride(format, width);
   wldt->stride = align(format_stride, alignment);

   nblocksy = util_format_get_nblocksy(format, height);
   wldt->size = wldt->stride * nblocksy;

   wldt->fd = mkstemp(filename);
   if (wldt->fd < 0) {
      FREE(wldt);
      return NULL;
   }

   if (ftruncate(wldt->fd, wldt->size) < 0) {
      unlink(filename);
      close(wldt->fd);
      FREE(wldt);
      return NULL;
   }

   unlink(filename);

   *stride = wldt->stride;

   return (struct sw_displaytarget *) wldt;
}
예제 #22
0
static unsigned r300_texture_get_nblocksy(struct r300_texture* tex,
        unsigned level)
{
    unsigned height, tile_height;

    height = u_minify(tex->tex.height0, level);

    if (!util_format_is_compressed(tex->tex.format)) {
        tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT,
                      tex->mip_macrotile[level]);
        height = align(height, tile_height);
    }

    return util_format_get_nblocksy(tex->tex.format, height);
}
static void
i945_texture_layout_3d(struct i915_texture *tex)
{
   struct pipe_resource *pt = &tex->b.b;
   unsigned width = util_next_power_of_two(pt->width0);
   unsigned height = util_next_power_of_two(pt->height0);
   unsigned depth = util_next_power_of_two(pt->depth0);
   unsigned nblocksy = util_format_get_nblocksy(pt->format, width);
   unsigned pack_x_pitch, pack_x_nr;
   unsigned pack_y_pitch;
   unsigned level;

   tex->stride = align(util_format_get_stride(pt->format, width), 4);
   tex->total_nblocksy = 0;

   pack_y_pitch = MAX2(nblocksy, 2);
   pack_x_pitch = tex->stride / util_format_get_blocksize(pt->format);
   pack_x_nr = 1;

   for (level = 0; level <= pt->last_level; level++) {
      int x = 0;
      int y = 0;
      unsigned q, j;

      i915_texture_set_level_info(tex, level, depth);

      for (q = 0; q < depth;) {
         for (j = 0; j < pack_x_nr && q < depth; j++, q++) {
            i915_texture_set_image_offset(tex, level, q, x, y + tex->total_nblocksy);
            x += pack_x_pitch;
         }

         x = 0;
         y += pack_y_pitch;
      }

      tex->total_nblocksy += y;

      if (pack_x_pitch > 4) {
         pack_x_pitch >>= 1;
         pack_x_nr <<= 1;
         assert(pack_x_pitch * pack_x_nr * util_format_get_blocksize(pt->format) <= tex->stride);
      }

      if (pack_y_pitch > 2) {
         pack_y_pitch >>= 1;
      }
예제 #24
0
static struct sw_displaytarget *
xlib_displaytarget_create(struct sw_winsys *winsys,
                          unsigned tex_usage,
                          enum pipe_format format,
                          unsigned width, unsigned height,
                          unsigned alignment,
                          unsigned *stride)
{
   struct xlib_displaytarget *xlib_dt;
   unsigned nblocksy, size;

   xlib_dt = CALLOC_STRUCT(xlib_displaytarget);
   if (!xlib_dt)
      goto no_xlib_dt;

   xlib_dt->display = ((struct xlib_sw_winsys *)winsys)->display;
   xlib_dt->format = format;
   xlib_dt->width = width;
   xlib_dt->height = height;

   nblocksy = util_format_get_nblocksy(format, height);
   xlib_dt->stride = align(util_format_get_stride(format, width), alignment);
   size = xlib_dt->stride * nblocksy;

   if (!debug_get_option_xlib_no_shm()) {
      xlib_dt->data = alloc_shm(xlib_dt, size);
      if (xlib_dt->data) {
         xlib_dt->shm = True;
      }
   }

   if (!xlib_dt->data) {
      xlib_dt->data = align_malloc(size, alignment);
      if (!xlib_dt->data)
         goto no_data;
   }

   *stride = xlib_dt->stride;
   return (struct sw_displaytarget *)xlib_dt;

no_data:
   FREE(xlib_dt);
no_xlib_dt:
   return NULL;
}
void trace_dump_box_bytes(const void *data,
			  enum pipe_format format,
			  const struct pipe_box *box,
			  unsigned stride,
			  unsigned slice_stride)
{
   size_t size;

   if (slice_stride)
      size = box->depth * slice_stride;
   else if (stride)
      size = util_format_get_nblocksy(format, box->height) * stride;
   else {
      size = util_format_get_nblocksx(format, box->width) * util_format_get_blocksize(format);
   }

   trace_dump_bytes(data, size);
}
예제 #26
0
static struct pipe_buffer* xsp_surface_buffer_create
(
   struct pipe_winsys *pws,
   unsigned width,
   unsigned height,
   enum pipe_format format,
   unsigned usage,
   unsigned tex_usage,
   unsigned *stride
)
{
   const unsigned int ALIGNMENT = 1;
   unsigned nblocksy;

   nblocksy = util_format_get_nblocksy(format, height);
   *stride = align(util_format_get_stride(format, width), ALIGNMENT);

   return pws->buffer_create(pws, ALIGNMENT, usage,
                             *stride * nblocksy);
}
예제 #27
0
int virgl_vtest_recv_transfer_get_data(struct virgl_vtest_winsys *vws,
                                       void *data,
                                       uint32_t data_size,
                                       uint32_t stride,
                                       const struct pipe_box *box,
                                       uint32_t format)
{
   void *line;
   void *ptr = data;
   int hblocks = util_format_get_nblocksy(format, box->height);

   line = malloc(stride);
   while (hblocks) {
      virgl_block_read(vws->sock_fd, line, stride);
      memcpy(ptr, line, util_format_get_stride(format, box->width));
      ptr += stride;
      hblocks--;
   }
   free(line);
   return 0;
}
예제 #28
0
/* FIXME: dump resources, not surfaces... */
void debug_dump_surface(struct pipe_context *pipe,
                        const char *prefix,
                        struct pipe_surface *surface)
{
   struct pipe_resource *texture;
   struct pipe_transfer *transfer;
   void *data;

   if (!surface)
      return;

   /* XXX: this doesn't necessarily work, as the driver may be using
    * temporary storage for the surface which hasn't been propagated
    * back into the texture.  Need to nail down the semantics of views
    * and transfers a bit better before we can say if extra work needs
    * to be done here:
    */
   texture = surface->texture;

   transfer = pipe_get_transfer(pipe, texture, surface->u.tex.level,
                                surface->u.tex.first_layer,
                                PIPE_TRANSFER_READ,
                                0, 0, surface->width, surface->height);

   data = pipe->transfer_map(pipe, transfer);
   if(!data)
      goto error;

   debug_dump_image(prefix,
                    texture->format,
                    util_format_get_blocksize(texture->format),
                    util_format_get_nblocksx(texture->format, surface->width),
                    util_format_get_nblocksy(texture->format, surface->height),
                    transfer->stride,
                    data);

   pipe->transfer_unmap(pipe, transfer);
error:
   pipe->transfer_destroy(pipe, transfer);
}
예제 #29
0
static void
fd_resource_flush_rgtc(struct fd_transfer *trans, const struct pipe_box *box)
{
	struct fd_resource *rsc = fd_resource(trans->base.resource);
	struct fd_resource_slice *slice = fd_resource_slice(rsc, trans->base.level);
	enum pipe_format format = trans->base.resource->format;

	uint8_t *data = fd_bo_map(rsc->bo) + slice->offset +
		fd_resource_layer_offset(rsc, slice, trans->base.box.z) +
		((trans->base.box.y + box->y) * slice->pitch +
		 trans->base.box.x + box->x) * rsc->cpp;

	uint8_t *source = trans->staging +
		util_format_get_nblocksy(format, box->y) * trans->base.stride +
		util_format_get_stride(format, box->x);

	switch (format) {
	case PIPE_FORMAT_RGTC1_UNORM:
	case PIPE_FORMAT_RGTC1_SNORM:
	case PIPE_FORMAT_LATC1_UNORM:
	case PIPE_FORMAT_LATC1_SNORM:
		util_format_rgtc1_unorm_unpack_rgba_8unorm(
				data, slice->pitch * rsc->cpp,
				source, trans->base.stride,
				box->width, box->height);
		break;
	case PIPE_FORMAT_RGTC2_UNORM:
	case PIPE_FORMAT_RGTC2_SNORM:
	case PIPE_FORMAT_LATC2_UNORM:
	case PIPE_FORMAT_LATC2_SNORM:
		util_format_rgtc2_unorm_unpack_rgba_8unorm(
				data, slice->pitch * rsc->cpp,
				source, trans->base.stride,
				box->width, box->height);
		break;
	default:
		assert(!"Unexpected format\n");
		break;
	}
}
예제 #30
0
/**
 * Helper function to compute offset (in bytes) for a particular
 * texture level/face/slice from the start of the buffer.
 */
static unsigned
sp_get_tex_image_offset(const struct softpipe_resource *spr,
                        unsigned level, unsigned layer)
{
   const unsigned hgt = u_minify(spr->base.height0, level);
   const unsigned nblocksy = util_format_get_nblocksy(spr->base.format, hgt);
   unsigned offset = spr->level_offset[level];

   if (spr->base.target == PIPE_TEXTURE_CUBE ||
       spr->base.target == PIPE_TEXTURE_3D ||
       spr->base.target == PIPE_TEXTURE_2D_ARRAY) {
      offset += layer * nblocksy * spr->stride[level];
   }
   else if (spr->base.target == PIPE_TEXTURE_1D_ARRAY) {
      offset += layer * spr->stride[level];
   }
   else {
      assert(layer == 0);
   }

   return offset;
}