i965: fix bugs in projective texture coordinates
[mesa.git] / src / mesa / drivers / dri / r300 / r300_tex.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 * \file
31 *
32 * \author Keith Whitwell <keith@tungstengraphics.com>
33 */
34
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/colormac.h"
38 #include "main/context.h"
39 #include "main/enums.h"
40 #include "main/image.h"
41 #include "main/simple_list.h"
42 #include "main/texformat.h"
43 #include "main/texstore.h"
44 #include "main/teximage.h"
45 #include "main/texobj.h"
46
47 #include "texmem.h"
48
49 #include "r300_context.h"
50 #include "r300_state.h"
51 #include "r300_ioctl.h"
52 #include "r300_tex.h"
53
54 #include "xmlpool.h"
55
56
57 static unsigned int translate_wrap_mode(GLenum wrapmode)
58 {
59 switch(wrapmode) {
60 case GL_REPEAT: return R300_TX_REPEAT;
61 case GL_CLAMP: return R300_TX_CLAMP;
62 case GL_CLAMP_TO_EDGE: return R300_TX_CLAMP_TO_EDGE;
63 case GL_CLAMP_TO_BORDER: return R300_TX_CLAMP_TO_BORDER;
64 case GL_MIRRORED_REPEAT: return R300_TX_REPEAT | R300_TX_MIRRORED;
65 case GL_MIRROR_CLAMP_EXT: return R300_TX_CLAMP | R300_TX_MIRRORED;
66 case GL_MIRROR_CLAMP_TO_EDGE_EXT: return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
67 case GL_MIRROR_CLAMP_TO_BORDER_EXT: return R300_TX_CLAMP_TO_BORDER | R300_TX_MIRRORED;
68 default:
69 _mesa_problem(NULL, "bad wrap mode in %s", __FUNCTION__);
70 return 0;
71 }
72 }
73
74
75 /**
76 * Update the cached hardware registers based on the current texture wrap modes.
77 *
78 * \param t Texture object whose wrap modes are to be set
79 */
80 static void r300UpdateTexWrap(r300TexObjPtr t)
81 {
82 struct gl_texture_object *tObj = t->base.tObj;
83
84 t->filter &=
85 ~(R300_TX_WRAP_S_MASK | R300_TX_WRAP_T_MASK | R300_TX_WRAP_R_MASK);
86
87 t->filter |= translate_wrap_mode(tObj->WrapS) << R300_TX_WRAP_S_SHIFT;
88
89 if (tObj->Target != GL_TEXTURE_1D) {
90 t->filter |= translate_wrap_mode(tObj->WrapT) << R300_TX_WRAP_T_SHIFT;
91
92 if (tObj->Target == GL_TEXTURE_3D)
93 t->filter |= translate_wrap_mode(tObj->WrapR) << R300_TX_WRAP_R_SHIFT;
94 }
95 }
96
97 static GLuint aniso_filter(GLfloat anisotropy)
98 {
99 if (anisotropy >= 16.0) {
100 return R300_TX_MAX_ANISO_16_TO_1;
101 } else if (anisotropy >= 8.0) {
102 return R300_TX_MAX_ANISO_8_TO_1;
103 } else if (anisotropy >= 4.0) {
104 return R300_TX_MAX_ANISO_4_TO_1;
105 } else if (anisotropy >= 2.0) {
106 return R300_TX_MAX_ANISO_2_TO_1;
107 } else {
108 return R300_TX_MAX_ANISO_1_TO_1;
109 }
110 }
111
112 /**
113 * Set the texture magnification and minification modes.
114 *
115 * \param t Texture whose filter modes are to be set
116 * \param minf Texture minification mode
117 * \param magf Texture magnification mode
118 * \param anisotropy Maximum anisotropy level
119 */
120 static void r300SetTexFilter(r300TexObjPtr t, GLenum minf, GLenum magf, GLfloat anisotropy)
121 {
122 t->filter &= ~(R300_TX_MIN_FILTER_MASK | R300_TX_MIN_FILTER_MIP_MASK | R300_TX_MAG_FILTER_MASK | R300_TX_MAX_ANISO_MASK);
123 t->filter_1 &= ~R300_EDGE_ANISO_EDGE_ONLY;
124
125 /* Note that EXT_texture_filter_anisotropic is extremely vague about
126 * how anisotropic filtering interacts with the "normal" filter modes.
127 * When anisotropic filtering is enabled, we override min and mag
128 * filter settings completely. This includes driconf's settings.
129 */
130 if (anisotropy >= 2.0 && (minf != GL_NEAREST) && (magf != GL_NEAREST)) {
131 t->filter |= R300_TX_MAG_FILTER_ANISO
132 | R300_TX_MIN_FILTER_ANISO
133 | R300_TX_MIN_FILTER_MIP_LINEAR
134 | aniso_filter(anisotropy);
135 if (RADEON_DEBUG & DEBUG_TEXTURE)
136 fprintf(stderr, "Using maximum anisotropy of %f\n", anisotropy);
137 return;
138 }
139
140 switch (minf) {
141 case GL_NEAREST:
142 t->filter |= R300_TX_MIN_FILTER_NEAREST;
143 break;
144 case GL_LINEAR:
145 t->filter |= R300_TX_MIN_FILTER_LINEAR;
146 break;
147 case GL_NEAREST_MIPMAP_NEAREST:
148 t->filter |= R300_TX_MIN_FILTER_NEAREST|R300_TX_MIN_FILTER_MIP_NEAREST;
149 break;
150 case GL_NEAREST_MIPMAP_LINEAR:
151 t->filter |= R300_TX_MIN_FILTER_NEAREST|R300_TX_MIN_FILTER_MIP_LINEAR;
152 break;
153 case GL_LINEAR_MIPMAP_NEAREST:
154 t->filter |= R300_TX_MIN_FILTER_LINEAR|R300_TX_MIN_FILTER_MIP_NEAREST;
155 break;
156 case GL_LINEAR_MIPMAP_LINEAR:
157 t->filter |= R300_TX_MIN_FILTER_LINEAR|R300_TX_MIN_FILTER_MIP_LINEAR;
158 break;
159 }
160
161 /* Note we don't have 3D mipmaps so only use the mag filter setting
162 * to set the 3D texture filter mode.
163 */
164 switch (magf) {
165 case GL_NEAREST:
166 t->filter |= R300_TX_MAG_FILTER_NEAREST;
167 break;
168 case GL_LINEAR:
169 t->filter |= R300_TX_MAG_FILTER_LINEAR;
170 break;
171 }
172 }
173
174 static void r300SetTexBorderColor(r300TexObjPtr t, const GLfloat color[4])
175 {
176 GLubyte c[4];
177 CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
178 CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
179 CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
180 CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
181 t->pp_border_color = PACK_COLOR_8888(c[3], c[0], c[1], c[2]);
182 }
183
184 /**
185 * Allocate space for and load the mesa images into the texture memory block.
186 * This will happen before drawing with a new texture, or drawing with a
187 * texture after it was swapped out or teximaged again.
188 */
189
190 static r300TexObjPtr r300AllocTexObj(struct gl_texture_object *texObj)
191 {
192 r300TexObjPtr t;
193
194 t = CALLOC_STRUCT(r300_tex_obj);
195 texObj->DriverData = t;
196 if (t != NULL) {
197 if (RADEON_DEBUG & DEBUG_TEXTURE) {
198 fprintf(stderr, "%s( %p, %p )\n", __FUNCTION__,
199 (void *)texObj, (void *)t);
200 }
201
202 /* Initialize non-image-dependent parts of the state:
203 */
204 t->base.tObj = texObj;
205 t->border_fallback = GL_FALSE;
206
207 make_empty_list(&t->base);
208
209 r300UpdateTexWrap(t);
210 r300SetTexFilter(t, texObj->MinFilter, texObj->MagFilter, texObj->MaxAnisotropy);
211 r300SetTexBorderColor(t, texObj->BorderColor);
212 }
213
214 return t;
215 }
216
217 /* try to find a format which will only need a memcopy */
218 static const struct gl_texture_format *r300Choose8888TexFormat(GLenum srcFormat,
219 GLenum srcType)
220 {
221 const GLuint ui = 1;
222 const GLubyte littleEndian = *((const GLubyte *)&ui);
223
224 if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
225 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
226 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
227 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
228 return &_mesa_texformat_rgba8888;
229 } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
230 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
231 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
232 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
233 return &_mesa_texformat_rgba8888_rev;
234 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
235 srcType == GL_UNSIGNED_INT_8_8_8_8)) {
236 return &_mesa_texformat_argb8888_rev;
237 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
238 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
239 return &_mesa_texformat_argb8888;
240 } else
241 return _dri_texformat_argb8888;
242 }
243
244 static const struct gl_texture_format *r300ChooseTextureFormat(GLcontext * ctx,
245 GLint
246 internalFormat,
247 GLenum format,
248 GLenum type)
249 {
250 r300ContextPtr rmesa = R300_CONTEXT(ctx);
251 const GLboolean do32bpt =
252 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32);
253 const GLboolean force16bpt =
254 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16);
255 (void)format;
256
257 #if 0
258 fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n",
259 _mesa_lookup_enum_by_nr(internalFormat), internalFormat,
260 _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format));
261 fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt);
262 #endif
263
264 switch (internalFormat) {
265 case 4:
266 case GL_RGBA:
267 case GL_COMPRESSED_RGBA:
268 switch (type) {
269 case GL_UNSIGNED_INT_10_10_10_2:
270 case GL_UNSIGNED_INT_2_10_10_10_REV:
271 return do32bpt ? _dri_texformat_argb8888 :
272 _dri_texformat_argb1555;
273 case GL_UNSIGNED_SHORT_4_4_4_4:
274 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
275 return _dri_texformat_argb4444;
276 case GL_UNSIGNED_SHORT_5_5_5_1:
277 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
278 return _dri_texformat_argb1555;
279 default:
280 return do32bpt ? r300Choose8888TexFormat(format, type) :
281 _dri_texformat_argb4444;
282 }
283
284 case 3:
285 case GL_RGB:
286 case GL_COMPRESSED_RGB:
287 switch (type) {
288 case GL_UNSIGNED_SHORT_4_4_4_4:
289 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
290 return _dri_texformat_argb4444;
291 case GL_UNSIGNED_SHORT_5_5_5_1:
292 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
293 return _dri_texformat_argb1555;
294 case GL_UNSIGNED_SHORT_5_6_5:
295 case GL_UNSIGNED_SHORT_5_6_5_REV:
296 return _dri_texformat_rgb565;
297 default:
298 return do32bpt ? _dri_texformat_argb8888 :
299 _dri_texformat_rgb565;
300 }
301
302 case GL_RGBA8:
303 case GL_RGB10_A2:
304 case GL_RGBA12:
305 case GL_RGBA16:
306 return !force16bpt ?
307 r300Choose8888TexFormat(format,
308 type) : _dri_texformat_argb4444;
309
310 case GL_RGBA4:
311 case GL_RGBA2:
312 return _dri_texformat_argb4444;
313
314 case GL_RGB5_A1:
315 return _dri_texformat_argb1555;
316
317 case GL_RGB8:
318 case GL_RGB10:
319 case GL_RGB12:
320 case GL_RGB16:
321 return !force16bpt ? _dri_texformat_argb8888 :
322 _dri_texformat_rgb565;
323
324 case GL_RGB5:
325 case GL_RGB4:
326 case GL_R3_G3_B2:
327 return _dri_texformat_rgb565;
328
329 case GL_ALPHA:
330 case GL_ALPHA4:
331 case GL_ALPHA8:
332 case GL_ALPHA12:
333 case GL_ALPHA16:
334 case GL_COMPRESSED_ALPHA:
335 return _dri_texformat_a8;
336
337 case 1:
338 case GL_LUMINANCE:
339 case GL_LUMINANCE4:
340 case GL_LUMINANCE8:
341 case GL_LUMINANCE12:
342 case GL_LUMINANCE16:
343 case GL_COMPRESSED_LUMINANCE:
344 return _dri_texformat_l8;
345
346 case 2:
347 case GL_LUMINANCE_ALPHA:
348 case GL_LUMINANCE4_ALPHA4:
349 case GL_LUMINANCE6_ALPHA2:
350 case GL_LUMINANCE8_ALPHA8:
351 case GL_LUMINANCE12_ALPHA4:
352 case GL_LUMINANCE12_ALPHA12:
353 case GL_LUMINANCE16_ALPHA16:
354 case GL_COMPRESSED_LUMINANCE_ALPHA:
355 return _dri_texformat_al88;
356
357 case GL_INTENSITY:
358 case GL_INTENSITY4:
359 case GL_INTENSITY8:
360 case GL_INTENSITY12:
361 case GL_INTENSITY16:
362 case GL_COMPRESSED_INTENSITY:
363 return _dri_texformat_i8;
364
365 case GL_YCBCR_MESA:
366 if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
367 type == GL_UNSIGNED_BYTE)
368 return &_mesa_texformat_ycbcr;
369 else
370 return &_mesa_texformat_ycbcr_rev;
371
372 case GL_RGB_S3TC:
373 case GL_RGB4_S3TC:
374 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
375 return &_mesa_texformat_rgb_dxt1;
376
377 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
378 return &_mesa_texformat_rgba_dxt1;
379
380 case GL_RGBA_S3TC:
381 case GL_RGBA4_S3TC:
382 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
383 return &_mesa_texformat_rgba_dxt3;
384
385 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
386 return &_mesa_texformat_rgba_dxt5;
387
388 case GL_ALPHA16F_ARB:
389 return &_mesa_texformat_alpha_float16;
390 case GL_ALPHA32F_ARB:
391 return &_mesa_texformat_alpha_float32;
392 case GL_LUMINANCE16F_ARB:
393 return &_mesa_texformat_luminance_float16;
394 case GL_LUMINANCE32F_ARB:
395 return &_mesa_texformat_luminance_float32;
396 case GL_LUMINANCE_ALPHA16F_ARB:
397 return &_mesa_texformat_luminance_alpha_float16;
398 case GL_LUMINANCE_ALPHA32F_ARB:
399 return &_mesa_texformat_luminance_alpha_float32;
400 case GL_INTENSITY16F_ARB:
401 return &_mesa_texformat_intensity_float16;
402 case GL_INTENSITY32F_ARB:
403 return &_mesa_texformat_intensity_float32;
404 case GL_RGB16F_ARB:
405 return &_mesa_texformat_rgba_float16;
406 case GL_RGB32F_ARB:
407 return &_mesa_texformat_rgba_float32;
408 case GL_RGBA16F_ARB:
409 return &_mesa_texformat_rgba_float16;
410 case GL_RGBA32F_ARB:
411 return &_mesa_texformat_rgba_float32;
412
413 case GL_DEPTH_COMPONENT:
414 case GL_DEPTH_COMPONENT16:
415 case GL_DEPTH_COMPONENT24:
416 case GL_DEPTH_COMPONENT32:
417 #if 0
418 switch (type) {
419 case GL_UNSIGNED_BYTE:
420 case GL_UNSIGNED_SHORT:
421 return &_mesa_texformat_z16;
422 case GL_UNSIGNED_INT:
423 return &_mesa_texformat_z32;
424 case GL_UNSIGNED_INT_24_8_EXT:
425 default:
426 return &_mesa_texformat_z24_s8;
427 }
428 #else
429 return &_mesa_texformat_z16;
430 #endif
431
432 default:
433 _mesa_problem(ctx,
434 "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
435 (int)internalFormat);
436 return NULL;
437 }
438
439 return NULL; /* never get here */
440 }
441
442 static GLboolean
443 r300ValidateClientStorage(GLcontext * ctx, GLenum target,
444 GLint internalFormat,
445 GLint srcWidth, GLint srcHeight,
446 GLenum format, GLenum type, const void *pixels,
447 const struct gl_pixelstore_attrib *packing,
448 struct gl_texture_object *texObj,
449 struct gl_texture_image *texImage)
450 {
451 r300ContextPtr rmesa = R300_CONTEXT(ctx);
452
453 if (RADEON_DEBUG & DEBUG_TEXTURE)
454 fprintf(stderr, "intformat %s format %s type %s\n",
455 _mesa_lookup_enum_by_nr(internalFormat),
456 _mesa_lookup_enum_by_nr(format),
457 _mesa_lookup_enum_by_nr(type));
458
459 if (!ctx->Unpack.ClientStorage)
460 return 0;
461
462 if (ctx->_ImageTransferState ||
463 texImage->IsCompressed || texObj->GenerateMipmap)
464 return 0;
465
466 /* This list is incomplete, may be different on ppc???
467 */
468 switch (internalFormat) {
469 case GL_RGBA:
470 if (format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV) {
471 texImage->TexFormat = _dri_texformat_argb8888;
472 } else
473 return 0;
474 break;
475
476 case GL_RGB:
477 if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) {
478 texImage->TexFormat = _dri_texformat_rgb565;
479 } else
480 return 0;
481 break;
482
483 case GL_YCBCR_MESA:
484 if (format == GL_YCBCR_MESA &&
485 type == GL_UNSIGNED_SHORT_8_8_REV_APPLE) {
486 texImage->TexFormat = &_mesa_texformat_ycbcr_rev;
487 } else if (format == GL_YCBCR_MESA &&
488 (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
489 type == GL_UNSIGNED_BYTE)) {
490 texImage->TexFormat = &_mesa_texformat_ycbcr;
491 } else
492 return 0;
493 break;
494
495 default:
496 return 0;
497 }
498
499 /* Could deal with these packing issues, but currently don't:
500 */
501 if (packing->SkipPixels ||
502 packing->SkipRows || packing->SwapBytes || packing->LsbFirst) {
503 return 0;
504 }
505
506 GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth,
507 format, type);
508
509 if (RADEON_DEBUG & DEBUG_TEXTURE)
510 fprintf(stderr, "%s: srcRowStride %d/%x\n",
511 __FUNCTION__, srcRowStride, srcRowStride);
512
513 /* Could check this later in upload, pitch restrictions could be
514 * relaxed, but would need to store the image pitch somewhere,
515 * as packing details might change before image is uploaded:
516 */
517 if (!r300IsGartMemory(rmesa, pixels, srcHeight * srcRowStride)
518 || (srcRowStride & 63))
519 return 0;
520
521 /* Have validated that _mesa_transfer_teximage would be a straight
522 * memcpy at this point. NOTE: future calls to TexSubImage will
523 * overwrite the client data. This is explicitly mentioned in the
524 * extension spec.
525 */
526 texImage->Data = (void *)pixels;
527 texImage->IsClientData = GL_TRUE;
528 texImage->RowStride = srcRowStride / texImage->TexFormat->TexelBytes;
529
530 return 1;
531 }
532
533 static void r300TexImage1D(GLcontext * ctx, GLenum target, GLint level,
534 GLint internalFormat,
535 GLint width, GLint border,
536 GLenum format, GLenum type, const GLvoid * pixels,
537 const struct gl_pixelstore_attrib *packing,
538 struct gl_texture_object *texObj,
539 struct gl_texture_image *texImage)
540 {
541 driTextureObject *t = (driTextureObject *) texObj->DriverData;
542
543 if (t) {
544 driSwapOutTextureObject(t);
545 } else {
546 t = (driTextureObject *) r300AllocTexObj(texObj);
547 if (!t) {
548 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
549 return;
550 }
551 }
552
553 /* Note, this will call ChooseTextureFormat */
554 _mesa_store_teximage1d(ctx, target, level, internalFormat,
555 width, border, format, type, pixels,
556 &ctx->Unpack, texObj, texImage);
557
558 t->dirty_images[0] |= (1 << level);
559 }
560
561 static void r300TexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
562 GLint xoffset,
563 GLsizei width,
564 GLenum format, GLenum type,
565 const GLvoid * pixels,
566 const struct gl_pixelstore_attrib *packing,
567 struct gl_texture_object *texObj,
568 struct gl_texture_image *texImage)
569 {
570 driTextureObject *t = (driTextureObject *) texObj->DriverData;
571
572 assert(t); /* this _should_ be true */
573 if (t) {
574 driSwapOutTextureObject(t);
575 } else {
576 t = (driTextureObject *) r300AllocTexObj(texObj);
577 if (!t) {
578 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
579 return;
580 }
581 }
582
583 _mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
584 format, type, pixels, packing, texObj,
585 texImage);
586
587 t->dirty_images[0] |= (1 << level);
588 }
589
590 static void r300TexImage2D(GLcontext * ctx, GLenum target, GLint level,
591 GLint internalFormat,
592 GLint width, GLint height, GLint border,
593 GLenum format, GLenum type, const GLvoid * pixels,
594 const struct gl_pixelstore_attrib *packing,
595 struct gl_texture_object *texObj,
596 struct gl_texture_image *texImage)
597 {
598 driTextureObject *t = (driTextureObject *) texObj->DriverData;
599 GLuint face;
600
601 /* which cube face or ordinary 2D image */
602 switch (target) {
603 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
604 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
605 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
606 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
607 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
608 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
609 face =
610 (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
611 ASSERT(face < 6);
612 break;
613 default:
614 face = 0;
615 }
616
617 if (t != NULL) {
618 driSwapOutTextureObject(t);
619 } else {
620 t = (driTextureObject *) r300AllocTexObj(texObj);
621 if (!t) {
622 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
623 return;
624 }
625 }
626
627 texImage->IsClientData = GL_FALSE;
628
629 if (r300ValidateClientStorage(ctx, target,
630 internalFormat,
631 width, height,
632 format, type, pixels,
633 packing, texObj, texImage)) {
634 if (RADEON_DEBUG & DEBUG_TEXTURE)
635 fprintf(stderr, "%s: Using client storage\n",
636 __FUNCTION__);
637 } else {
638 if (RADEON_DEBUG & DEBUG_TEXTURE)
639 fprintf(stderr, "%s: Using normal storage\n",
640 __FUNCTION__);
641
642 /* Normal path: copy (to cached memory) and eventually upload
643 * via another copy to GART memory and then a blit... Could
644 * eliminate one copy by going straight to (permanent) GART.
645 *
646 * Note, this will call r300ChooseTextureFormat.
647 */
648 _mesa_store_teximage2d(ctx, target, level, internalFormat,
649 width, height, border, format, type,
650 pixels, &ctx->Unpack, texObj, texImage);
651
652 t->dirty_images[face] |= (1 << level);
653 }
654 }
655
656 static void r300TexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
657 GLint xoffset, GLint yoffset,
658 GLsizei width, GLsizei height,
659 GLenum format, GLenum type,
660 const GLvoid * pixels,
661 const struct gl_pixelstore_attrib *packing,
662 struct gl_texture_object *texObj,
663 struct gl_texture_image *texImage)
664 {
665 driTextureObject *t = (driTextureObject *) texObj->DriverData;
666 GLuint face;
667
668 /* which cube face or ordinary 2D image */
669 switch (target) {
670 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
671 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
672 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
673 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
674 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
675 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
676 face =
677 (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
678 ASSERT(face < 6);
679 break;
680 default:
681 face = 0;
682 }
683
684 assert(t); /* this _should_ be true */
685 if (t) {
686 driSwapOutTextureObject(t);
687 } else {
688 t = (driTextureObject *) r300AllocTexObj(texObj);
689 if (!t) {
690 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
691 return;
692 }
693 }
694
695 _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
696 height, format, type, pixels, packing, texObj,
697 texImage);
698
699 t->dirty_images[face] |= (1 << level);
700 }
701
702 static void r300CompressedTexImage2D(GLcontext * ctx, GLenum target,
703 GLint level, GLint internalFormat,
704 GLint width, GLint height, GLint border,
705 GLsizei imageSize, const GLvoid * data,
706 struct gl_texture_object *texObj,
707 struct gl_texture_image *texImage)
708 {
709 driTextureObject *t = (driTextureObject *) texObj->DriverData;
710 GLuint face;
711
712 /* which cube face or ordinary 2D image */
713 switch (target) {
714 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
715 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
716 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
717 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
718 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
719 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
720 face =
721 (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
722 ASSERT(face < 6);
723 break;
724 default:
725 face = 0;
726 }
727
728 if (t != NULL) {
729 driSwapOutTextureObject(t);
730 } else {
731 t = (driTextureObject *) r300AllocTexObj(texObj);
732 if (!t) {
733 _mesa_error(ctx, GL_OUT_OF_MEMORY,
734 "glCompressedTexImage2D");
735 return;
736 }
737 }
738
739 texImage->IsClientData = GL_FALSE;
740
741 /* can't call this, different parameters. Would never evaluate to true anyway currently */
742 #if 0
743 if (r300ValidateClientStorage(ctx, target,
744 internalFormat,
745 width, height,
746 format, type, pixels,
747 packing, texObj, texImage)) {
748 if (RADEON_DEBUG & DEBUG_TEXTURE)
749 fprintf(stderr, "%s: Using client storage\n",
750 __FUNCTION__);
751 } else
752 #endif
753 {
754 if (RADEON_DEBUG & DEBUG_TEXTURE)
755 fprintf(stderr, "%s: Using normal storage\n",
756 __FUNCTION__);
757
758 /* Normal path: copy (to cached memory) and eventually upload
759 * via another copy to GART memory and then a blit... Could
760 * eliminate one copy by going straight to (permanent) GART.
761 *
762 * Note, this will call r300ChooseTextureFormat.
763 */
764 _mesa_store_compressed_teximage2d(ctx, target, level,
765 internalFormat, width, height,
766 border, imageSize, data,
767 texObj, texImage);
768
769 t->dirty_images[face] |= (1 << level);
770 }
771 }
772
773 static void r300CompressedTexSubImage2D(GLcontext * ctx, GLenum target,
774 GLint level, GLint xoffset,
775 GLint yoffset, GLsizei width,
776 GLsizei height, GLenum format,
777 GLsizei imageSize, const GLvoid * data,
778 struct gl_texture_object *texObj,
779 struct gl_texture_image *texImage)
780 {
781 driTextureObject *t = (driTextureObject *) texObj->DriverData;
782 GLuint face;
783
784 /* which cube face or ordinary 2D image */
785 switch (target) {
786 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
787 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
788 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
789 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
790 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
791 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
792 face =
793 (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
794 ASSERT(face < 6);
795 break;
796 default:
797 face = 0;
798 }
799
800 assert(t); /* this _should_ be true */
801 if (t) {
802 driSwapOutTextureObject(t);
803 } else {
804 t = (driTextureObject *) r300AllocTexObj(texObj);
805 if (!t) {
806 _mesa_error(ctx, GL_OUT_OF_MEMORY,
807 "glCompressedTexSubImage3D");
808 return;
809 }
810 }
811
812 _mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset,
813 yoffset, width, height, format,
814 imageSize, data, texObj, texImage);
815
816 t->dirty_images[face] |= (1 << level);
817 }
818
819 static void r300TexImage3D(GLcontext * ctx, GLenum target, GLint level,
820 GLint internalFormat,
821 GLint width, GLint height, GLint depth,
822 GLint border,
823 GLenum format, GLenum type, const GLvoid * pixels,
824 const struct gl_pixelstore_attrib *packing,
825 struct gl_texture_object *texObj,
826 struct gl_texture_image *texImage)
827 {
828 driTextureObject *t = (driTextureObject *) texObj->DriverData;
829
830 if (t) {
831 driSwapOutTextureObject(t);
832 } else {
833 t = (driTextureObject *) r300AllocTexObj(texObj);
834 if (!t) {
835 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
836 return;
837 }
838 }
839
840 texImage->IsClientData = GL_FALSE;
841
842 #if 0
843 if (r300ValidateClientStorage(ctx, target,
844 internalFormat,
845 width, height,
846 format, type, pixels,
847 packing, texObj, texImage)) {
848 if (RADEON_DEBUG & DEBUG_TEXTURE)
849 fprintf(stderr, "%s: Using client storage\n",
850 __FUNCTION__);
851 } else
852 #endif
853 {
854 if (RADEON_DEBUG & DEBUG_TEXTURE)
855 fprintf(stderr, "%s: Using normal storage\n",
856 __FUNCTION__);
857
858 /* Normal path: copy (to cached memory) and eventually upload
859 * via another copy to GART memory and then a blit... Could
860 * eliminate one copy by going straight to (permanent) GART.
861 *
862 * Note, this will call r300ChooseTextureFormat.
863 */
864 _mesa_store_teximage3d(ctx, target, level, internalFormat,
865 width, height, depth, border,
866 format, type, pixels,
867 &ctx->Unpack, texObj, texImage);
868
869 t->dirty_images[0] |= (1 << level);
870 }
871 }
872
873 static void
874 r300TexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
875 GLint xoffset, GLint yoffset, GLint zoffset,
876 GLsizei width, GLsizei height, GLsizei depth,
877 GLenum format, GLenum type,
878 const GLvoid * pixels,
879 const struct gl_pixelstore_attrib *packing,
880 struct gl_texture_object *texObj,
881 struct gl_texture_image *texImage)
882 {
883 driTextureObject *t = (driTextureObject *) texObj->DriverData;
884
885 /* fprintf(stderr, "%s\n", __FUNCTION__); */
886
887 assert(t); /* this _should_ be true */
888 if (t) {
889 driSwapOutTextureObject(t);
890 } else {
891 t = (driTextureObject *) r300AllocTexObj(texObj);
892 if (!t) {
893 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
894 return;
895 }
896 texObj->DriverData = t;
897 }
898
899 _mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset,
900 width, height, depth,
901 format, type, pixels, packing, texObj,
902 texImage);
903
904 t->dirty_images[0] |= (1 << level);
905 }
906
907 /**
908 * Changes variables and flags for a state update, which will happen at the
909 * next UpdateTextureState
910 */
911
912 static void r300TexParameter(GLcontext * ctx, GLenum target,
913 struct gl_texture_object *texObj,
914 GLenum pname, const GLfloat * params)
915 {
916 r300TexObjPtr t = (r300TexObjPtr) texObj->DriverData;
917
918 if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
919 fprintf(stderr, "%s( %s )\n", __FUNCTION__,
920 _mesa_lookup_enum_by_nr(pname));
921 }
922
923 switch (pname) {
924 case GL_TEXTURE_MIN_FILTER:
925 case GL_TEXTURE_MAG_FILTER:
926 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
927 r300SetTexFilter(t, texObj->MinFilter, texObj->MagFilter, texObj->MaxAnisotropy);
928 break;
929
930 case GL_TEXTURE_WRAP_S:
931 case GL_TEXTURE_WRAP_T:
932 case GL_TEXTURE_WRAP_R:
933 r300UpdateTexWrap(t);
934 break;
935
936 case GL_TEXTURE_BORDER_COLOR:
937 r300SetTexBorderColor(t, texObj->BorderColor);
938 break;
939
940 case GL_TEXTURE_BASE_LEVEL:
941 case GL_TEXTURE_MAX_LEVEL:
942 case GL_TEXTURE_MIN_LOD:
943 case GL_TEXTURE_MAX_LOD:
944 /* This isn't the most efficient solution but there doesn't appear to
945 * be a nice alternative. Since there's no LOD clamping,
946 * we just have to rely on loading the right subset of mipmap levels
947 * to simulate a clamped LOD.
948 */
949 driSwapOutTextureObject((driTextureObject *) t);
950 break;
951
952 case GL_DEPTH_TEXTURE_MODE:
953 if (!texObj->Image[0][texObj->BaseLevel])
954 return;
955 if (texObj->Image[0][texObj->BaseLevel]->TexFormat->BaseFormat
956 == GL_DEPTH_COMPONENT) {
957 r300SetDepthTexMode(texObj);
958 break;
959 } else {
960 /* If the texture isn't a depth texture, changing this
961 * state won't cause any changes to the hardware.
962 * Don't force a flush of texture state.
963 */
964 return;
965 }
966
967 default:
968 return;
969 }
970 }
971
972 static void r300BindTexture(GLcontext * ctx, GLenum target,
973 struct gl_texture_object *texObj)
974 {
975 if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
976 fprintf(stderr, "%s( %p ) unit=%d\n", __FUNCTION__,
977 (void *)texObj, ctx->Texture.CurrentUnit);
978 }
979
980 if ((target == GL_TEXTURE_1D)
981 || (target == GL_TEXTURE_2D)
982 || (target == GL_TEXTURE_3D)
983 || (target == GL_TEXTURE_CUBE_MAP)
984 || (target == GL_TEXTURE_RECTANGLE_NV)) {
985 assert(texObj->DriverData != NULL);
986 }
987 }
988
989 static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj)
990 {
991 r300ContextPtr rmesa = R300_CONTEXT(ctx);
992 driTextureObject *t = (driTextureObject *) texObj->DriverData;
993
994 if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
995 fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__,
996 (void *)texObj,
997 _mesa_lookup_enum_by_nr(texObj->Target));
998 }
999
1000 if (t != NULL) {
1001 if (rmesa) {
1002 R300_FIREVERTICES(rmesa);
1003 }
1004
1005 driDestroyTextureObject(t);
1006 }
1007 /* Free mipmap images and the texture object itself */
1008 _mesa_delete_texture_object(ctx, texObj);
1009 }
1010
1011 /**
1012 * Allocate a new texture object.
1013 * Called via ctx->Driver.NewTextureObject.
1014 * Note: this function will be called during context creation to
1015 * allocate the default texture objects.
1016 * Note: we could use containment here to 'derive' the driver-specific
1017 * texture object from the core mesa gl_texture_object. Not done at this time.
1018 * Fixup MaxAnisotropy according to user preference.
1019 */
1020 static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx,
1021 GLuint name,
1022 GLenum target)
1023 {
1024 r300ContextPtr rmesa = R300_CONTEXT(ctx);
1025 struct gl_texture_object *obj;
1026 obj = _mesa_new_texture_object(ctx, name, target);
1027 if (!obj)
1028 return NULL;
1029 obj->MaxAnisotropy = rmesa->initialMaxAnisotropy;
1030
1031 r300AllocTexObj(obj);
1032 return obj;
1033 }
1034
1035 void r300InitTextureFuncs(struct dd_function_table *functions)
1036 {
1037 /* Note: we only plug in the functions we implement in the driver
1038 * since _mesa_init_driver_functions() was already called.
1039 */
1040 functions->ChooseTextureFormat = r300ChooseTextureFormat;
1041 functions->TexImage1D = r300TexImage1D;
1042 functions->TexImage2D = r300TexImage2D;
1043 functions->TexImage3D = r300TexImage3D;
1044 functions->TexSubImage1D = r300TexSubImage1D;
1045 functions->TexSubImage2D = r300TexSubImage2D;
1046 functions->TexSubImage3D = r300TexSubImage3D;
1047 functions->NewTextureObject = r300NewTextureObject;
1048 functions->BindTexture = r300BindTexture;
1049 functions->DeleteTexture = r300DeleteTexture;
1050 functions->IsTextureResident = driIsTextureResident;
1051
1052 functions->TexParameter = r300TexParameter;
1053
1054 functions->CompressedTexImage2D = r300CompressedTexImage2D;
1055 functions->CompressedTexSubImage2D = r300CompressedTexSubImage2D;
1056
1057 driInitTextureFormats();
1058 }