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