Пример #1
0
static void
i915_texture_layout_3d(struct i915_texture *tex)
{
   struct pipe_resource *pt = &tex->b.b;
   unsigned level;

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

   /* Calculate the size of a single slice. 
    */
   tex->stride = align(util_format_get_stride(pt->format, pt->width0), 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 * pt->depth0;
}
static uint32_t
setup_slices(struct fd_resource *rsc, uint32_t alignment)
{
	struct pipe_resource *prsc = &rsc->base.b;
	uint32_t level, size = 0;
	uint32_t width = prsc->width0;
	uint32_t height = prsc->height0;
	uint32_t depth = prsc->depth0;
	/* in layer_first layout, the level (slice) contains just one
	 * layer (since in fact the layer contains the slices)
	 */
	uint32_t layers_in_level = rsc->layer_first ? 1 : prsc->array_size;

	for (level = 0; level <= prsc->last_level; level++) {
		struct fd_resource_slice *slice = fd_resource_slice(rsc, level);

		slice->pitch = width = align(width, 32);
		slice->offset = size;
		/* 1d array and 2d array textures must all have the same layer size
		 * for each miplevel on a3xx. 3d textures can have different layer
		 * sizes for high levels, but the hw auto-sizer is buggy (or at least
		 * different than what this code does), so as soon as the layer size
		 * range gets into range, we stop reducing it.
		 */
		if (prsc->target == PIPE_TEXTURE_3D && (
					level == 1 ||
					(level > 1 && rsc->slices[level - 1].size0 > 0xf000)))
			slice->size0 = align(slice->pitch * height * rsc->cpp, alignment);
		else if (level == 0 || rsc->layer_first || alignment == 1)
			slice->size0 = align(slice->pitch * height * rsc->cpp, alignment);
		else
			slice->size0 = rsc->slices[level - 1].size0;

		size += slice->size0 * depth * layers_in_level;

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

	return size;
}
Пример #3
0
/**
 * When doing GL render to texture, we have to be sure that finalize_texture()
 * didn't yank out the pipe_resource that we earlier created a surface for.
 * Check for that here and create a new surface if needed.
 */
static void
update_renderbuffer_surface(struct st_context *st,
                            struct st_renderbuffer *strb)
{
   struct pipe_context *pipe = st->pipe;
   struct pipe_resource *resource = strb->rtt ? strb->rtt->pt : strb->texture;
   int rtt_width = strb->Base.Width;
   int rtt_height = strb->Base.Height;
   enum pipe_format format = st->ctx->Color.sRGBEnabled ? resource->format : util_format_linear(resource->format);

   if (!strb->surface ||
       strb->surface->format != format ||
       strb->surface->texture != resource ||
       strb->surface->width != rtt_width ||
       strb->surface->height != rtt_height) {
      GLuint level;
      /* find matching mipmap level size */
      for (level = 0; level <= resource->last_level; level++) {
         if (u_minify(resource->width0, level) == rtt_width &&
             u_minify(resource->height0, level) == rtt_height) {
            struct pipe_surface surf_tmpl;
            memset(&surf_tmpl, 0, sizeof(surf_tmpl));
            surf_tmpl.format = format;
            surf_tmpl.u.tex.level = level;
            surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice;
            surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice;

            pipe_surface_reference(&strb->surface, NULL);

            strb->surface = pipe->create_surface(pipe,
                                                 resource,
                                                 &surf_tmpl);
#if 0
            printf("-- alloc new surface %d x %d into tex %p\n",
                   strb->surface->width, strb->surface->height,
                   texture);
#endif
            break;
         }
      }
   }
}
Пример #4
0
static boolean is_simple_msaa_resolve(const struct pipe_blit_info *info)
{
	unsigned dst_width = u_minify(info->dst.resource->width0, info->dst.level);
	unsigned dst_height = u_minify(info->dst.resource->height0, info->dst.level);

	return info->dst.resource->format == info->src.resource->format &&
		info->dst.resource->format == info->dst.format &&
		info->src.resource->format == info->src.format &&
		!info->scissor_enable &&
		info->mask == PIPE_MASK_RGBA &&
		dst_width == info->src.resource->width0 &&
		dst_height == info->src.resource->height0 &&
		info->dst.box.x == 0 &&
		info->dst.box.y == 0 &&
		info->dst.box.width == dst_width &&
		info->dst.box.height == dst_height &&
		info->src.box.x == 0 &&
		info->src.box.y == 0 &&
		info->src.box.width == dst_width &&
		info->src.box.height == dst_height;
}
Пример #5
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);
}
/* Return true if macrotiling should be enabled on the miplevel. */
static boolean r300_texture_macro_switch(struct r300_texture_desc *desc,
                                         unsigned level,
                                         boolean rv350_mode,
                                         enum r300_dim dim)
{
    unsigned tile, texdim;

    tile = r300_get_pixel_alignment(desc->b.b.format, desc->b.b.nr_samples,
                                    desc->microtile, R300_BUFFER_TILED, dim);
    if (dim == DIM_WIDTH) {
        texdim = u_minify(desc->b.b.width0, level);
    } else {
        texdim = u_minify(desc->b.b.height0, level);
    }

    /* See TX_FILTER1_n.MACRO_SWITCH. */
    if (rv350_mode) {
        return texdim >= tile;
    } else {
        return texdim > tile;
    }
}
Пример #7
0
/*
 * Store SWR HotTiles back to renderTarget surface.
 */
void
swr_store_render_target(struct pipe_context *pipe,
                        uint32_t attachment,
                        enum SWR_TILE_STATE post_tile_state)
{
   struct swr_context *ctx = swr_context(pipe);
   struct swr_draw_context *pDC = &ctx->swrDC;
   struct SWR_SURFACE_STATE *renderTarget = &pDC->renderTargets[attachment];

   /* Only proceed if there's a valid surface to store to */
   if (renderTarget->xpBaseAddress) {
      swr_update_draw_context(ctx);
      SWR_RECT full_rect =
         {0, 0,
          (int32_t)u_minify(renderTarget->width, renderTarget->lod),
          (int32_t)u_minify(renderTarget->height, renderTarget->lod)};
      ctx->api.pfnSwrStoreTiles(ctx->swrContext,
                                1 << attachment,
                                post_tile_state,
                                full_rect);
   }
}
Пример #8
0
/* Return true if macrotiling should be enabled on the miplevel. */
static boolean r300_texture_macro_switch(struct r300_resource *tex,
                                         unsigned level,
                                         boolean rv350_mode,
                                         enum r300_dim dim)
{
    unsigned tile, texdim;

    tile = r300_get_pixel_alignment(tex->b.b.b.format, tex->b.b.b.nr_samples,
                                    tex->tex.microtile, RADEON_LAYOUT_TILED, dim, 0);
    if (dim == DIM_WIDTH) {
        texdim = u_minify(tex->tex.width0, level);
    } else {
        texdim = u_minify(tex->tex.height0, level);
    }

    /* See TX_FILTER1_n.MACRO_SWITCH. */
    if (rv350_mode) {
        return texdim >= tile;
    } else {
        return texdim > tile;
    }
}
Пример #9
0
static boolean is_simple_resolve(const struct pipe_resolve_info *info)
{
   unsigned dst_width = u_minify(info->dst.res->width0, info->dst.level);
   unsigned dst_height = u_minify(info->dst.res->height0, info->dst.level);
   struct r600_texture *dst = (struct r600_texture*)info->dst.res;
   unsigned dst_tile_mode = dst->surface.level[info->dst.level].mode;

   return info->dst.res->format == info->src.res->format &&
          dst_width == info->src.res->width0 &&
          dst_height == info->src.res->height0 &&
          info->dst.x0 == 0 &&
          info->dst.y0 == 0 &&
          info->dst.x1 == dst_width &&
          info->dst.y1 == dst_height &&
          info->src.x0 == 0 &&
          info->src.y0 == 0 &&
          info->src.x1 == dst_width &&
          info->src.y1 == dst_height &&
          /* Dst must be tiled. If it's not, we have to use a temporary
	   * resource which is tiled. */
	  dst_tile_mode >= RADEON_SURF_MODE_1D;
}
Пример #10
0
static void get_texcoords(struct pipe_sampler_view *src,
                          unsigned src_width0, unsigned src_height0,
                          unsigned x1, unsigned y1,
                          unsigned x2, unsigned y2,
                          float out[4])
{
   struct pipe_resource *tex = src->texture;
   unsigned level = src->u.tex.first_level;
   boolean normalized = tex->target != PIPE_TEXTURE_RECT;

   if (normalized) {
      out[0] = x1 / (float)u_minify(src_width0,  level);
      out[1] = y1 / (float)u_minify(src_height0, level);
      out[2] = x2 / (float)u_minify(src_width0,  level);
      out[3] = y2 / (float)u_minify(src_height0, level);
   } else {
      out[0] = x1;
      out[1] = y1;
      out[2] = x2;
      out[3] = y2;
   }
}
Пример #11
0
static struct pipe_surface *
swr_create_surface(struct pipe_context *pipe,
                   struct pipe_resource *pt,
                   const struct pipe_surface *surf_tmpl)
{
   struct pipe_surface *ps;

   ps = CALLOC_STRUCT(pipe_surface);
   if (ps) {
      pipe_reference_init(&ps->reference, 1);
      pipe_resource_reference(&ps->texture, pt);
      ps->context = pipe;
      ps->format = surf_tmpl->format;
      if (pt->target != PIPE_BUFFER) {
         assert(surf_tmpl->u.tex.level <= pt->last_level);
         ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level);
         ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level);
         ps->u.tex.level = surf_tmpl->u.tex.level;
         ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
         ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
         if (ps->u.tex.first_layer != ps->u.tex.last_layer) {
            debug_printf("creating surface with multiple layers, rendering "
                         "to first layer only\n");
         }
      } else {
         /* setting width as number of elements should get us correct
          * renderbuffer width */
         ps->width = surf_tmpl->u.buf.last_element
            - surf_tmpl->u.buf.first_element + 1;
         ps->height = pt->height0;
         ps->u.buf.first_element = surf_tmpl->u.buf.first_element;
         ps->u.buf.last_element = surf_tmpl->u.buf.last_element;
         assert(ps->u.buf.first_element <= ps->u.buf.last_element);
         assert(ps->u.buf.last_element < ps->width);
      }
   }
   return ps;
}
Пример #12
0
struct pipe_surface *
nv30_miptree_surface_new(struct pipe_context *pipe,
                         struct pipe_resource *pt,
                         const struct pipe_surface *tmpl)
{
   struct nv30_miptree *mt = nv30_miptree(pt); /* guaranteed */
   struct nv30_surface *ns;
   struct pipe_surface *ps;
   struct nv30_miptree_level *lvl = &mt->level[tmpl->u.tex.level];

   ns = CALLOC_STRUCT(nv30_surface);
   if (!ns)
      return NULL;
   ps = &ns->base;

   pipe_reference_init(&ps->reference, 1);
   pipe_resource_reference(&ps->texture, pt);
   ps->context = pipe;
   ps->format = tmpl->format;
   ps->usage = tmpl->usage;
   ps->u.tex.level = tmpl->u.tex.level;
   ps->u.tex.first_layer = tmpl->u.tex.first_layer;
   ps->u.tex.last_layer = tmpl->u.tex.last_layer;

   ns->width = u_minify(pt->width0, ps->u.tex.level);
   ns->height = u_minify(pt->height0, ps->u.tex.level);
   ns->depth = ps->u.tex.last_layer - ps->u.tex.first_layer + 1;
   ns->offset = layer_offset(pt, ps->u.tex.level, ps->u.tex.first_layer);
   if (mt->swizzled)
      ns->pitch = 4096; /* random, just something the hw won't reject.. */
   else
      ns->pitch = lvl->pitch;

   /* comment says there are going to be removed, but they're used by the st */
   ps->width = ns->width;
   ps->height = ns->height;
   return ps;
}
Пример #13
0
static boolean
vrend_resource_layout(struct virgl_texture *res,
                      uint32_t *total_size)
{
   struct pipe_resource *pt = &res->base.u.b;
   unsigned level;
   unsigned width = pt->width0;
   unsigned height = pt->height0;
   unsigned depth = pt->depth0;
   unsigned buffer_size = 0;

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

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

      res->stride[level] = util_format_get_stride(pt->format, width);
      res->level_offset[level] = buffer_size;

      buffer_size += (util_format_get_nblocksy(pt->format, height) *
                      slices * res->stride[level]);

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

   if (pt->nr_samples <= 1)
      *total_size = buffer_size;
   else /* don't create guest backing store for MSAA */
      *total_size = 0;
   return TRUE;
}
Пример #14
0
static struct pipe_sampler_view *
vc4_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc,
                        const struct pipe_sampler_view *cso)
{
        struct pipe_sampler_view *so = malloc(sizeof(*so));

        if (!so)
                return NULL;

        *so = *cso;

        pipe_reference(NULL, &prsc->reference);

        /* There is no hardware level clamping, and the start address of a
         * texture may be misaligned, so in that case we have to copy to a
         * temporary.
         */
        if (so->u.tex.first_level) {
                struct vc4_resource *shadow_parent = vc4_resource(prsc);
                struct pipe_resource tmpl = shadow_parent->base.b;
                struct vc4_resource *clone;

                tmpl.width0 = u_minify(tmpl.width0, so->u.tex.first_level);
                tmpl.height0 = u_minify(tmpl.height0, so->u.tex.first_level);
                tmpl.last_level = so->u.tex.last_level - so->u.tex.first_level;

                prsc = vc4_resource_create(pctx->screen, &tmpl);
                clone = vc4_resource(prsc);
                clone->shadow_parent = &shadow_parent->base.b;
                /* Flag it as needing update of the contents from the parent. */
                clone->writes = shadow_parent->writes - 1;
        }
        so->texture = prsc;
        so->reference.count = 1;
        so->context = pctx;

        return so;
}
Пример #15
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;
}
Пример #16
0
static unsigned u_max_layer(struct pipe_resource *r, unsigned level)
{
	switch (r->target) {
	case PIPE_TEXTURE_CUBE:
		return 6 - 1;
	case PIPE_TEXTURE_3D:
		return u_minify(r->depth0, level) - 1;
	case PIPE_TEXTURE_1D_ARRAY:
	case PIPE_TEXTURE_2D_ARRAY:
		return r->array_size - 1;
	default:
		return 0;
	}
}
static boolean r300_is_simple_msaa_resolve(const struct pipe_blit_info *info)
{
    unsigned dst_width = u_minify(info->dst.resource->width0, info->dst.level);
    unsigned dst_height = u_minify(info->dst.resource->height0, info->dst.level);

    return info->dst.resource->format == info->src.resource->format &&
           info->dst.resource->format == info->dst.format &&
           info->src.resource->format == info->src.format &&
           !info->scissor_enable &&
           info->mask == PIPE_MASK_RGBA &&
           dst_width == info->src.resource->width0 &&
           dst_height == info->src.resource->height0 &&
           info->dst.box.x == 0 &&
           info->dst.box.y == 0 &&
           info->dst.box.width == dst_width &&
           info->dst.box.height == dst_height &&
           info->src.box.x == 0 &&
           info->src.box.y == 0 &&
           info->src.box.width == dst_width &&
           info->src.box.height == dst_height &&
           (r300_resource(info->dst.resource)->tex.microtile != RADEON_LAYOUT_LINEAR ||
            r300_resource(info->dst.resource)->tex.macrotile[info->dst.level] != RADEON_LAYOUT_LINEAR);
}
Пример #18
0
/**
 * 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)
{
   struct pipe_resource *pt = &spr->base;
   unsigned level;
   unsigned width = pt->width0;
   unsigned height = pt->height0;
   unsigned depth = pt->depth0;
   unsigned buffer_size = 0;

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

      if (pt->target == PIPE_TEXTURE_CUBE)
         slices = 6;
      else 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;

      buffer_size += (util_format_get_nblocksy(pt->format, height) *
                      slices * spr->stride[level]);

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

   spr->data = align_malloc(buffer_size, 16);

   return spr->data != NULL;
}
Пример #19
0
static void r300_setup_miptree(struct r300_screen* screen,
                               struct r300_texture* tex)
{
    struct pipe_texture* base = &tex->tex;
    unsigned stride, size, layer_size, nblocksy, i;
    boolean rv350_mode = screen->caps->family >= CHIP_FAMILY_RV350;

    SCREEN_DBG(screen, DBG_TEX, "r300: Making miptree for texture, format %s\n",
               util_format_name(base->format));

    for (i = 0; i <= base->last_level; i++) {
        /* Let's see if this miplevel can be macrotiled. */
        tex->mip_macrotile[i] = (tex->macrotile == R300_BUFFER_TILED &&
                                 r300_texture_macro_switch(tex, i, rv350_mode)) ?
                                R300_BUFFER_TILED : R300_BUFFER_LINEAR;

        stride = r300_texture_get_stride(screen, tex, i);
        nblocksy = r300_texture_get_nblocksy(tex, i);
        layer_size = stride * nblocksy;

        if (base->target == PIPE_TEXTURE_CUBE)
            size = layer_size * 6;
        else
            size = layer_size * u_minify(base->depth0, i);

        tex->offset[i] = tex->size;
        tex->size = tex->offset[i] + size;
        tex->layer_size[i] = layer_size;
        tex->pitch[i] = stride / util_format_get_blocksize(base->format);

        SCREEN_DBG(screen, DBG_TEX, "r300: Texture miptree: Level %d "
                   "(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n",
                   i, u_minify(base->width0, i), u_minify(base->height0, i),
                   u_minify(base->depth0, i), stride, tex->size,
                   tex->mip_macrotile[i] ? "TRUE" : "FALSE");
    }
}
Пример #20
0
/**
 * Map a resource for read/write.
 */
void *
llvmpipe_resource_map(struct pipe_resource *resource,
                      unsigned level,
                      unsigned layer,
                      enum lp_texture_usage tex_usage)
{
   struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
   uint8_t *map;

   assert(level < LP_MAX_TEXTURE_LEVELS);
   assert(layer < (u_minify(resource->depth0, level) + resource->array_size - 1));

   assert(tex_usage == LP_TEX_USAGE_READ ||
          tex_usage == LP_TEX_USAGE_READ_WRITE ||
          tex_usage == LP_TEX_USAGE_WRITE_ALL);

   if (lpr->dt) {
      /* display target */
      struct llvmpipe_screen *screen = llvmpipe_screen(resource->screen);
      struct sw_winsys *winsys = screen->winsys;
      unsigned dt_usage;

      if (tex_usage == LP_TEX_USAGE_READ) {
         dt_usage = PIPE_TRANSFER_READ;
      }
      else {
         dt_usage = PIPE_TRANSFER_READ_WRITE;
      }

      assert(level == 0);
      assert(layer == 0);

      /* FIXME: keep map count? */
      map = winsys->displaytarget_map(winsys, lpr->dt, dt_usage);

      /* install this linear image in texture data structure */
      lpr->linear_img.data = map;

      return map;
   }
   else if (llvmpipe_resource_is_texture(resource)) {

      map = llvmpipe_get_texture_image(lpr, layer, level, tex_usage);
      return map;
   }
   else {
      return lpr->data;
   }
}
Пример #21
0
static void translate_image(struct fd6_image *img, struct pipe_image_view *pimg)
{
	enum pipe_format format = pimg->format;
	struct pipe_resource *prsc = pimg->resource;
	struct fd_resource *rsc = fd_resource(prsc);
	unsigned lvl;

	if (!pimg->resource) {
		memset(img, 0, sizeof(*img));
		return;
	}

	img->pfmt      = format;
	img->fmt       = fd6_pipe2tex(format);
	img->fetchsize = fd6_pipe2fetchsize(format);
	img->type      = fd6_tex_type(prsc->target);
	img->srgb      = util_format_is_srgb(format);
	img->cpp       = rsc->cpp;
	img->bo        = rsc->bo;

	if (prsc->target == PIPE_BUFFER) {
		lvl = 0;
		img->offset = pimg->u.buf.offset;
		img->pitch  = pimg->u.buf.size;
		img->array_pitch = 0;
	} else {
		lvl = pimg->u.tex.level;
		img->offset = rsc->slices[lvl].offset;
		img->pitch  = rsc->slices[lvl].pitch * rsc->cpp;
		img->array_pitch = rsc->layer_size;
	}

	img->width     = u_minify(prsc->width0, lvl);
	img->height    = u_minify(prsc->height0, lvl);
	img->depth     = u_minify(prsc->depth0, lvl);
}
Пример #22
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;
   }
}
Пример #23
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);
   }
}
Пример #24
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);
}
Пример #25
0
/**
 * Check if a texture image can be pulled into a unified mipmap texture.
 */
GLboolean
st_texture_match_image(struct st_context *st,
                       const struct pipe_resource *pt,
                       const struct gl_texture_image *image)
{
   unsigned ptWidth;
   uint16_t ptHeight, ptDepth, ptLayers;

   /* Images with borders are never pulled into mipmap textures.
    */
   if (image->Border)
      return GL_FALSE;

   /* Check if this image's format matches the established texture's format.
    */
   if (st_mesa_format_to_pipe_format(st, image->TexFormat) != pt->format)
      return GL_FALSE;

   st_gl_texture_dims_to_pipe_dims(image->TexObject->Target,
                                   image->Width, image->Height, image->Depth,
                                   &ptWidth, &ptHeight, &ptDepth, &ptLayers);

   /* Test if this image's size matches what's expected in the
    * established texture.
    */
   if (ptWidth != u_minify(pt->width0, image->Level) ||
       ptHeight != u_minify(pt->height0, image->Level) ||
       ptDepth != u_minify(pt->depth0, image->Level) ||
       ptLayers != pt->array_size)
      return GL_FALSE;

   if (image->Level > pt->last_level)
      return GL_FALSE;

   return GL_TRUE;
}
Пример #26
0
/* Return true if macrotiling should be enabled on the miplevel. */
static boolean r300_texture_macro_switch(struct r300_texture *tex,
        unsigned level,
        boolean rv350_mode)
{
    unsigned tile_width, width;

    tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH, TRUE);
    width = u_minify(tex->tex.width0, level);

    /* See TX_FILTER1_n.MACRO_SWITCH. */
    if (rv350_mode) {
        return width >= tile_width;
    } else {
        return width > tile_width;
    }
}
Пример #27
0
static void blitter_set_texcoords(struct blitter_context_priv *ctx,
                                  struct pipe_sampler_view *src,
                                  unsigned src_width0, unsigned src_height0,
                                  unsigned layer,
                                  unsigned x1, unsigned y1,
                                  unsigned x2, unsigned y2)
{
   unsigned i;
   float coord[4];
   float face_coord[4][2];

   get_texcoords(src, src_width0, src_height0, x1, y1, x2, y2, coord);

   if (src->texture->target == PIPE_TEXTURE_CUBE) {
      set_texcoords_in_vertices(coord, &face_coord[0][0], 2);
      util_map_texcoords2d_onto_cubemap(layer,
                                        /* pointer, stride in floats */
                                        &face_coord[0][0], 2,
                                        &ctx->vertices[0][1][0], 8);
   } else {
      set_texcoords_in_vertices(coord, &ctx->vertices[0][1][0], 8);
   }

   /* Set the layer. */
   switch (src->texture->target) {
   case PIPE_TEXTURE_3D:
      {
         float r = layer / (float)u_minify(src->texture->depth0,
                                           src->u.tex.first_level);
         for (i = 0; i < 4; i++)
            ctx->vertices[i][1][2] = r; /*r*/
      }
      break;

   case PIPE_TEXTURE_1D_ARRAY:
      for (i = 0; i < 4; i++)
         ctx->vertices[i][1][1] = layer; /*t*/
      break;

   case PIPE_TEXTURE_2D_ARRAY:
      for (i = 0; i < 4; i++)
         ctx->vertices[i][1][2] = layer; /*r*/
      break;

   default:;
   }
}
Пример #28
0
/**
 * Copy the image at level=0 in 'src' to the 'dst' resource at 'dstLevel'.
 * This is used to copy mipmap images from one texture buffer to another.
 * This typically happens when our initial guess at the total texture size
 * is incorrect (see the guess_and_alloc_texture() function).
 */
void
st_texture_image_copy(struct pipe_context *pipe,
                      struct pipe_resource *dst, GLuint dstLevel,
                      struct pipe_resource *src, GLuint srcLevel,
                      GLuint face)
{
   GLuint width = u_minify(dst->width0, dstLevel);
   GLuint height = u_minify(dst->height0, dstLevel);
   GLuint depth = u_minify(dst->depth0, dstLevel);
   struct pipe_box src_box;
   GLuint i;

   if (u_minify(src->width0, srcLevel) != width ||
       u_minify(src->height0, srcLevel) != height ||
       u_minify(src->depth0, srcLevel) != depth) {
      /* The source image size doesn't match the destination image size.
       * This can happen in some degenerate situations such as rendering to a
       * cube map face which was set up with mismatched texture sizes.
       */
      return;
   }

   src_box.x = 0;
   src_box.y = 0;
   src_box.width = width;
   src_box.height = height;
   src_box.depth = 1;

   if (src->target == PIPE_TEXTURE_1D_ARRAY ||
       src->target == PIPE_TEXTURE_2D_ARRAY ||
       src->target == PIPE_TEXTURE_CUBE_ARRAY) {
      face = 0;
      depth = src->array_size;
   }

   /* Loop over 3D image slices */
   /* could (and probably should) use "true" 3d box here -
      but drivers can't quite handle it yet */
   for (i = face; i < face + depth; i++) {
      src_box.z = i;

      if (0)  {
         print_center_pixel(pipe, src);
      }

      pipe->resource_copy_region(pipe,
                                 dst,
                                 dstLevel,
                                 0, 0, i,/* destX, Y, Z */
                                 src,
                                 srcLevel,
                                 &src_box);
   }
}
Пример #29
0
static void r600_setup_miptree(struct pipe_screen *screen,
			       struct r600_resource_texture *rtex,
			       unsigned array_mode)
{
	struct pipe_resource *ptex = &rtex->resource.b.b;
	enum chip_class chipc = ((struct r600_screen*)screen)->chip_class;
	unsigned size, layer_size, i, offset;
	unsigned nblocksx, nblocksy;

	for (i = 0, offset = 0; i <= ptex->last_level; i++) {
		unsigned blocksize = util_format_get_blocksize(rtex->real_format);
		unsigned base_align = r600_get_base_alignment(screen, rtex->real_format, array_mode);

		r600_texture_set_array_mode(screen, rtex, i, array_mode);

		nblocksx = r600_texture_get_nblocksx(screen, rtex, i);
		nblocksy = r600_texture_get_nblocksy(screen, rtex, i);

		if (array_mode == V_009910_ARRAY_LINEAR_GENERAL)
			layer_size = align(nblocksx, 64) * nblocksy * blocksize;
		else
			layer_size = nblocksx * nblocksy * blocksize;

		if (ptex->target == PIPE_TEXTURE_CUBE) {
			if (chipc >= CAYMAN)
				size = layer_size * 8;
		}
		else if (ptex->target == PIPE_TEXTURE_3D)
			size = layer_size * u_minify(ptex->depth0, i);
		else
			size = layer_size * ptex->array_size;

		/* align base image and start of miptree */
		if ((i == 0) || (i == 1))
			offset = align(offset, base_align);
		rtex->offset[i] = offset;
		rtex->layer_size[i] = layer_size;
		rtex->pitch_in_blocks[i] = nblocksx; /* CB talks in elements */
		rtex->pitch_in_bytes[i] = nblocksx * blocksize;

		offset += size;
	}
	rtex->size = offset;
}
Пример #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;
}