33673fa0b9c4b62c0437778d412205d51378862a
[mesa.git] / src / mesa / drivers / dri / r300 / r300_texstate.c
1 /*
2 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
3
4 The Weather Channel (TM) funded Tungsten Graphics to develop the
5 initial release of the Radeon 8500 driver under the XFree86 license.
6 This notice must be preserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
15
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 **************************************************************************/
29
30 /**
31 * \file
32 *
33 * \author Keith Whitwell <keith@tungstengraphics.com>
34 *
35 * \todo Enable R300 texture tiling code?
36 */
37
38 #include "main/glheader.h"
39 #include "main/imports.h"
40 #include "main/context.h"
41 #include "main/macros.h"
42 #include "main/texformat.h"
43 #include "main/teximage.h"
44 #include "main/texobj.h"
45 #include "main/enums.h"
46
47 #include "r300_context.h"
48 #include "r300_state.h"
49 #include "r300_ioctl.h"
50 #include "radeon_ioctl.h"
51 #include "r300_mipmap_tree.h"
52 #include "r300_tex.h"
53 #include "r300_reg.h"
54
55 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5 \
56 || ((f) >= MESA_FORMAT_RGBA_FLOAT32 && \
57 (f) <= MESA_FORMAT_INTENSITY_FLOAT16)) \
58 && tx_table[f].flag )
59
60 #define _ASSIGN(entry, format) \
61 [ MESA_FORMAT_ ## entry ] = { format, 0, 1}
62
63 /*
64 * Note that the _REV formats are the same as the non-REV formats. This is
65 * because the REV and non-REV formats are identical as a byte string, but
66 * differ when accessed as 16-bit or 32-bit words depending on the endianness of
67 * the host. Since the textures are transferred to the R300 as a byte string
68 * (i.e. without any byte-swapping), the R300 sees the REV and non-REV formats
69 * identically. -- paulus
70 */
71
72 static const struct tx_table {
73 GLuint format, filter, flag;
74 } tx_table[] = {
75 /* *INDENT-OFF* */
76 #ifdef MESA_LITTLE_ENDIAN
77 _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
78 _ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)),
79 _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
80 _ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
81 #else
82 _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)),
83 _ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
84 _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
85 _ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
86 #endif
87 _ASSIGN(RGB888, R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8)),
88 _ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
89 _ASSIGN(RGB565_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
90 _ASSIGN(ARGB4444, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
91 _ASSIGN(ARGB4444_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
92 _ASSIGN(ARGB1555, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
93 _ASSIGN(ARGB1555_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
94 _ASSIGN(AL88, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
95 _ASSIGN(AL88_REV, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
96 _ASSIGN(RGB332, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z3Y3X2)),
97 _ASSIGN(A8, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8)),
98 _ASSIGN(L8, R300_EASY_TX_FORMAT(X, X, X, ONE, X8)),
99 _ASSIGN(I8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
100 _ASSIGN(CI8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
101 _ASSIGN(YCBCR, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE),
102 _ASSIGN(YCBCR_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE),
103 _ASSIGN(RGB_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1)),
104 _ASSIGN(RGBA_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1)),
105 _ASSIGN(RGBA_DXT3, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3)),
106 _ASSIGN(RGBA_DXT5, R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5)),
107 _ASSIGN(RGBA_FLOAT32, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R32G32B32A32)),
108 _ASSIGN(RGBA_FLOAT16, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R16G16B16A16)),
109 _ASSIGN(RGB_FLOAT32, 0xffffffff),
110 _ASSIGN(RGB_FLOAT16, 0xffffffff),
111 _ASSIGN(ALPHA_FLOAT32, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I32)),
112 _ASSIGN(ALPHA_FLOAT16, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I16)),
113 _ASSIGN(LUMINANCE_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I32)),
114 _ASSIGN(LUMINANCE_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I16)),
115 _ASSIGN(LUMINANCE_ALPHA_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I32A32)),
116 _ASSIGN(LUMINANCE_ALPHA_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I16A16)),
117 _ASSIGN(INTENSITY_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, X, FL_I32)),
118 _ASSIGN(INTENSITY_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, X, FL_I16)),
119 _ASSIGN(Z16, R300_EASY_TX_FORMAT(X, X, X, X, X16)),
120 _ASSIGN(Z24_S8, R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8)),
121 _ASSIGN(Z32, R300_EASY_TX_FORMAT(X, X, X, X, X32)),
122 /* *INDENT-ON* */
123 };
124
125 #undef _ASSIGN
126
127 void r300SetDepthTexMode(struct gl_texture_object *tObj)
128 {
129 static const GLuint formats[3][3] = {
130 {
131 R300_EASY_TX_FORMAT(X, X, X, ONE, X16),
132 R300_EASY_TX_FORMAT(X, X, X, X, X16),
133 R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X16),
134 },
135 {
136 R300_EASY_TX_FORMAT(X, X, X, ONE, X24_Y8),
137 R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8),
138 R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X24_Y8),
139 },
140 {
141 R300_EASY_TX_FORMAT(X, X, X, ONE, X32),
142 R300_EASY_TX_FORMAT(X, X, X, X, X32),
143 R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X32),
144 },
145 };
146 const GLuint *format;
147 r300TexObjPtr t;
148
149 if (!tObj)
150 return;
151
152 t = r300_tex_obj(tObj);
153
154 switch (tObj->Image[0][tObj->BaseLevel]->TexFormat->MesaFormat) {
155 case MESA_FORMAT_Z16:
156 format = formats[0];
157 break;
158 case MESA_FORMAT_Z24_S8:
159 format = formats[1];
160 break;
161 case MESA_FORMAT_Z32:
162 format = formats[2];
163 break;
164 default:
165 /* Error...which should have already been caught by higher
166 * levels of Mesa.
167 */
168 ASSERT(0);
169 return;
170 }
171
172 switch (tObj->DepthMode) {
173 case GL_LUMINANCE:
174 t->format = format[0];
175 break;
176 case GL_INTENSITY:
177 t->format = format[1];
178 break;
179 case GL_ALPHA:
180 t->format = format[2];
181 break;
182 default:
183 /* Error...which should have already been caught by higher
184 * levels of Mesa.
185 */
186 ASSERT(0);
187 return;
188 }
189 }
190
191
192 /**
193 * Compute the cached hardware register values for the given texture object.
194 *
195 * \param rmesa Context pointer
196 * \param t the r300 texture object
197 */
198 static void setup_hardware_state(r300ContextPtr rmesa, r300TexObj *t)
199 {
200 const struct gl_texture_image *firstImage =
201 t->base.Image[0][t->mt->firstLevel];
202
203 if (!t->image_override
204 && VALID_FORMAT(firstImage->TexFormat->MesaFormat)) {
205 if (firstImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) {
206 r300SetDepthTexMode(&t->base);
207 } else {
208 t->format = tx_table[firstImage->TexFormat->MesaFormat].format;
209 }
210
211 t->filter |= tx_table[firstImage->TexFormat->MesaFormat].filter;
212 } else if (!t->image_override) {
213 _mesa_problem(NULL, "unexpected texture format in %s",
214 __FUNCTION__);
215 return;
216 }
217
218 t->tile_bits = 0;
219
220 if (t->base.Target == GL_TEXTURE_CUBE_MAP)
221 t->format |= R300_TX_FORMAT_CUBIC_MAP;
222 if (t->base.Target == GL_TEXTURE_3D)
223 t->format |= R300_TX_FORMAT_3D;
224
225 t->size = (((firstImage->Width - 1) << R300_TX_WIDTHMASK_SHIFT)
226 | ((firstImage->Height - 1) << R300_TX_HEIGHTMASK_SHIFT))
227 | ((t->mt->lastLevel - t->mt->firstLevel) << R300_TX_MAX_MIP_LEVEL_SHIFT);
228
229 if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
230 unsigned int align = (64 / t->mt->bpp) - 1;
231 t->size |= R300_TX_SIZE_TXPITCH_EN;
232 if (!t->image_override)
233 t->pitch_reg = ((firstImage->Width + align) & ~align) - 1;
234 }
235
236 if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
237 if (firstImage->Width > 2048)
238 t->pitch_reg |= R500_TXWIDTH_BIT11;
239 if (firstImage->Height > 2048)
240 t->pitch_reg |= R500_TXHEIGHT_BIT11;
241 }
242 }
243
244
245 static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
246 GLuint numrows, GLuint rowsize)
247 {
248 assert(rowsize <= dststride);
249 assert(rowsize <= srcstride);
250
251 if (rowsize == srcstride && rowsize == dststride) {
252 memcpy(dst, src, numrows*rowsize);
253 } else {
254 GLuint i;
255 for(i = 0; i < numrows; ++i) {
256 memcpy(dst, src, rowsize);
257 dst += dststride;
258 src += srcstride;
259 }
260 }
261 }
262
263
264 /**
265 * Ensure that the given image is stored in the given miptree from now on.
266 */
267 static void migrate_image_to_miptree(r300_mipmap_tree *mt, r300_texture_image *image, int face, int level)
268 {
269 r300_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel];
270 unsigned char *dest;
271
272 assert(image->mt != mt);
273 assert(dstlvl->width == image->base.Width);
274 assert(dstlvl->height == image->base.Height);
275 assert(dstlvl->depth == image->base.Depth);
276
277 radeon_bo_map(mt->bo, GL_TRUE);
278 dest = mt->bo->ptr + dstlvl->faces[face].offset;
279
280 if (image->mt) {
281 /* Format etc. should match, so we really just need a memcpy().
282 * In fact, that memcpy() could be done by the hardware in many
283 * cases, provided that we have a proper memory manager.
284 */
285 r300_mipmap_level *srclvl = &image->mt->levels[image->mtlevel];
286
287 assert(srclvl->size == dstlvl->size);
288 assert(srclvl->rowstride == dstlvl->rowstride);
289
290 radeon_bo_map(image->mt->bo, GL_FALSE);
291 memcpy(dest,
292 image->mt->bo->ptr + srclvl->faces[face].offset,
293 dstlvl->size);
294 radeon_bo_unmap(image->mt->bo);
295
296 r300_miptree_unreference(image->mt);
297 } else {
298 uint srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
299
300 if (mt->tilebits)
301 WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
302
303 copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride,
304 image->base.Height * image->base.Depth, srcrowstride);
305
306 _mesa_free_texmemory(image->base.Data);
307 image->base.Data = 0;
308 }
309
310 radeon_bo_unmap(mt->bo);
311
312 image->mt = mt;
313 image->mtface = face;
314 image->mtlevel = level;
315 r300_miptree_reference(image->mt);
316 }
317
318
319 /**
320 * Ensure the given texture is ready for rendering.
321 *
322 * Mostly this means populating the texture object's mipmap tree.
323 */
324 static GLboolean r300_validate_texture(GLcontext * ctx, struct gl_texture_object *texObj)
325 {
326 r300ContextPtr rmesa = R300_CONTEXT(ctx);
327 r300TexObj *t = r300_tex_obj(texObj);
328 r300_texture_image *baseimage = get_r300_texture_image(texObj->Image[0][texObj->BaseLevel]);
329 int face, level;
330
331 if (t->validated)
332 return GL_TRUE;
333
334 if (RADEON_DEBUG & DEBUG_TEXTURE)
335 fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj);
336
337 if (baseimage->base.Border > 0)
338 return GL_FALSE;
339
340 /* Ensure a matching miptree exists.
341 *
342 * Differing mipmap trees can result when the app uses TexImage to
343 * change texture dimensions.
344 *
345 * Prefer to use base image's miptree if it
346 * exists, since that most likely contains more valid data (remember
347 * that the base level is usually significantly larger than the rest
348 * of the miptree, so cubemaps are the only possible exception).
349 */
350 if (baseimage->mt &&
351 baseimage->mt != t->mt &&
352 r300_miptree_matches_texture(baseimage->mt, &t->base)) {
353 r300_miptree_unreference(t->mt);
354 t->mt = baseimage->mt;
355 r300_miptree_reference(t->mt);
356 } else if (t->mt && !r300_miptree_matches_texture(t->mt, &t->base)) {
357 r300_miptree_unreference(t->mt);
358 t->mt = 0;
359 }
360
361 if (!t->mt) {
362 if (RADEON_DEBUG & DEBUG_TEXTURE)
363 fprintf(stderr, " Allocate new miptree\n");
364 r300_try_alloc_miptree(rmesa, t, &baseimage->base, 0, texObj->BaseLevel);
365 if (!t->mt) {
366 _mesa_problem(ctx, "r300_validate_texture failed to alloc miptree");
367 return GL_FALSE;
368 }
369 }
370
371 /* Ensure all images are stored in the single main miptree */
372 for(face = 0; face < t->mt->faces; ++face) {
373 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) {
374 r300_texture_image *image = get_r300_texture_image(texObj->Image[face][level]);
375 if (RADEON_DEBUG & DEBUG_TEXTURE)
376 fprintf(stderr, " face %i, level %i... ", face, level);
377 if (t->mt == image->mt) {
378 if (RADEON_DEBUG & DEBUG_TEXTURE)
379 fprintf(stderr, "OK\n");
380 continue;
381 }
382
383 if (RADEON_DEBUG & DEBUG_TEXTURE)
384 fprintf(stderr, "migrating\n");
385 migrate_image_to_miptree(t->mt, image, face, level);
386 }
387 }
388
389 /* Configure the hardware registers (more precisely, the cached version
390 * of the hardware registers). */
391 setup_hardware_state(rmesa, t);
392
393 t->validated = GL_TRUE;
394 return GL_TRUE;
395 }
396
397
398 /**
399 * Ensure all enabled and complete textures are uploaded.
400 */
401 void r300ValidateTextures(GLcontext * ctx)
402 {
403 int i;
404
405 for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
406 if (!ctx->Texture.Unit[i]._ReallyEnabled)
407 continue;
408
409 if (!r300_validate_texture(ctx, ctx->Texture.Unit[i]._Current)) {
410 _mesa_warning(ctx,
411 "failed to validate texture for unit %d.\n",
412 i);
413 }
414 }
415 }
416
417 void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
418 unsigned long long offset, GLint depth, GLuint pitch)
419 {
420 r300ContextPtr rmesa = pDRICtx->driverPrivate;
421 struct gl_texture_object *tObj =
422 _mesa_lookup_texture(rmesa->radeon.glCtx, texname);
423 r300TexObjPtr t = r300_tex_obj(tObj);
424 uint32_t pitch_val;
425
426 if (!tObj)
427 return;
428
429 t->image_override = GL_TRUE;
430
431 if (!offset)
432 return;
433
434 t->override_offset = offset;
435 t->pitch_reg &= (1 << 13) -1;
436 pitch_val = pitch;
437
438 switch (depth) {
439 case 32:
440 t->format = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
441 t->filter |= tx_table[2].filter;
442 pitch_val /= 4;
443 break;
444 case 24:
445 default:
446 t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
447 t->filter |= tx_table[4].filter;
448 pitch_val /= 4;
449 break;
450 case 16:
451 t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
452 t->filter |= tx_table[5].filter;
453 pitch_val /= 2;
454 break;
455 }
456 pitch_val--;
457
458 t->pitch_reg |= pitch_val;
459 }