1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/************************************************************************** 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved. 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish, 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions: 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software. 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/ 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Authors: 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Keith Whitwell <keith@tungstengraphics.com> 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Michel Dänzer <michel@tungstengraphics.com> 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdio.h> 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_context.h" 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_defines.h" 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_inlines.h" 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_cpu_detect.h" 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_format.h" 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_math.h" 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h" 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_simple_list.h" 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_transfer.h" 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_context.h" 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_flush.h" 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_screen.h" 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_tile_image.h" 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_texture.h" 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_setup.h" 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_state.h" 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "state_tracker/sw_winsys.h" 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct llvmpipe_resource resource_list; 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned id_counter = 0; 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE boolean 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgresource_is_texture(const struct pipe_resource *resource) 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (resource->target) { 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PIPE_BUFFER: 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return FALSE; 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PIPE_TEXTURE_1D: 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PIPE_TEXTURE_2D: 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PIPE_TEXTURE_RECT: 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PIPE_TEXTURE_3D: 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case PIPE_TEXTURE_CUBE: 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return TRUE; 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return FALSE; 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Allocate storage for llvmpipe_texture::layout array. 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The number of elements is width_in_tiles * height_in_tiles. 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic enum lp_texture_layout * 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgalloc_layout_array(unsigned num_slices, unsigned width, unsigned height) 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned tx = align(width, TILE_SIZE) / TILE_SIZE; 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned ty = align(height, TILE_SIZE) / TILE_SIZE; 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(num_slices * tx * ty > 0); 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(LP_TEX_LAYOUT_NONE == 0); /* calloc'ing LP_TEX_LAYOUT_NONE here */ 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (enum lp_texture_layout *) 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CALLOC(num_slices * tx * ty, sizeof(enum lp_texture_layout)); 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Conventional allocation path for non-display textures: 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Just compute row strides here. Storage is allocated on demand later. 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_texture_layout(struct llvmpipe_screen *screen, 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_resource *lpr) 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_resource *pt = &lpr->base; 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned level; 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned width = pt->width0; 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned height = pt->height0; 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned depth = pt->depth0; 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size_t total_size = 0; 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(LP_MAX_TEXTURE_2D_LEVELS <= LP_MAX_TEXTURE_LEVELS); 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(LP_MAX_TEXTURE_3D_LEVELS <= LP_MAX_TEXTURE_LEVELS); 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (level = 0; level <= pt->last_level; level++) { 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Row stride and image stride (for linear layout) */ 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned alignment, nblocksx, nblocksy, block_size; 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* For non-compressed formats we need to align the texture size 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to the tile size to facilitate render-to-texture. 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (util_format_is_compressed(pt->format)) 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org alignment = 1; 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org alignment = TILE_SIZE; 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nblocksx = util_format_get_nblocksx(pt->format, 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org align(width, alignment)); 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org nblocksy = util_format_get_nblocksy(pt->format, 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org align(height, alignment)); 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org block_size = util_format_get_blocksize(pt->format); 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->row_stride[level] = align(nblocksx * block_size, 16); 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->img_stride[level] = lpr->row_stride[level] * nblocksy; 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Size of the image in tiles (for tiled layout) */ 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned width_t = align(width, TILE_SIZE) / TILE_SIZE; 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned height_t = align(height, TILE_SIZE) / TILE_SIZE; 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->tiles_per_row[level] = width_t; 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->tiles_per_image[level] = width_t * height_t; 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Number of 3D image slices or cube faces */ 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned num_slices; 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lpr->base.target == PIPE_TEXTURE_CUBE) 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_slices = 6; 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (lpr->base.target == PIPE_TEXTURE_3D) 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_slices = depth; 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org num_slices = 1; 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->num_slices_faces[level] = num_slices; 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->layout[level] = alloc_layout_array(num_slices, width, height); 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!lpr->layout[level]) { 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto fail; 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org total_size += lpr->num_slices_faces[level] * lpr->img_stride[level]; 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (total_size > LP_MAX_TEXTURE_SIZE) { 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto fail; 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Compute size of next mipmap level */ 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org width = u_minify(width, 1); 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org height = u_minify(height, 1); 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org depth = u_minify(depth, 1); 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return TRUE; 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfail: 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (level = 0; level <= pt->last_level; level++) { 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lpr->layout[level]) { 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(lpr->layout[level]); 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return FALSE; 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_resource *lpr) 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct sw_winsys *winsys = screen->winsys; 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Round up the surface size to a multiple of the tile size to 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * avoid tile clipping. 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned width = align(lpr->base.width0, TILE_SIZE); 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned height = align(lpr->base.height0, TILE_SIZE); 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned width_t = width / TILE_SIZE; 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned height_t = height / TILE_SIZE; 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->tiles_per_row[0] = width_t; 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->tiles_per_image[0] = width_t * height_t; 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->num_slices_faces[0] = 1; 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->img_stride[0] = 0; 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->layout[0] = alloc_layout_array(1, width, height); 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!lpr->layout[0]) { 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return FALSE; 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->dt = winsys->displaytarget_create(winsys, 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->base.bind, 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->base.format, 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org width, height, 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 16, 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &lpr->row_stride[0] ); 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lpr->dt == NULL) 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return FALSE; 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *map = winsys->displaytarget_map(winsys, lpr->dt, 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PIPE_TRANSFER_WRITE); 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (map) 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(map, 0, height * lpr->row_stride[0]); 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org winsys->displaytarget_unmap(winsys, lpr->dt); 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return TRUE; 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct pipe_resource * 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_resource_create(struct pipe_screen *_screen, 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct pipe_resource *templat) 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_screen *screen = llvmpipe_screen(_screen); 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_resource *lpr = CALLOC_STRUCT(llvmpipe_resource); 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!lpr) 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->base = *templat; 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_reference_init(&lpr->base.reference, 1); 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->base.screen = &screen->base; 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* assert(lpr->base.bind); */ 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (resource_is_texture(&lpr->base)) { 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lpr->base.bind & PIPE_BIND_DISPLAY_TARGET) { 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* displayable surface */ 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!llvmpipe_displaytarget_layout(screen, lpr)) 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto fail; 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(lpr->layout[0][0] == LP_TEX_LAYOUT_NONE); 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* texture map */ 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!llvmpipe_texture_layout(screen, lpr)) 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto fail; 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(lpr->layout[0][0] == LP_TEX_LAYOUT_NONE); 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(lpr->layout[0]); 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* other data (vertex buffer, const buffer, etc) */ 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const enum pipe_format format = templat->format; 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const uint w = templat->width0 / util_format_get_blockheight(format); 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* XXX buffers should only have one dimension, those values should be 1 */ 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const uint h = templat->height0 / util_format_get_blockwidth(format); 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const uint d = templat->depth0; 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const uint bpp = util_format_get_blocksize(format); 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const uint bytes = w * h * d * bpp; 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->data = align_malloc(bytes, 16); 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!lpr->data) 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto fail; 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(lpr->data, 0, bytes); 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->id = id_counter++; 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insert_at_tail(&resource_list, lpr); 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &lpr->base; 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fail: 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(lpr); 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_resource_destroy(struct pipe_screen *pscreen, 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_resource *pt) 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_screen *screen = llvmpipe_screen(pscreen); 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_resource *lpr = llvmpipe_resource(pt); 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lpr->dt) { 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* display target */ 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct sw_winsys *winsys = screen->winsys; 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org winsys->displaytarget_destroy(winsys, lpr->dt); 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lpr->tiled[0].data) { 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org align_free(lpr->tiled[0].data); 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->tiled[0].data = NULL; 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(lpr->layout[0]); 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (resource_is_texture(pt)) { 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* regular texture */ 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint level; 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* free linear image data */ 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (level = 0; level < Elements(lpr->linear); level++) { 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lpr->linear[level].data) { 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org align_free(lpr->linear[level].data); 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->linear[level].data = NULL; 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* free tiled image data */ 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (level = 0; level < Elements(lpr->tiled); level++) { 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lpr->tiled[level].data) { 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org align_free(lpr->tiled[level].data); 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->tiled[level].data = NULL; 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* free layout flag arrays */ 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (level = 0; level < Elements(lpr->tiled); level++) { 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(lpr->layout[level]); 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->layout[level] = NULL; 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (!lpr->userBuffer) { 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(lpr->data); 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org align_free(lpr->data); 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lpr->next) 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org remove_from_list(lpr); 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(lpr); 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Map a resource for read/write. 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid * 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_resource_map(struct pipe_resource *resource, 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned level, 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned layer, 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_usage tex_usage, 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_layout layout) 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_resource *lpr = llvmpipe_resource(resource); 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint8_t *map; 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(level < LP_MAX_TEXTURE_LEVELS); 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(layer < (u_minify(resource->depth0, level) + resource->array_size - 1)); 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(tex_usage == LP_TEX_USAGE_READ || 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex_usage == LP_TEX_USAGE_READ_WRITE || 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex_usage == LP_TEX_USAGE_WRITE_ALL); 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(layout == LP_TEX_LAYOUT_NONE || 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org layout == LP_TEX_LAYOUT_TILED || 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org layout == LP_TEX_LAYOUT_LINEAR); 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lpr->dt) { 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* display target */ 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_screen *screen = llvmpipe_screen(resource->screen); 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct sw_winsys *winsys = screen->winsys; 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned dt_usage; 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint8_t *map2; 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tex_usage == LP_TEX_USAGE_READ) { 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dt_usage = PIPE_TRANSFER_READ; 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dt_usage = PIPE_TRANSFER_READ_WRITE; 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(level == 0); 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(layer == 0); 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* FIXME: keep map count? */ 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map = winsys->displaytarget_map(winsys, lpr->dt, dt_usage); 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* install this linear image in texture data structure */ 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->linear[level].data = map; 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* make sure tiled data gets converted to linear data */ 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map2 = llvmpipe_get_texture_image(lpr, 0, 0, tex_usage, layout); 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (layout == LP_TEX_LAYOUT_LINEAR) 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(map == map2); 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return map2; 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (resource_is_texture(resource)) { 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map = llvmpipe_get_texture_image(lpr, layer, level, 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex_usage, layout); 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return map; 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return lpr->data; 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Unmap a resource. 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_resource_unmap(struct pipe_resource *resource, 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned level, 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned layer) 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_resource *lpr = llvmpipe_resource(resource); 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lpr->dt) { 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* display target */ 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_screen *lp_screen = llvmpipe_screen(resource->screen); 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct sw_winsys *winsys = lp_screen->winsys; 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(level == 0); 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(layer == 0); 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* make sure linear image is up to date */ 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void) llvmpipe_get_texture_image(lpr, layer, level, 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LP_TEX_USAGE_READ, 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LP_TEX_LAYOUT_LINEAR); 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org winsys->displaytarget_unmap(winsys, lpr->dt); 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid * 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_resource_data(struct pipe_resource *resource) 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_resource *lpr = llvmpipe_resource(resource); 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(!resource_is_texture(resource)); 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return lpr->data; 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct pipe_resource * 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_resource_from_handle(struct pipe_screen *screen, 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct pipe_resource *template, 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct winsys_handle *whandle) 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys; 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_resource *lpr; 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned width, height, width_t, height_t; 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* XXX Seems like from_handled depth textures doesn't work that well */ 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr = CALLOC_STRUCT(llvmpipe_resource); 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!lpr) { 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto no_lpr; 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->base = *template; 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_reference_init(&lpr->base.reference, 1); 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->base.screen = screen; 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org width = align(lpr->base.width0, TILE_SIZE); 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org height = align(lpr->base.height0, TILE_SIZE); 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org width_t = width / TILE_SIZE; 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org height_t = height / TILE_SIZE; 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Looks like unaligned displaytargets work just fine, 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * at least sampler/render ones. 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(lpr->base.width0 == width); 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(lpr->base.height0 == height); 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->tiles_per_row[0] = width_t; 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->tiles_per_image[0] = width_t * height_t; 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->num_slices_faces[0] = 1; 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->img_stride[0] = 0; 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->dt = winsys->displaytarget_from_handle(winsys, 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org template, 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org whandle, 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &lpr->row_stride[0]); 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!lpr->dt) { 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto no_dt; 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->layout[0] = alloc_layout_array(1, lpr->base.width0, lpr->base.height0); 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!lpr->layout[0]) { 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto no_layout_0; 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(lpr->layout[0][0] == LP_TEX_LAYOUT_NONE); 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->id = id_counter++; 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org insert_at_tail(&resource_list, lpr); 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &lpr->base; 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgno_layout_0: 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org winsys->displaytarget_destroy(winsys, lpr->dt); 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgno_dt: 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(lpr); 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgno_lpr: 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_resource_get_handle(struct pipe_screen *screen, 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_resource *pt, 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct winsys_handle *whandle) 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys; 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_resource *lpr = llvmpipe_resource(pt); 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(lpr->dt); 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!lpr->dt) 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return FALSE; 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return winsys->displaytarget_get_handle(winsys, lpr->dt, whandle); 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct pipe_surface * 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_create_surface(struct pipe_context *pipe, 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_resource *pt, 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct pipe_surface *surf_tmpl) 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_surface *ps; 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(surf_tmpl->u.tex.level <= pt->last_level); 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ps = CALLOC_STRUCT(pipe_surface); 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ps) { 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_reference_init(&ps->reference, 1); 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_resource_reference(&ps->texture, pt); 568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ps->context = pipe; 569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ps->format = surf_tmpl->format; 570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level); 571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level); 572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ps->usage = surf_tmpl->usage; 573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ps->u.tex.level = surf_tmpl->u.tex.level; 575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer; 576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer; 577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ps; 579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_surface_destroy(struct pipe_context *pipe, 584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_surface *surf) 585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Effectively do the texture_update work here - if texture images 587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * needed post-processing to put them into hardware layout, this is 588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * where it would happen. For llvmpipe, nothing to do. 589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(surf->texture); 591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_resource_reference(&surf->texture, NULL); 592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(surf); 593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct pipe_transfer * 597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_get_transfer(struct pipe_context *pipe, 598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_resource *resource, 599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned level, 600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned usage, 601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct pipe_box *box) 602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_resource *lprex = llvmpipe_resource(resource); 605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_transfer *lpr; 606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(resource); 608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(level <= resource->last_level); 609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Transfers, like other pipe operations, must happen in order, so flush the 612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * context if necessary. 613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) { 615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean read_only = !(usage & PIPE_TRANSFER_WRITE); 616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean do_not_block = !!(usage & PIPE_TRANSFER_DONTBLOCK); 617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!llvmpipe_flush_resource(pipe, resource, 618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org level, 619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org box->depth > 1 ? -1 : box->z, 620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org read_only, 621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TRUE, /* cpu_access */ 622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org do_not_block, 623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org __FUNCTION__)) { 624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * It would have blocked, but state tracker requested no to. 626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(do_not_block); 628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (resource == llvmpipe->constants[PIPE_SHADER_FRAGMENT][0]) 633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org llvmpipe->dirty |= LP_NEW_CONSTANTS; 634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr = CALLOC_STRUCT(llvmpipe_transfer); 636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lpr) { 637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_transfer *pt = &lpr->base; 638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_resource_reference(&pt->resource, resource); 639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pt->box = *box; 640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pt->level = level; 641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pt->stride = lprex->row_stride[level]; 642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pt->layer_stride = lprex->img_stride[level]; 643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pt->usage = usage; 644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return pt; 646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_transfer_destroy(struct pipe_context *pipe, 653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_transfer *transfer) 654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Effectively do the texture_update work here - if texture images 656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * needed post-processing to put them into hardware layout, this is 657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * where it would happen. For llvmpipe, nothing to do. 658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert (transfer->resource); 660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_resource_reference(&transfer->resource, NULL); 661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(transfer); 662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void * 666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_transfer_map( struct pipe_context *pipe, 667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_transfer *transfer ) 668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen); 670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ubyte *map; 671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_resource *lpr; 672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum pipe_format format; 673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_usage tex_usage; 674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *mode; 675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(transfer->level < LP_MAX_TEXTURE_LEVELS); 677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("tex_transfer_map(%d, %d %d x %d of %d x %d, usage %d )\n", 680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transfer->x, transfer->y, transfer->width, transfer->height, 681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transfer->texture->width0, 682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transfer->texture->height0, 683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transfer->usage); 684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (transfer->usage == PIPE_TRANSFER_READ) { 687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex_usage = LP_TEX_USAGE_READ; 688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mode = "read"; 689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex_usage = LP_TEX_USAGE_READ_WRITE; 692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mode = "read/write"; 693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (0) { 696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_resource *lpr = llvmpipe_resource(transfer->resource); 697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org printf("transfer map tex %u mode %s\n", lpr->id, mode); 698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(transfer->resource); 702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr = llvmpipe_resource(transfer->resource); 703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org format = lpr->base.format; 704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map = llvmpipe_resource_map(transfer->resource, 706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transfer->level, 707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transfer->box.z, 708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tex_usage, LP_TEX_LAYOUT_LINEAR); 709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* May want to do different things here depending on read/write nature 712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the map: 713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (transfer->usage & PIPE_TRANSFER_WRITE) { 715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Do something to notify sharing contexts of a texture change. 716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org screen->timestamp++; 718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map += 721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transfer->box.y / util_format_get_blockheight(format) * transfer->stride + 722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); 723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return map; 725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_transfer_unmap(struct pipe_context *pipe, 730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_transfer *transfer) 731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(transfer->resource); 733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org llvmpipe_resource_unmap(transfer->resource, 735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transfer->level, 736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org transfer->box.z); 737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned int 740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_is_resource_referenced( struct pipe_context *pipe, 741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_resource *presource, 742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned level, int layer) 743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); 745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (presource->target == PIPE_BUFFER) 747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return LP_UNREFERENCED; 748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return lp_setup_is_resource_referenced(llvmpipe->setup, presource); 750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Create buffer which wraps user-space data. 756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pipe_resource * 758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_user_buffer_create(struct pipe_screen *screen, 759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ptr, 760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned bytes, 761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned bind_flags) 762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_resource *buffer; 764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer = CALLOC_STRUCT(llvmpipe_resource); 766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!buffer) 767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_reference_init(&buffer->base.reference, 1); 770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->base.screen = screen; 771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */ 772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->base.bind = bind_flags; 773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->base.usage = PIPE_USAGE_IMMUTABLE; 774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->base.flags = 0; 775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->base.width0 = bytes; 776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->base.height0 = 1; 777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->base.depth0 = 1; 778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->base.array_size = 1; 779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->userBuffer = TRUE; 780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org buffer->data = ptr; 781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return &buffer->base; 783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute size (in bytes) need to store a texture image / mipmap level, 788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * for just one cube face or one 3D texture slice 789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned 791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtex_image_face_size(const struct llvmpipe_resource *lpr, unsigned level, 792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_layout layout) 793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned width = u_minify(lpr->base.width0, level); 795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned height = u_minify(lpr->base.height0, level); 796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(layout == LP_TEX_LAYOUT_TILED || 798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org layout == LP_TEX_LAYOUT_LINEAR); 799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (layout == LP_TEX_LAYOUT_TILED) { 801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* for tiled layout, force a 32bpp format */ 802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const enum pipe_format format = PIPE_FORMAT_B8G8R8A8_UNORM; 803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned block_size = util_format_get_blocksize(format); 804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned nblocksy = 805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org util_format_get_nblocksy(format, align(height, TILE_SIZE)); 806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned nblocksx = 807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org util_format_get_nblocksx(format, align(width, TILE_SIZE)); 808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned buffer_size = block_size * nblocksy * nblocksx; 809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return buffer_size; 810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* we already computed this */ 813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return lpr->img_stride[level]; 814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute size (in bytes) need to store a texture image / mipmap level, 820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * including all cube faces or 3D image slices 821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned 823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtex_image_size(const struct llvmpipe_resource *lpr, unsigned level, 824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_layout layout) 825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned buf_size = tex_image_face_size(lpr, level, layout); 827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return buf_size * lpr->num_slices_faces[level]; 828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This function encapsulates some complicated logic for determining 833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * how to convert a tile of image data from linear layout to tiled 834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * layout, or vice versa. 835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param cur_layout the current tile layout 836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param target_layout the desired tile layout 837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param usage how the tile will be accessed (R/W vs. read-only, etc) 838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param new_layout_return returns the new layout mode 839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param convert_return returns TRUE if image conversion is needed 840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglayout_logic(enum lp_texture_layout cur_layout, 843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_layout target_layout, 844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_usage usage, 845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_layout *new_layout_return, 846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean *convert) 847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_layout other_layout, new_layout; 849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *convert = FALSE; 851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_layout = 99; /* debug check */ 853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (target_layout == LP_TEX_LAYOUT_LINEAR) { 855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org other_layout = LP_TEX_LAYOUT_TILED; 856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(target_layout == LP_TEX_LAYOUT_TILED); 859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org other_layout = LP_TEX_LAYOUT_LINEAR; 860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_layout = target_layout; /* may get changed below */ 863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cur_layout == LP_TEX_LAYOUT_BOTH) { 865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (usage == LP_TEX_USAGE_READ) { 866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_layout = LP_TEX_LAYOUT_BOTH; 867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (cur_layout == other_layout) { 870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (usage != LP_TEX_USAGE_WRITE_ALL) { 871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* need to convert tiled data to linear or vice versa */ 872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *convert = TRUE; 873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (usage == LP_TEX_USAGE_READ) 875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_layout = LP_TEX_LAYOUT_BOTH; 876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(cur_layout == LP_TEX_LAYOUT_NONE || 880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cur_layout == target_layout); 881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(new_layout == LP_TEX_LAYOUT_BOTH || 884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_layout == target_layout); 885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *new_layout_return = new_layout; 887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return pointer to a 2D texture image/face/slice. 892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * No tiled/linear conversion is done. 893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgubyte * 895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_get_texture_image_address(struct llvmpipe_resource *lpr, 896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned face_slice, unsigned level, 897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_layout layout) 898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_texture_image *img; 900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned offset; 901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (layout == LP_TEX_LAYOUT_LINEAR) { 903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org img = &lpr->linear[level]; 904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert (layout == LP_TEX_LAYOUT_TILED); 907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org img = &lpr->tiled[level]; 908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (face_slice > 0) 911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset = face_slice * tex_image_face_size(lpr, level, layout); 912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org offset = 0; 914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (ubyte *) img->data + offset; 916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE enum lp_texture_layout 920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_get_texture_tile_layout(const struct llvmpipe_resource *lpr, 921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned face_slice, unsigned level, 922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned x, unsigned y) 923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint i; 925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(resource_is_texture(&lpr->base)); 926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(x < lpr->tiles_per_row[level]); 927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org i = face_slice * lpr->tiles_per_image[level] 928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org + y * lpr->tiles_per_row[level] + x; 929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return lpr->layout[level][i]; 930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void 934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_set_texture_tile_layout(struct llvmpipe_resource *lpr, 935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned face_slice, unsigned level, 936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned x, unsigned y, 937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_layout layout) 938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint i; 940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(resource_is_texture(&lpr->base)); 941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(x < lpr->tiles_per_row[level]); 942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org i = face_slice * lpr->tiles_per_image[level] 943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org + y * lpr->tiles_per_row[level] + x; 944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->layout[level][i] = layout; 945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Set the layout mode for all tiles in a particular image. 950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void 952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_set_texture_image_layout(struct llvmpipe_resource *lpr, 953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned face_slice, unsigned level, 954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned width_t, unsigned height_t, 955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_layout layout) 956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned start = face_slice * lpr->tiles_per_image[level]; 958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < width_t * height_t; i++) { 961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->layout[level][start + i] = layout; 962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Allocate storage for a linear or tile texture image (all cube 968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * faces and all 3D slices. 969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgalloc_image_data(struct llvmpipe_resource *lpr, unsigned level, 972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_layout layout) 973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint alignment = MAX2(16, util_cpu_caps.cacheline); 975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lpr->dt) 977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(level == 0); 978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (layout == LP_TEX_LAYOUT_TILED) { 980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* tiled data is stored in regular memory */ 981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint buffer_size = tex_image_size(lpr, level, layout); 982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->tiled[level].data = align_malloc(buffer_size, alignment); 983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lpr->tiled[level].data) { 984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(lpr->tiled[level].data, 0, buffer_size); 985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(layout == LP_TEX_LAYOUT_LINEAR); 989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lpr->dt) { 990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* we get the linear memory from the winsys, and it has 991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * already been zeroed 992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_screen *screen = llvmpipe_screen(lpr->base.screen); 994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct sw_winsys *winsys = screen->winsys; 995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->linear[0].data = 997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org winsys->displaytarget_map(winsys, lpr->dt, 998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PIPE_TRANSFER_READ_WRITE); 999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* not a display target - allocate regular memory */ 1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint buffer_size = tex_image_size(lpr, level, LP_TEX_LAYOUT_LINEAR); 1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->linear[level].data = align_malloc(buffer_size, alignment); 1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lpr->linear[level].data) { 1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(lpr->linear[level].data, 0, buffer_size); 1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return pointer to texture image data (either linear or tiled layout) 1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * for a particular cube face or 3D texture slice. 1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param face_slice the cube face or 3D slice of interest 1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param usage one of LP_TEX_USAGE_READ/WRITE_ALL/READ_WRITE 1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \param layout either LP_TEX_LAYOUT_LINEAR or _TILED or _NONE 1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid * 1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_get_texture_image(struct llvmpipe_resource *lpr, 1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned face_slice, unsigned level, 1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_usage usage, 1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_layout layout) 1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 'target' refers to the image which we're retrieving (either in 1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * tiled or linear layout). 1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 'other' refers to the same image but in the other layout. (it may 1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * or may not exist. 1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_texture_image *target_img; 1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_texture_image *other_img; 1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *target_data; 1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *other_data; 1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned width = u_minify(lpr->base.width0, level); 1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned height = u_minify(lpr->base.height0, level); 1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned width_t = align(width, TILE_SIZE) / TILE_SIZE; 1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned height_t = align(height, TILE_SIZE) / TILE_SIZE; 1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_layout other_layout; 1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean only_allocate; 1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(layout == LP_TEX_LAYOUT_NONE || 1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org layout == LP_TEX_LAYOUT_TILED || 1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org layout == LP_TEX_LAYOUT_LINEAR); 1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(usage == LP_TEX_USAGE_READ || 1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org usage == LP_TEX_USAGE_READ_WRITE || 1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org usage == LP_TEX_USAGE_WRITE_ALL); 1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* check for the special case of layout == LP_TEX_LAYOUT_NONE */ 1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (layout == LP_TEX_LAYOUT_NONE) { 1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org only_allocate = TRUE; 1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org layout = LP_TEX_LAYOUT_TILED; 1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org only_allocate = FALSE; 1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lpr->dt) { 1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(lpr->linear[level].data); 1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* which is target? which is other? */ 1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (layout == LP_TEX_LAYOUT_LINEAR) { 1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org target_img = &lpr->linear[level]; 1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org other_img = &lpr->tiled[level]; 1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org other_layout = LP_TEX_LAYOUT_TILED; 1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org target_img = &lpr->tiled[level]; 1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org other_img = &lpr->linear[level]; 1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org other_layout = LP_TEX_LAYOUT_LINEAR; 1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org target_data = target_img->data; 1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org other_data = other_img->data; 1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!target_data) { 1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* allocate memory for the target image now */ 1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org alloc_image_data(lpr, level, layout); 1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org target_data = target_img->data; 1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (face_slice > 0) { 1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned target_offset, other_offset; 1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org target_offset = face_slice * tex_image_face_size(lpr, level, layout); 1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org other_offset = face_slice * tex_image_face_size(lpr, level, other_layout); 1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (target_data) { 1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org target_data = (uint8_t *) target_data + target_offset; 1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (other_data) { 1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org other_data = (uint8_t *) other_data + other_offset; 1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (only_allocate) { 1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Just allocating tiled memory. Don't initialize it from the 1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * linear data if it exists. 1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return target_data; 1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (other_data) { 1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* may need to convert other data to the requested layout */ 1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_layout new_layout; 1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned x, y; 1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* loop over all image tiles, doing layout conversion where needed */ 1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (y = 0; y < height_t; y++) { 1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (x = 0; x < width_t; x++) { 1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_layout cur_layout = 1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org llvmpipe_get_texture_tile_layout(lpr, face_slice, level, x, y); 1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean convert; 1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org layout_logic(cur_layout, layout, usage, &new_layout, &convert); 1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (convert && other_data && target_data) { 1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (layout == LP_TEX_LAYOUT_TILED) { 1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lp_linear_to_tiled(other_data, target_data, 1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x * TILE_SIZE, y * TILE_SIZE, 1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TILE_SIZE, TILE_SIZE, 1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->base.format, 1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->row_stride[level], 1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->tiles_per_row[level]); 1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(layout == LP_TEX_LAYOUT_LINEAR); 1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lp_tiled_to_linear(other_data, target_data, 1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x * TILE_SIZE, y * TILE_SIZE, 1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TILE_SIZE, TILE_SIZE, 1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->base.format, 1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->row_stride[level], 1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->tiles_per_row[level]); 1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (new_layout != cur_layout) 1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org llvmpipe_set_texture_tile_layout(lpr, face_slice, level, x, y, 1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_layout); 1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* no other data */ 1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org llvmpipe_set_texture_image_layout(lpr, face_slice, level, 1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org width_t, height_t, layout); 1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return target_data; 1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return pointer to start of a texture image (1D, 2D, 3D, CUBE). 1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All cube faces and 3D slices will be converted to the requested 1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * layout if needed. 1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is typically used when we're about to sample from a texture. 1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid * 1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_get_texture_image_all(struct llvmpipe_resource *lpr, 1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned level, 1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_usage usage, 1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_layout layout) 1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const int slices = lpr->num_slices_faces[level]; 1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int slice; 1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *map = NULL; 1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(slices > 0); 1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (slice = slices - 1; slice >= 0; slice--) { 1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org map = llvmpipe_get_texture_image(lpr, slice, level, usage, layout); 1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return map; 1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Get pointer to a linear image (not the tile!) where the tile at (x,y) 1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is known to be in linear layout. 1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Conversion from tiled to linear will be done if necessary. 1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return pointer to start of image/face (not the tile) 1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgubyte * 1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpr, 1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned face_slice, unsigned level, 1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_usage usage, 1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned x, unsigned y) 1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_texture_image *linear_img = &lpr->linear[level]; 1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_layout cur_layout, new_layout; 1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned tx = x / TILE_SIZE, ty = y / TILE_SIZE; 1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean convert; 1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint8_t *tiled_image, *linear_image; 1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(resource_is_texture(&lpr->base)); 1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(x % TILE_SIZE == 0); 1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(y % TILE_SIZE == 0); 1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!linear_img->data) { 1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* allocate memory for the linear image now */ 1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org alloc_image_data(lpr, level, LP_TEX_LAYOUT_LINEAR); 1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* compute address of the slice/face of the image that contains the tile */ 1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tiled_image = llvmpipe_get_texture_image_address(lpr, face_slice, level, 1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LP_TEX_LAYOUT_TILED); 1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org linear_image = llvmpipe_get_texture_image_address(lpr, face_slice, level, 1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LP_TEX_LAYOUT_LINEAR); 1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* get current tile layout and determine if data conversion is needed */ 1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cur_layout = llvmpipe_get_texture_tile_layout(lpr, face_slice, level, tx, ty); 1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org layout_logic(cur_layout, LP_TEX_LAYOUT_LINEAR, usage, 1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &new_layout, &convert); 1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (convert && tiled_image && linear_image) { 1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lp_tiled_to_linear(tiled_image, linear_image, 1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x, y, TILE_SIZE, TILE_SIZE, lpr->base.format, 1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->row_stride[level], 1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->tiles_per_row[level]); 1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (new_layout != cur_layout) 1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org llvmpipe_set_texture_tile_layout(lpr, face_slice, level, tx, ty, new_layout); 1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return linear_image; 1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Get pointer to tiled data for rendering. 1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return pointer to the tiled data at the given tile position 1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgubyte * 1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_get_texture_tile(struct llvmpipe_resource *lpr, 1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned face_slice, unsigned level, 1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_usage usage, 1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned x, unsigned y) 1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_texture_image *tiled_img = &lpr->tiled[level]; 1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum lp_texture_layout cur_layout, new_layout; 1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned tx = x / TILE_SIZE, ty = y / TILE_SIZE; 1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean convert; 1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint8_t *tiled_image, *linear_image; 1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned tile_offset; 1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(x % TILE_SIZE == 0); 1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(y % TILE_SIZE == 0); 1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!tiled_img->data) { 1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* allocate memory for the tiled image now */ 1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org alloc_image_data(lpr, level, LP_TEX_LAYOUT_TILED); 1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* compute address of the slice/face of the image that contains the tile */ 1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tiled_image = llvmpipe_get_texture_image_address(lpr, face_slice, level, 1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LP_TEX_LAYOUT_TILED); 1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org linear_image = llvmpipe_get_texture_image_address(lpr, face_slice, level, 1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LP_TEX_LAYOUT_LINEAR); 1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* get current tile layout and see if we need to convert the data */ 1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cur_layout = llvmpipe_get_texture_tile_layout(lpr, face_slice, level, tx, ty); 1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org layout_logic(cur_layout, LP_TEX_LAYOUT_TILED, usage, &new_layout, &convert); 1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (convert && linear_image && tiled_image) { 1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lp_linear_to_tiled(linear_image, tiled_image, 1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x, y, TILE_SIZE, TILE_SIZE, lpr->base.format, 1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->row_stride[level], 1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->tiles_per_row[level]); 1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!tiled_image) 1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (new_layout != cur_layout) 1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org llvmpipe_set_texture_tile_layout(lpr, face_slice, level, tx, ty, new_layout); 1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* compute, return address of the 64x64 tile */ 1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tile_offset = (ty * lpr->tiles_per_row[level] + tx) 1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TILE_SIZE * TILE_SIZE * 4; 1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (ubyte *) tiled_image + tile_offset; 1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Get pointer to tiled data for rendering. 1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return pointer to the tiled data at the given tile position 1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_unswizzle_cbuf_tile(struct llvmpipe_resource *lpr, 1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned face_slice, unsigned level, 1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned x, unsigned y, 1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint8_t *tile) 1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_texture_image *linear_img = &lpr->linear[level]; 1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned tx = x / TILE_SIZE, ty = y / TILE_SIZE; 1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint8_t *linear_image; 1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(x % TILE_SIZE == 0); 1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(y % TILE_SIZE == 0); 1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!linear_img->data) { 1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* allocate memory for the linear image now */ 1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org alloc_image_data(lpr, level, LP_TEX_LAYOUT_LINEAR); 1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* compute address of the slice/face of the image that contains the tile */ 1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org linear_image = llvmpipe_get_texture_image_address(lpr, face_slice, level, 1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LP_TEX_LAYOUT_LINEAR); 1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint ii = x, jj = y; 1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint tile_offset = jj / TILE_SIZE + ii / TILE_SIZE; 1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint byte_offset = tile_offset * TILE_SIZE * TILE_SIZE * 4; 1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Note that lp_tiled_to_linear expects the tile parameter to 1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * point at the first tile in a whole-image sized array. In 1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * this code, we have only a single tile and have to do some 1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * pointer arithmetic to figure out where the "image" would have 1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * started. 1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lp_tiled_to_linear(tile - byte_offset, linear_image, 1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x, y, TILE_SIZE, TILE_SIZE, 1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->base.format, 1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->row_stride[level], 1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1); /* tiles per row */ 1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org llvmpipe_set_texture_tile_layout(lpr, face_slice, level, tx, ty, 1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LP_TEX_LAYOUT_LINEAR); 1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Get pointer to tiled data for rendering. 1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return pointer to the tiled data at the given tile position 1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_swizzle_cbuf_tile(struct llvmpipe_resource *lpr, 1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned face_slice, unsigned level, 1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned x, unsigned y, 1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint8_t *tile) 1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint8_t *linear_image; 1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(x % TILE_SIZE == 0); 1353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(y % TILE_SIZE == 0); 1354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* compute address of the slice/face of the image that contains the tile */ 1356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org linear_image = llvmpipe_get_texture_image_address(lpr, face_slice, level, 1357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LP_TEX_LAYOUT_LINEAR); 1358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (linear_image) { 1360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint ii = x, jj = y; 1361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint tile_offset = jj / TILE_SIZE + ii / TILE_SIZE; 1362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint byte_offset = tile_offset * TILE_SIZE * TILE_SIZE * 4; 1363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Note that lp_linear_to_tiled expects the tile parameter to 1365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * point at the first tile in a whole-image sized array. In 1366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * this code, we have only a single tile and have to do some 1367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * pointer arithmetic to figure out where the "image" would have 1368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * started. 1369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lp_linear_to_tiled(linear_image, tile - byte_offset, 1371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org x, y, TILE_SIZE, TILE_SIZE, 1372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->base.format, 1373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->row_stride[level], 1374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1); /* tiles per row */ 1375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 1380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return size of resource in bytes 1381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 1382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned 1383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_resource_size(const struct pipe_resource *resource) 1384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct llvmpipe_resource *lpr = llvmpipe_resource_const(resource); 1386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned lvl, size = 0; 1387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (lvl = 0; lvl <= lpr->base.last_level; lvl++) { 1389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lpr->linear[lvl].data) 1390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size += tex_image_size(lpr, lvl, LP_TEX_LAYOUT_LINEAR); 1391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (lpr->tiled[lvl].data) 1393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size += tex_image_size(lpr, lvl, LP_TEX_LAYOUT_TILED); 1394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return size; 1397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG 1401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 1402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_print_resources(void) 1403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct llvmpipe_resource *lpr; 1405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned n = 0, total = 0; 1406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("LLVMPIPE: current resources:\n"); 1408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org foreach(lpr, &resource_list) { 1409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned size = llvmpipe_resource_size(&lpr->base); 1410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("resource %u at %p, size %ux%ux%u: %u bytes, refcount %u\n", 1411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->id, (void *) lpr, 1412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lpr->base.width0, lpr->base.height0, lpr->base.depth0, 1413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size, lpr->base.reference.count); 1414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org total += size; 1415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org n++; 1416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("LLVMPIPE: total size of %u resources: %u\n", n, total); 1418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 1420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 1423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_init_screen_resource_funcs(struct pipe_screen *screen) 1424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef DEBUG 1426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* init linked list for tracking resources */ 1427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 1428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static boolean first_call = TRUE; 1429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (first_call) { 1430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&resource_list, 0, sizeof(resource_list)); 1431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org make_empty_list(&resource_list); 1432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org first_call = FALSE; 1433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 1435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 1436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org screen->resource_create = llvmpipe_resource_create; 1438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org screen->resource_destroy = llvmpipe_resource_destroy; 1439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org screen->resource_from_handle = llvmpipe_resource_from_handle; 1440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org screen->resource_get_handle = llvmpipe_resource_get_handle; 1441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 1445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgllvmpipe_init_context_resource_funcs(struct pipe_context *pipe) 1446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 1447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->get_transfer = llvmpipe_get_transfer; 1448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->transfer_destroy = llvmpipe_transfer_destroy; 1449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->transfer_map = llvmpipe_transfer_map; 1450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->transfer_unmap = llvmpipe_transfer_unmap; 1451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->transfer_flush_region = u_default_transfer_flush_region; 1453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->transfer_inline_write = u_default_transfer_inline_write; 1454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 1455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->create_surface = llvmpipe_create_surface; 1456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe->surface_destroy = llvmpipe_surface_destroy; 1457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 1458