r300: SetTex extension support
[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 #include "radeon_buffer.h"
55
56 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5 \
57 || ((f) >= MESA_FORMAT_RGBA_FLOAT32 && \
58 (f) <= MESA_FORMAT_INTENSITY_FLOAT16)) \
59 && tx_table[f].flag )
60
61 #define _ASSIGN(entry, format) \
62 [ MESA_FORMAT_ ## entry ] = { format, 0, 1}
63
64 /*
65 * Note that the _REV formats are the same as the non-REV formats. This is
66 * because the REV and non-REV formats are identical as a byte string, but
67 * differ when accessed as 16-bit or 32-bit words depending on the endianness of
68 * the host. Since the textures are transferred to the R300 as a byte string
69 * (i.e. without any byte-swapping), the R300 sees the REV and non-REV formats
70 * identically. -- paulus
71 */
72
73 static const struct tx_table {
74 GLuint format, filter, flag;
75 } tx_table[] = {
76 /* *INDENT-OFF* */
77 #ifdef MESA_LITTLE_ENDIAN
78 _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
79 _ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)),
80 _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
81 _ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
82 #else
83 _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)),
84 _ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
85 _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
86 _ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
87 #endif
88 _ASSIGN(RGB888, R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8)),
89 _ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
90 _ASSIGN(RGB565_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
91 _ASSIGN(ARGB4444, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
92 _ASSIGN(ARGB4444_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
93 _ASSIGN(ARGB1555, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
94 _ASSIGN(ARGB1555_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
95 _ASSIGN(AL88, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
96 _ASSIGN(AL88_REV, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
97 _ASSIGN(RGB332, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z3Y3X2)),
98 _ASSIGN(A8, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8)),
99 _ASSIGN(L8, R300_EASY_TX_FORMAT(X, X, X, ONE, X8)),
100 _ASSIGN(I8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
101 _ASSIGN(CI8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
102 _ASSIGN(YCBCR, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE),
103 _ASSIGN(YCBCR_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE),
104 _ASSIGN(RGB_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1)),
105 _ASSIGN(RGBA_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1)),
106 _ASSIGN(RGBA_DXT3, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3)),
107 _ASSIGN(RGBA_DXT5, R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5)),
108 _ASSIGN(RGBA_FLOAT32, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R32G32B32A32)),
109 _ASSIGN(RGBA_FLOAT16, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R16G16B16A16)),
110 _ASSIGN(RGB_FLOAT32, 0xffffffff),
111 _ASSIGN(RGB_FLOAT16, 0xffffffff),
112 _ASSIGN(ALPHA_FLOAT32, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I32)),
113 _ASSIGN(ALPHA_FLOAT16, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I16)),
114 _ASSIGN(LUMINANCE_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I32)),
115 _ASSIGN(LUMINANCE_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I16)),
116 _ASSIGN(LUMINANCE_ALPHA_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I32A32)),
117 _ASSIGN(LUMINANCE_ALPHA_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I16A16)),
118 _ASSIGN(INTENSITY_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, X, FL_I32)),
119 _ASSIGN(INTENSITY_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, X, FL_I16)),
120 _ASSIGN(Z16, R300_EASY_TX_FORMAT(X, X, X, X, X16)),
121 _ASSIGN(Z24_S8, R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8)),
122 _ASSIGN(Z32, R300_EASY_TX_FORMAT(X, X, X, X, X32)),
123 /* *INDENT-ON* */
124 };
125
126 #undef _ASSIGN
127
128 void r300SetDepthTexMode(struct gl_texture_object *tObj)
129 {
130 static const GLuint formats[3][3] = {
131 {
132 R300_EASY_TX_FORMAT(X, X, X, ONE, X16),
133 R300_EASY_TX_FORMAT(X, X, X, X, X16),
134 R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X16),
135 },
136 {
137 R300_EASY_TX_FORMAT(X, X, X, ONE, X24_Y8),
138 R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8),
139 R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X24_Y8),
140 },
141 {
142 R300_EASY_TX_FORMAT(X, X, X, ONE, X32),
143 R300_EASY_TX_FORMAT(X, X, X, X, X32),
144 R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X32),
145 },
146 };
147 const GLuint *format;
148 r300TexObjPtr t;
149
150 if (!tObj)
151 return;
152
153 t = r300_tex_obj(tObj);
154
155 switch (tObj->Image[0][tObj->BaseLevel]->TexFormat->MesaFormat) {
156 case MESA_FORMAT_Z16:
157 format = formats[0];
158 break;
159 case MESA_FORMAT_Z24_S8:
160 format = formats[1];
161 break;
162 case MESA_FORMAT_Z32:
163 format = formats[2];
164 break;
165 default:
166 /* Error...which should have already been caught by higher
167 * levels of Mesa.
168 */
169 ASSERT(0);
170 return;
171 }
172
173 switch (tObj->DepthMode) {
174 case GL_LUMINANCE:
175 t->format = format[0];
176 break;
177 case GL_INTENSITY:
178 t->format = format[1];
179 break;
180 case GL_ALPHA:
181 t->format = format[2];
182 break;
183 default:
184 /* Error...which should have already been caught by higher
185 * levels of Mesa.
186 */
187 ASSERT(0);
188 return;
189 }
190 }
191
192
193 /**
194 * Compute the cached hardware register values for the given texture object.
195 *
196 * \param rmesa Context pointer
197 * \param t the r300 texture object
198 */
199 static void setup_hardware_state(r300ContextPtr rmesa, r300TexObj *t)
200 {
201 const struct gl_texture_image *firstImage =
202 t->base.Image[0][t->mt->firstLevel];
203
204 if (!t->image_override
205 && VALID_FORMAT(firstImage->TexFormat->MesaFormat)) {
206 if (firstImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) {
207 r300SetDepthTexMode(&t->base);
208 } else {
209 t->format = tx_table[firstImage->TexFormat->MesaFormat].format;
210 }
211
212 t->filter |= tx_table[firstImage->TexFormat->MesaFormat].filter;
213 } else if (!t->image_override) {
214 _mesa_problem(NULL, "unexpected texture format in %s",
215 __FUNCTION__);
216 return;
217 }
218
219 t->tile_bits = 0;
220
221 if (t->base.Target == GL_TEXTURE_CUBE_MAP)
222 t->format |= R300_TX_FORMAT_CUBIC_MAP;
223 if (t->base.Target == GL_TEXTURE_3D)
224 t->format |= R300_TX_FORMAT_3D;
225
226 t->size = (((firstImage->Width - 1) << R300_TX_WIDTHMASK_SHIFT)
227 | ((firstImage->Height - 1) << R300_TX_HEIGHTMASK_SHIFT))
228 | ((t->mt->lastLevel - t->mt->firstLevel) << R300_TX_MAX_MIP_LEVEL_SHIFT);
229
230 if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
231 unsigned int align = (64 / t->mt->bpp) - 1;
232 t->size |= R300_TX_SIZE_TXPITCH_EN;
233 if (!t->image_override)
234 t->pitch_reg = ((firstImage->Width + align) & ~align) - 1;
235 }
236
237 if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
238 if (firstImage->Width > 2048)
239 t->pitch_reg |= R500_TXWIDTH_BIT11;
240 if (firstImage->Height > 2048)
241 t->pitch_reg |= R500_TXHEIGHT_BIT11;
242 }
243 }
244
245
246 static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
247 GLuint numrows, GLuint rowsize)
248 {
249 assert(rowsize <= dststride);
250 assert(rowsize <= srcstride);
251
252 if (rowsize == srcstride && rowsize == dststride) {
253 memcpy(dst, src, numrows*rowsize);
254 } else {
255 GLuint i;
256 for(i = 0; i < numrows; ++i) {
257 memcpy(dst, src, rowsize);
258 dst += dststride;
259 src += srcstride;
260 }
261 }
262 }
263
264
265 /**
266 * Ensure that the given image is stored in the given miptree from now on.
267 */
268 static void migrate_image_to_miptree(r300_mipmap_tree *mt, r300_texture_image *image, int face, int level)
269 {
270 r300_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel];
271 unsigned char *dest;
272
273 assert(image->mt != mt);
274 assert(dstlvl->width == image->base.Width);
275 assert(dstlvl->height == image->base.Height);
276 assert(dstlvl->depth == image->base.Depth);
277
278 radeon_bo_map(mt->bo, GL_TRUE);
279 dest = mt->bo->ptr + dstlvl->faces[face].offset;
280
281 if (image->mt) {
282 /* Format etc. should match, so we really just need a memcpy().
283 * In fact, that memcpy() could be done by the hardware in many
284 * cases, provided that we have a proper memory manager.
285 */
286 r300_mipmap_level *srclvl = &image->mt->levels[image->mtlevel];
287
288 assert(srclvl->size == dstlvl->size);
289 assert(srclvl->rowstride == dstlvl->rowstride);
290
291 radeon_bo_map(image->mt->bo, GL_FALSE);
292 memcpy(dest,
293 image->mt->bo->ptr + srclvl->faces[face].offset,
294 dstlvl->size);
295 radeon_bo_unmap(image->mt->bo);
296
297 r300_miptree_unreference(image->mt);
298 } else {
299 uint srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
300
301 if (mt->tilebits)
302 WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
303
304 copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride,
305 image->base.Height * image->base.Depth, srcrowstride);
306
307 _mesa_free_texmemory(image->base.Data);
308 image->base.Data = 0;
309 }
310
311 radeon_bo_unmap(mt->bo);
312
313 image->mt = mt;
314 image->mtface = face;
315 image->mtlevel = level;
316 r300_miptree_reference(image->mt);
317 }
318
319
320 /**
321 * Ensure the given texture is ready for rendering.
322 *
323 * Mostly this means populating the texture object's mipmap tree.
324 */
325 static GLboolean r300_validate_texture(GLcontext * ctx, struct gl_texture_object *texObj)
326 {
327 r300ContextPtr rmesa = R300_CONTEXT(ctx);
328 r300TexObj *t = r300_tex_obj(texObj);
329 r300_texture_image *baseimage = get_r300_texture_image(texObj->Image[0][texObj->BaseLevel]);
330 int face, level;
331
332 if (t->validated || t->image_override)
333 return GL_TRUE;
334
335 if (RADEON_DEBUG & DEBUG_TEXTURE)
336 fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj);
337
338 if (baseimage->base.Border > 0)
339 return GL_FALSE;
340
341 /* Ensure a matching miptree exists.
342 *
343 * Differing mipmap trees can result when the app uses TexImage to
344 * change texture dimensions.
345 *
346 * Prefer to use base image's miptree if it
347 * exists, since that most likely contains more valid data (remember
348 * that the base level is usually significantly larger than the rest
349 * of the miptree, so cubemaps are the only possible exception).
350 */
351 if (baseimage->mt &&
352 baseimage->mt != t->mt &&
353 r300_miptree_matches_texture(baseimage->mt, &t->base)) {
354 r300_miptree_unreference(t->mt);
355 t->mt = baseimage->mt;
356 r300_miptree_reference(t->mt);
357 } else if (t->mt && !r300_miptree_matches_texture(t->mt, &t->base)) {
358 r300_miptree_unreference(t->mt);
359 t->mt = 0;
360 }
361
362 if (!t->mt) {
363 if (RADEON_DEBUG & DEBUG_TEXTURE)
364 fprintf(stderr, " Allocate new miptree\n");
365 r300_try_alloc_miptree(rmesa, t, &baseimage->base, 0, texObj->BaseLevel);
366 if (!t->mt) {
367 _mesa_problem(ctx, "r300_validate_texture failed to alloc miptree");
368 return GL_FALSE;
369 }
370 }
371
372 /* Ensure all images are stored in the single main miptree */
373 for(face = 0; face < t->mt->faces; ++face) {
374 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) {
375 r300_texture_image *image = get_r300_texture_image(texObj->Image[face][level]);
376 if (RADEON_DEBUG & DEBUG_TEXTURE)
377 fprintf(stderr, " face %i, level %i... ", face, level);
378 if (t->mt == image->mt) {
379 if (RADEON_DEBUG & DEBUG_TEXTURE)
380 fprintf(stderr, "OK\n");
381 continue;
382 }
383
384 if (RADEON_DEBUG & DEBUG_TEXTURE)
385 fprintf(stderr, "migrating\n");
386 migrate_image_to_miptree(t->mt, image, face, level);
387 }
388 }
389
390 /* Configure the hardware registers (more precisely, the cached version
391 * of the hardware registers). */
392 setup_hardware_state(rmesa, t);
393
394 t->validated = GL_TRUE;
395 return GL_TRUE;
396 }
397
398
399 /**
400 * Ensure all enabled and complete textures are uploaded.
401 */
402 void r300ValidateTextures(GLcontext * ctx)
403 {
404 int i;
405
406 for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
407 if (!ctx->Texture.Unit[i]._ReallyEnabled)
408 continue;
409
410 if (!r300_validate_texture(ctx, ctx->Texture.Unit[i]._Current)) {
411 _mesa_warning(ctx,
412 "failed to validate texture for unit %d.\n",
413 i);
414 }
415 }
416 }
417
418 void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
419 unsigned long long offset, GLint depth, GLuint pitch)
420 {
421 r300ContextPtr rmesa = pDRICtx->driverPrivate;
422 struct gl_texture_object *tObj =
423 _mesa_lookup_texture(rmesa->radeon.glCtx, texname);
424 r300TexObjPtr t = r300_tex_obj(tObj);
425 uint32_t pitch_val;
426
427 if (!tObj)
428 return;
429
430 t->image_override = GL_TRUE;
431
432 if (!offset)
433 return;
434 t->bo = NULL;
435 t->override_offset = offset;
436 t->pitch_reg &= (1 << 13) -1;
437 pitch_val = pitch;
438
439 switch (depth) {
440 case 32:
441 t->format = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
442 t->filter |= tx_table[2].filter;
443 pitch_val /= 4;
444 break;
445 case 24:
446 default:
447 t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
448 t->filter |= tx_table[4].filter;
449 pitch_val /= 4;
450 break;
451 case 16:
452 t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
453 t->filter |= tx_table[5].filter;
454 pitch_val /= 2;
455 break;
456 }
457 pitch_val--;
458
459 t->pitch_reg |= pitch_val;
460 }
461
462 void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
463 {
464 struct gl_texture_unit *texUnit;
465 struct gl_texture_object *texObj;
466 struct gl_texture_image *texImage;
467 struct radeon_renderbuffer *rb;
468 radeonContextPtr radeon;
469 r300ContextPtr rmesa;
470 GLframebuffer *fb;
471 r300TexObjPtr t;
472 uint32_t pitch_val;
473
474 target = GL_TEXTURE_RECTANGLE_ARB;
475 radeon = pDRICtx->driverPrivate;
476 rmesa = pDRICtx->driverPrivate;
477 fb = dPriv->driverPrivate;
478 texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit];
479 texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target);
480 texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0);
481
482 radeon_update_renderbuffers(pDRICtx, dPriv);
483 rb = (void*)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
484 if (rb->bo == NULL) {
485 /* Failed to BO for the buffer */
486 return;
487 }
488
489 _mesa_lock_texture(radeon->glCtx, texObj);
490 _mesa_init_teximage_fields(radeon->glCtx, target, texImage,
491 rb->width, rb->height, rb->cpp, 0, rb->cpp);
492 texImage->TexFormat = &_mesa_texformat_rgba8888_rev;
493
494 t = r300_tex_obj(texObj);
495 if (t == NULL) {
496 return;
497 }
498 t->bo = rb->bo;
499 t->tile_bits = 0;
500 t->image_override = GL_TRUE;
501 t->override_offset = 0;
502 t->pitch_reg &= (1 << 13) -1;
503 pitch_val = rb->pitch;
504 switch (rb->cpp) {
505 case 4:
506 t->format = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
507 t->filter |= tx_table[2].filter;
508 pitch_val /= 4;
509 break;
510 case 3:
511 default:
512 t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
513 t->filter |= tx_table[4].filter;
514 pitch_val /= 4;
515 break;
516 case 2:
517 t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
518 t->filter |= tx_table[5].filter;
519 pitch_val /= 2;
520 break;
521 }
522 pitch_val--;
523 t->size = ((rb->width - 1) << R300_TX_WIDTHMASK_SHIFT) |
524 ((rb->height - 1) << R300_TX_HEIGHTMASK_SHIFT);
525 t->size |= R300_TX_SIZE_TXPITCH_EN;
526 t->pitch_reg |= pitch_val;
527 t->validated = GL_TRUE;
528 _mesa_unlock_texture(radeon->glCtx, texObj);
529 return;
530 }