/** * 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); } }
/** * 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); } }
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); } }
/** * 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));
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); }
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); }
/** * 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; } }
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; }
/** * 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; }
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); }
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; } }
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; }
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; }
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; }
/** * 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; }