Exemple #1
0
/**
 * Return the stride, in bytes, of the texture images of the given texture
 * at the given level.
 */
unsigned r300_texture_get_stride(struct r300_screen* screen,
                                 struct r300_texture* tex, unsigned level)
{
    unsigned tile_width, width;

    if (tex->stride_override)
        return tex->stride_override;

    /* Check the level. */
    if (level > tex->tex.last_level) {
        SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n",
                   __FUNCTION__, level, tex->tex.last_level);
        return 0;
    }

    width = u_minify(tex->tex.width0, level);

    if (!util_format_is_compressed(tex->tex.format)) {
        tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH,
                                                tex->mip_macrotile[level]);
        width = align(width, tile_width);

        return util_format_get_stride(tex->tex.format, width);
    } else {
        return align(util_format_get_stride(tex->tex.format, width), 32);
    }
}
Exemple #2
0
/**
 * 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;
}
/**
 * Return the stride, in bytes, of the texture image of the given texture
 * at the given level.
 */
static unsigned r300_texture_get_stride(struct r300_screen *screen,
                                        struct r300_texture_desc *desc,
                                        unsigned level)
{
    unsigned tile_width, width, stride;

    if (desc->stride_in_bytes_override)
        return desc->stride_in_bytes_override;

    /* Check the level. */
    if (level > desc->b.b.last_level) {
        SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n",
                   __FUNCTION__, level, desc->b.b.last_level);
        return 0;
    }

    width = u_minify(desc->b.b.width0, level);

    if (util_format_is_plain(desc->b.b.format)) {
        tile_width = r300_get_pixel_alignment(desc->b.b.format,
                                              desc->b.b.nr_samples,
                                              desc->microtile,
                                              desc->macrotile[level],
                                              DIM_WIDTH);
        width = align(width, tile_width);

        stride = util_format_get_stride(desc->b.b.format, width);

        /* Some IGPs need a minimum stride of 64 bytes, hmm... */
        if (!desc->macrotile[level] &&
            (screen->caps.family == CHIP_FAMILY_RS600 ||
             screen->caps.family == CHIP_FAMILY_RS690 ||
             screen->caps.family == CHIP_FAMILY_RS740)) {
            unsigned min_stride;

            if (desc->microtile) {
                unsigned tile_height =
                        r300_get_pixel_alignment(desc->b.b.format,
                                                 desc->b.b.nr_samples,
                                                 desc->microtile,
                                                 desc->macrotile[level],
                                                 DIM_HEIGHT);

                min_stride = 64 / tile_height;
            } else {
                min_stride = 64;
            }

            return stride < min_stride ? min_stride : stride;
        }

        /* The alignment to 32 bytes is sort of implied by the layout... */
        return stride;
    } else {
        return align(util_format_get_stride(desc->b.b.format, width), 32);
    }
}
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 r600_setup_miptree(struct r600_screen *rscreen, struct r600_resource_texture *rtex)
{
	struct pipe_resource *ptex = &rtex->resource.base.b;
	unsigned long w, h, pitch, size, layer_size, i, offset;

	rtex->bpt = util_format_get_blocksize(ptex->format);
	for (i = 0, offset = 0; i <= ptex->last_level; i++) {
		w = u_minify(ptex->width0, i);
		h = u_minify(ptex->height0, i);
		h = util_next_power_of_two(h);
		pitch = util_format_get_stride(ptex->format, align(w, 64));
		pitch = align(pitch, 256);
		layer_size = pitch * h;
		if (ptex->target == PIPE_TEXTURE_CUBE)
			size = layer_size * 6;
		else
			size = layer_size * u_minify(ptex->depth0, i);
		rtex->offset[i] = offset;
		rtex->layer_size[i] = layer_size;
		rtex->pitch[i] = pitch;
		rtex->width[i] = w;
		rtex->height[i] = h;
		offset += size;
	}
	rtex->size = offset;
}
/**
 * Special case to deal with scanout textures.
 */
static boolean
i9x5_scanout_layout(struct i915_texture *tex)
{
   struct pipe_resource *pt = &tex->b.b;

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

   i915_texture_set_level_info(tex, 0, 1);
   i915_texture_set_image_offset(tex, 0, 0, 0, 0);

   if (pt->width0 >= 240) {
      tex->stride = align(util_format_get_stride(pt->format, pt->width0), 64);
      tex->total_nblocksy = align_nblocksy(pt->format, pt->height0, 8);
      tex->tiling = I915_TILE_X;
   /* special case for cursors */
   } else if (pt->width0 == 64 && pt->height0 == 64) {
      tex->stride = get_pot_stride(pt->format, pt->width0);
      tex->total_nblocksy = align_nblocksy(pt->format, pt->height0, 8);
   } else {
      return FALSE;
   }

#if DEBUG_TEXTURE
   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);
#endif

   return TRUE;
}
static void *
nv30_vertex_state_create(struct pipe_context *pipe, unsigned num_elements,
                         const struct pipe_vertex_element *elements)
{
    struct nv30_vertex_stateobj *so;
    struct translate_key transkey;
    unsigned i;

    assert(num_elements);

    so = MALLOC(sizeof(*so) + sizeof(*so->element) * num_elements);
    if (!so)
        return NULL;
    memcpy(so->pipe, elements, sizeof(*elements) * num_elements);
    so->num_elements = num_elements;
    so->need_conversion = FALSE;

    transkey.nr_elements = 0;
    transkey.output_stride = 0;

    for (i = 0; i < num_elements; i++) {
        const struct pipe_vertex_element *ve = &elements[i];
        const unsigned vbi = ve->vertex_buffer_index;
        enum pipe_format fmt = ve->src_format;

        so->element[i].state = nv30_vtxfmt(pipe->screen, fmt)->hw;
        if (!so->element[i].state) {
            switch (util_format_get_nr_components(fmt)) {
            case 1: fmt = PIPE_FORMAT_R32_FLOAT; break;
            case 2: fmt = PIPE_FORMAT_R32G32_FLOAT; break;
            case 3: fmt = PIPE_FORMAT_R32G32B32_FLOAT; break;
            case 4: fmt = PIPE_FORMAT_R32G32B32A32_FLOAT; break;
            default:
                assert(0);
                return NULL;
            }
            so->element[i].state = nv30_vtxfmt(pipe->screen, fmt)->hw;
            so->need_conversion = TRUE;
        }

        if (1) {
            unsigned j = transkey.nr_elements++;

            transkey.element[j].type = TRANSLATE_ELEMENT_NORMAL;
            transkey.element[j].input_format = ve->src_format;
            transkey.element[j].input_buffer = vbi;
            transkey.element[j].input_offset = ve->src_offset;
            transkey.element[j].instance_divisor = ve->instance_divisor;

            transkey.element[j].output_format = fmt;
            transkey.element[j].output_offset = transkey.output_stride;
            transkey.output_stride += (util_format_get_stride(fmt, 1) + 3) & ~3;
        }
    }

    so->translate = translate_create(&transkey);
    so->vtx_size = transkey.output_stride / 4;
    so->vtx_per_packet_max = NV04_PFIFO_MAX_PACKET_LEN / MAX2(so->vtx_size, 1);
    return so;
}
/**
 * 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;
}
static unsigned
nvfx_miptree_layout(struct nvfx_miptree *mt)
{
	struct pipe_resource* pt = &mt->base.base;
        uint offset = 0;

	if(!nvfx_screen(pt->screen)->is_nv4x)
	{
		assert(pt->target == PIPE_TEXTURE_RECT
			|| (util_is_power_of_two(pt->width0) && util_is_power_of_two(pt->height0)));
	}

	for (unsigned l = 0; l <= pt->last_level; l++)
	{
		unsigned size;
		mt->level_offset[l] = offset;

		if(mt->linear_pitch)
			size = mt->linear_pitch;
		else
			size = util_format_get_stride(pt->format, u_minify(pt->width0, l));
		size = util_format_get_2d_size(pt->format, size, u_minify(pt->height0, l));

		if(pt->target == PIPE_TEXTURE_3D)
			size *= u_minify(pt->depth0, l);

		offset += size;
	}

	offset = align(offset, 128);
	mt->face_size = offset;
	if(mt->base.base.target == PIPE_TEXTURE_CUBE)
		offset += 5 * mt->face_size;
	return offset;
}
/**
 * Special case to deal with shared textures.
 */
static boolean
i9x5_display_target_layout(struct i915_texture *tex)
{
   struct pipe_resource *pt = &tex->b.b;

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

   /* fallback to normal textures for small textures */
   if (pt->width0 < 240)
      return FALSE;

   i915_texture_set_level_info(tex, 0, 1);
   i915_texture_set_image_offset(tex, 0, 0, 0, 0);

   tex->stride = align(util_format_get_stride(pt->format, pt->width0), 64);
   tex->total_nblocksy = align_nblocksy(pt->format, pt->height0, 8);
   tex->tiling = I915_TILE_X;

#if DEBUG_TEXTURE
   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);
#endif

   return TRUE;
}
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);
   }
}
Exemple #12
0
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);
   }
}
Exemple #13
0
/**
 * gl_renderbuffer::AllocStorage()
 * This is called to allocate the original drawing surface, and
 * during window resize.
 */
static GLboolean
st_renderbuffer_alloc_storage(struct gl_context * ctx,
                              struct gl_renderbuffer *rb,
                              GLenum internalFormat,
                              GLuint width, GLuint height)
{
   struct st_context *st = st_context(ctx);
   struct pipe_context *pipe = st->pipe;
   struct pipe_screen *screen = st->pipe->screen;
   struct st_renderbuffer *strb = st_renderbuffer(rb);
   enum pipe_format format;
   struct pipe_surface surf_tmpl;

   format = st_choose_renderbuffer_format(screen, internalFormat,
                                          rb->NumSamples);

   if (format == PIPE_FORMAT_NONE) {
      return FALSE;
   }

   /* init renderbuffer fields */
   strb->Base.Width  = width;
   strb->Base.Height = height;
   strb->Base.Format = st_pipe_format_to_mesa_format(format);
   strb->Base._BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
   strb->Base.DataType = st_format_datatype(format);
   strb->format = format;

   strb->defined = GL_FALSE;  /* undefined contents now */

   if (strb->software) {
      size_t size;
      
      free(strb->data);

      assert(strb->format != PIPE_FORMAT_NONE);
      
      strb->stride = util_format_get_stride(strb->format, width);
      size = util_format_get_2d_size(strb->format, strb->stride, height);
      
      strb->data = malloc(size);
      
      return strb->data != NULL;
   }
   else {
      struct pipe_resource template;
    
      /* Free the old surface and texture
       */
      pipe_surface_reference( &strb->surface, NULL );
      pipe_resource_reference( &strb->texture, NULL );
      pipe_sampler_view_reference(&strb->sampler_view, NULL);

      /* Setup new texture template.
       */
      memset(&template, 0, sizeof(template));
Exemple #14
0
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);
}
Exemple #15
0
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);
}
Exemple #16
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,
                         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;
   }
}
Exemple #17
0
static struct sw_displaytarget *
HiddVC4CreateDisplaytarget(struct sw_winsys *winsys, unsigned tex_usage,
    enum pipe_format format, unsigned width, unsigned height,
    unsigned alignment, unsigned *stride)
{
    struct HiddVC4Displaytarget * spdt = 
        AllocVec(sizeof(struct HiddVC4Displaytarget), MEMF_PUBLIC | MEMF_CLEAR);
    
    *stride = align(util_format_get_stride(format, width), alignment);
    spdt->data = AllocVec(*stride * height, MEMF_PUBLIC | MEMF_CLEAR);
    
    return (struct sw_displaytarget *)spdt;
}
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;
}
Exemple #19
0
/**
 * Return the stride, in bytes, of the texture image of the given texture
 * at the given level.
 */
static unsigned r300_texture_get_stride(struct r300_screen *screen,
                                        struct r300_resource *tex,
                                        unsigned level)
{
    unsigned tile_width, width, stride;
    boolean is_rs690 = (screen->caps.family == CHIP_FAMILY_RS600 ||
                        screen->caps.family == CHIP_FAMILY_RS690 ||
                        screen->caps.family == CHIP_FAMILY_RS740);

    if (tex->tex.stride_in_bytes_override)
        return tex->tex.stride_in_bytes_override;

    /* Check the level. */
    if (level > tex->b.b.b.last_level) {
        SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n",
                   __FUNCTION__, level, tex->b.b.b.last_level);
        return 0;
    }

    width = u_minify(tex->tex.width0, level);

    if (util_format_is_plain(tex->b.b.b.format)) {
        tile_width = r300_get_pixel_alignment(tex->b.b.b.format,
                                              tex->b.b.b.nr_samples,
                                              tex->tex.microtile,
                                              tex->tex.macrotile[level],
                                              DIM_WIDTH, is_rs690);
        width = align(width, tile_width);

        stride = util_format_get_stride(tex->b.b.b.format, width);
        /* The alignment to 32 bytes is sort of implied by the layout... */
        return stride;
    } else {
        return align(util_format_get_stride(tex->b.b.b.format, width), is_rs690 ? 64 : 32);
    }
}
static void
nvfx_miptree_choose_format(struct nvfx_miptree *mt)
{
	struct pipe_resource *pt = &mt->base.base;
	unsigned uniform_pitch = 0;
	static int no_swizzle = -1;
	if(no_swizzle < 0)
		no_swizzle = debug_get_bool_option("NV40_NO_SWIZZLE", FALSE); /* this will break things on nv30 */

	if (!util_is_power_of_two(pt->width0) ||
	    !util_is_power_of_two(pt->height0) ||
	    !util_is_power_of_two(pt->depth0) ||
	    (!nvfx_screen(pt->screen)->is_nv4x && pt->target == PIPE_TEXTURE_RECT)
	    )
		uniform_pitch = 1;

	if (
		(pt->bind & (PIPE_BIND_SCANOUT | PIPE_BIND_DISPLAY_TARGET))
		|| (pt->usage & PIPE_USAGE_DYNAMIC) || (pt->usage & PIPE_USAGE_STAGING)
		|| util_format_is_compressed(pt->format)
		|| no_swizzle
	)
		mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR;

	/* non compressed formats with uniform pitch must be linear, and vice versa */
	if(!util_format_is_s3tc(pt->format)
		&& (uniform_pitch || mt->base.base.flags & NVFX_RESOURCE_FLAG_LINEAR))
	{
		mt->base.base.flags |= NVFX_RESOURCE_FLAG_LINEAR;
		uniform_pitch = 1;
	}

	if(uniform_pitch)
	{
		mt->linear_pitch = util_format_get_stride(pt->format, pt->width0);

		// TODO: this is only a constraint for rendering and not sampling, apparently
		// we may also want this unconditionally
		if(pt->bind & (PIPE_BIND_SAMPLER_VIEW |
			PIPE_BIND_DEPTH_STENCIL |
			PIPE_BIND_RENDER_TARGET |
			PIPE_BIND_DISPLAY_TARGET |
			PIPE_BIND_SCANOUT))
			mt->linear_pitch = align(mt->linear_pitch, 64);
	}
	else
		mt->linear_pitch = 0;
}
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;
      }
Exemple #22
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;
}
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);
}
Exemple #24
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);
}
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;
}
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;
	}
}
Exemple #27
0
static struct pipe_resource *noop_resource_create(struct pipe_screen *screen,
						const struct pipe_resource *templ)
{
	struct noop_resource *nresource;
	unsigned stride;

	nresource = CALLOC_STRUCT(noop_resource);
	if (nresource == NULL)
		return NULL;

	stride = util_format_get_stride(templ->format, templ->width0);
	nresource->base = *templ;
	nresource->base.screen = screen;
	nresource->size = stride * templ->height0 * templ->depth0;
	nresource->data = MALLOC(nresource->size);
	pipe_reference_init(&nresource->base.reference, 1);
	if (nresource->data == NULL) {
		FREE(nresource);
		return NULL;
	}
	return &nresource->base;
}
Exemple #28
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;
}
Exemple #29
0
static uint32_t vtest_get_transfer_size(struct virgl_hw_res *res,
                                        const struct pipe_box *box,
                                        uint32_t stride, uint32_t layer_stride,
                                        uint32_t level, uint32_t *valid_stride_p)
{
   uint32_t valid_stride, valid_layer_stride;

   valid_stride = util_format_get_stride(res->format, box->width);
   if (stride) {
      if (box->height > 1)
         valid_stride = stride;
   }

   valid_layer_stride = util_format_get_2d_size(res->format, valid_stride,
                                                box->height);
   if (layer_stride) {
      if (box->depth > 1)
         valid_layer_stride = layer_stride;
   }

   *valid_stride_p = valid_stride;
   return valid_layer_stride * box->depth;
}
Exemple #30
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;
}