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