static boolean llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, struct llvmpipe_resource *lpr) { struct sw_winsys *winsys = screen->winsys; /* Round up the surface size to a multiple of the tile size to * avoid tile clipping. */ const unsigned width = align(lpr->base.width0, TILE_SIZE); const unsigned height = align(lpr->base.height0, TILE_SIZE); const unsigned width_t = width / TILE_SIZE; const unsigned height_t = height / TILE_SIZE; lpr->tiles_per_row[0] = width_t; lpr->tiles_per_image[0] = width_t * height_t; lpr->num_slices_faces[0] = 1; lpr->img_stride[0] = 0; lpr->layout[0] = alloc_layout_array(1, width, height); //lpr->layout[0][0] = LP_TEX_LAYOUT_LINEAR; lpr->dt = winsys->displaytarget_create(winsys, lpr->base.bind, lpr->base.format, width, height, 16, &lpr->row_stride[0] ); return lpr->dt != NULL; }
static boolean llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, struct llvmpipe_resource *lpr) { struct sw_winsys *winsys = screen->winsys; /* Round up the surface size to a multiple of the tile size to * avoid tile clipping. */ const unsigned width = align(lpr->base.width0, TILE_SIZE); const unsigned height = align(lpr->base.height0, TILE_SIZE); const unsigned width_t = width / TILE_SIZE; const unsigned height_t = height / TILE_SIZE; lpr->tiles_per_row[0] = width_t; lpr->tiles_per_image[0] = width_t * height_t; lpr->num_slices_faces[0] = 1; lpr->img_stride[0] = 0; lpr->layout[0] = alloc_layout_array(1, width, height); if (!lpr->layout[0]) { return FALSE; } lpr->dt = winsys->displaytarget_create(winsys, lpr->base.bind, lpr->base.format, width, height, 16, &lpr->row_stride[0] ); if (lpr->dt == NULL) return FALSE; { void *map = winsys->displaytarget_map(winsys, lpr->dt, PIPE_TRANSFER_WRITE); if (map) memset(map, 0, height * lpr->row_stride[0]); winsys->displaytarget_unmap(winsys, lpr->dt); } return TRUE; }
/** * Conventional allocation path for non-display textures: * Just compute row strides here. Storage is allocated on demand later. */ static boolean llvmpipe_texture_layout(struct llvmpipe_screen *screen, struct llvmpipe_resource *lpr) { struct pipe_resource *pt = &lpr->base; unsigned level; unsigned width = pt->width0; unsigned height = pt->height0; unsigned depth = pt->depth0; size_t total_size = 0; assert(LP_MAX_TEXTURE_2D_LEVELS <= LP_MAX_TEXTURE_LEVELS); assert(LP_MAX_TEXTURE_3D_LEVELS <= LP_MAX_TEXTURE_LEVELS); for (level = 0; level <= pt->last_level; level++) { /* Row stride and image stride (for linear layout) */ { unsigned alignment, nblocksx, nblocksy, block_size; /* For non-compressed formats we need to align the texture size * to the tile size to facilitate render-to-texture. */ if (util_format_is_compressed(pt->format)) alignment = 1; else alignment = TILE_SIZE; nblocksx = util_format_get_nblocksx(pt->format, align(width, alignment)); nblocksy = util_format_get_nblocksy(pt->format, align(height, alignment)); block_size = util_format_get_blocksize(pt->format); lpr->row_stride[level] = align(nblocksx * block_size, 16); lpr->img_stride[level] = lpr->row_stride[level] * nblocksy; } /* Size of the image in tiles (for tiled layout) */ { const unsigned width_t = align(width, TILE_SIZE) / TILE_SIZE; const unsigned height_t = align(height, TILE_SIZE) / TILE_SIZE; lpr->tiles_per_row[level] = width_t; lpr->tiles_per_image[level] = width_t * height_t; } /* Number of 3D image slices or cube faces */ { unsigned num_slices; if (lpr->base.target == PIPE_TEXTURE_CUBE) num_slices = 6; else if (lpr->base.target == PIPE_TEXTURE_3D) num_slices = depth; else num_slices = 1; lpr->num_slices_faces[level] = num_slices; lpr->layout[level] = alloc_layout_array(num_slices, width, height); if (!lpr->layout[level]) { goto fail; } } total_size += lpr->num_slices_faces[level] * lpr->img_stride[level]; if (total_size > LP_MAX_TEXTURE_SIZE) { goto fail; } /* Compute size of next mipmap level */ width = u_minify(width, 1); height = u_minify(height, 1); depth = u_minify(depth, 1); } return TRUE; fail: for (level = 0; level <= pt->last_level; level++) { FREE(lpr->layout[level]); } return FALSE; }