radeon: fixup some issue with fbos and sw fallbacks
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_texture.c
1 /*
2 * Copyright (C) 2008 Nicolai Haehnle.
3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4 *
5 * The Weather Channel (TM) funded Tungsten Graphics to develop the
6 * initial release of the Radeon 8500 driver under the XFree86 license.
7 * This notice must be preserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining
10 * a copy of this software and associated documentation files (the
11 * "Software"), to deal in the Software without restriction, including
12 * without limitation the rights to use, copy, modify, merge, publish,
13 * distribute, sublicense, and/or sell copies of the Software, and to
14 * permit persons to whom the Software is furnished to do so, subject to
15 * the following conditions:
16 *
17 * The above copyright notice and this permission notice (including the
18 * next paragraph) shall be included in all copies or substantial
19 * portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 *
29 */
30
31 #include "main/glheader.h"
32 #include "main/imports.h"
33 #include "main/context.h"
34 #include "main/convolve.h"
35 #include "main/mipmap.h"
36 #include "main/texcompress.h"
37 #include "main/texformat.h"
38 #include "main/texstore.h"
39 #include "main/teximage.h"
40 #include "main/texobj.h"
41
42 #include "xmlpool.h" /* for symbolic values of enum-type options */
43
44 #include "radeon_common.h"
45
46 #include "radeon_mipmap_tree.h"
47
48
49 static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
50 GLuint numrows, GLuint rowsize)
51 {
52 assert(rowsize <= dststride);
53 assert(rowsize <= srcstride);
54
55 if (rowsize == srcstride && rowsize == dststride) {
56 memcpy(dst, src, numrows*rowsize);
57 } else {
58 GLuint i;
59 for(i = 0; i < numrows; ++i) {
60 memcpy(dst, src, rowsize);
61 dst += dststride;
62 src += srcstride;
63 }
64 }
65 }
66
67 /* textures */
68 /**
69 * Allocate an empty texture image object.
70 */
71 struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx)
72 {
73 return CALLOC(sizeof(radeon_texture_image));
74 }
75
76 /**
77 * Free memory associated with this texture image.
78 */
79 void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage)
80 {
81 radeon_texture_image* image = get_radeon_texture_image(timage);
82
83 if (image->mt) {
84 radeon_miptree_unreference(image->mt);
85 image->mt = 0;
86 assert(!image->base.Data);
87 } else {
88 _mesa_free_texture_image_data(ctx, timage);
89 }
90 if (image->bo) {
91 radeon_bo_unref(image->bo);
92 image->bo = NULL;
93 }
94 if (timage->Data) {
95 _mesa_free_texmemory(timage->Data);
96 timage->Data = NULL;
97 }
98 }
99
100 /* Set Data pointer and additional data for mapped texture image */
101 static void teximage_set_map_data(radeon_texture_image *image)
102 {
103 radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
104
105 image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset;
106 image->base.RowStride = lvl->rowstride / image->mt->bpp;
107 }
108
109
110 /**
111 * Map a single texture image for glTexImage and friends.
112 */
113 void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable)
114 {
115 if (image->mt) {
116 assert(!image->base.Data);
117
118 radeon_bo_map(image->mt->bo, write_enable);
119 teximage_set_map_data(image);
120 }
121 }
122
123
124 void radeon_teximage_unmap(radeon_texture_image *image)
125 {
126 if (image->mt) {
127 assert(image->base.Data);
128
129 image->base.Data = 0;
130 radeon_bo_unmap(image->mt->bo);
131 }
132 }
133
134 /**
135 * Map a validated texture for reading during software rendering.
136 */
137 void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
138 {
139 radeonTexObj* t = radeon_tex_obj(texObj);
140 int face, level;
141
142 if (!radeon_validate_texture_miptree(ctx, texObj))
143 return;
144
145 /* for r100 3D sw fallbacks don't have mt */
146 if (!t->mt)
147 return;
148
149 radeon_bo_map(t->mt->bo, GL_FALSE);
150 for(face = 0; face < t->mt->faces; ++face) {
151 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level)
152 teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level]));
153 }
154 }
155
156 void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
157 {
158 radeonTexObj* t = radeon_tex_obj(texObj);
159 int face, level;
160
161 /* for r100 3D sw fallbacks don't have mt */
162 if (!t->mt)
163 return;
164
165 for(face = 0; face < t->mt->faces; ++face) {
166 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level)
167 texObj->Image[face][level]->Data = 0;
168 }
169 radeon_bo_unmap(t->mt->bo);
170 }
171
172 GLuint radeon_face_for_target(GLenum target)
173 {
174 switch (target) {
175 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
176 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
177 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
178 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
179 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
180 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
181 return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
182 default:
183 return 0;
184 }
185 }
186
187 /**
188 * Wraps Mesa's implementation to ensure that the base level image is mapped.
189 *
190 * This relies on internal details of _mesa_generate_mipmap, in particular
191 * the fact that the memory for recreated texture images is always freed.
192 */
193 static void radeon_generate_mipmap(GLcontext *ctx, GLenum target,
194 struct gl_texture_object *texObj)
195 {
196 radeonTexObj* t = radeon_tex_obj(texObj);
197 GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
198 int i, face;
199
200
201 _mesa_generate_mipmap(ctx, target, texObj);
202
203 for (face = 0; face < nr_faces; face++) {
204 for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) {
205 radeon_texture_image *image;
206
207 image = get_radeon_texture_image(texObj->Image[face][i]);
208
209 if (image == NULL)
210 break;
211
212 image->mtlevel = i;
213 image->mtface = face;
214
215 radeon_miptree_unreference(image->mt);
216 image->mt = NULL;
217 }
218 }
219
220 }
221
222 void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj)
223 {
224 GLuint face = radeon_face_for_target(target);
225 radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]);
226
227 radeon_teximage_map(baseimage, GL_FALSE);
228 radeon_generate_mipmap(ctx, target, texObj);
229 radeon_teximage_unmap(baseimage);
230 }
231
232
233 /* try to find a format which will only need a memcopy */
234 static const struct gl_texture_format *radeonChoose8888TexFormat(radeonContextPtr rmesa,
235 GLenum srcFormat,
236 GLenum srcType)
237 {
238 const GLuint ui = 1;
239 const GLubyte littleEndian = *((const GLubyte *)&ui);
240
241 /* r100 can only do this */
242 if (IS_R100_CLASS(rmesa->radeonScreen))
243 return _dri_texformat_argb8888;
244
245 if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
246 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
247 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
248 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
249 return &_mesa_texformat_rgba8888;
250 } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
251 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
252 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
253 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
254 return &_mesa_texformat_rgba8888_rev;
255 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
256 srcType == GL_UNSIGNED_INT_8_8_8_8)) {
257 return &_mesa_texformat_argb8888_rev;
258 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
259 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
260 return &_mesa_texformat_argb8888;
261 } else
262 return _dri_texformat_argb8888;
263 }
264
265 const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
266 GLint internalFormat,
267 GLenum format,
268 GLenum type)
269 {
270 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
271 const GLboolean do32bpt =
272 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32);
273 const GLboolean force16bpt =
274 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16);
275 (void)format;
276
277 #if 0
278 fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n",
279 _mesa_lookup_enum_by_nr(internalFormat), internalFormat,
280 _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format));
281 fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt);
282 #endif
283
284 switch (internalFormat) {
285 case 4:
286 case GL_RGBA:
287 case GL_COMPRESSED_RGBA:
288 switch (type) {
289 case GL_UNSIGNED_INT_10_10_10_2:
290 case GL_UNSIGNED_INT_2_10_10_10_REV:
291 return do32bpt ? _dri_texformat_argb8888 :
292 _dri_texformat_argb1555;
293 case GL_UNSIGNED_SHORT_4_4_4_4:
294 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
295 return _dri_texformat_argb4444;
296 case GL_UNSIGNED_SHORT_5_5_5_1:
297 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
298 return _dri_texformat_argb1555;
299 default:
300 return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type) :
301 _dri_texformat_argb4444;
302 }
303
304 case 3:
305 case GL_RGB:
306 case GL_COMPRESSED_RGB:
307 switch (type) {
308 case GL_UNSIGNED_SHORT_4_4_4_4:
309 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
310 return _dri_texformat_argb4444;
311 case GL_UNSIGNED_SHORT_5_5_5_1:
312 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
313 return _dri_texformat_argb1555;
314 case GL_UNSIGNED_SHORT_5_6_5:
315 case GL_UNSIGNED_SHORT_5_6_5_REV:
316 return _dri_texformat_rgb565;
317 default:
318 return do32bpt ? _dri_texformat_argb8888 :
319 _dri_texformat_rgb565;
320 }
321
322 case GL_RGBA8:
323 case GL_RGB10_A2:
324 case GL_RGBA12:
325 case GL_RGBA16:
326 return !force16bpt ?
327 radeonChoose8888TexFormat(rmesa, format,type) :
328 _dri_texformat_argb4444;
329
330 case GL_RGBA4:
331 case GL_RGBA2:
332 return _dri_texformat_argb4444;
333
334 case GL_RGB5_A1:
335 return _dri_texformat_argb1555;
336
337 case GL_RGB8:
338 case GL_RGB10:
339 case GL_RGB12:
340 case GL_RGB16:
341 return !force16bpt ? _dri_texformat_argb8888 :
342 _dri_texformat_rgb565;
343
344 case GL_RGB5:
345 case GL_RGB4:
346 case GL_R3_G3_B2:
347 return _dri_texformat_rgb565;
348
349 case GL_ALPHA:
350 case GL_ALPHA4:
351 case GL_ALPHA8:
352 case GL_ALPHA12:
353 case GL_ALPHA16:
354 case GL_COMPRESSED_ALPHA:
355 return _dri_texformat_a8;
356
357 case 1:
358 case GL_LUMINANCE:
359 case GL_LUMINANCE4:
360 case GL_LUMINANCE8:
361 case GL_LUMINANCE12:
362 case GL_LUMINANCE16:
363 case GL_COMPRESSED_LUMINANCE:
364 return _dri_texformat_l8;
365
366 case 2:
367 case GL_LUMINANCE_ALPHA:
368 case GL_LUMINANCE4_ALPHA4:
369 case GL_LUMINANCE6_ALPHA2:
370 case GL_LUMINANCE8_ALPHA8:
371 case GL_LUMINANCE12_ALPHA4:
372 case GL_LUMINANCE12_ALPHA12:
373 case GL_LUMINANCE16_ALPHA16:
374 case GL_COMPRESSED_LUMINANCE_ALPHA:
375 return _dri_texformat_al88;
376
377 case GL_INTENSITY:
378 case GL_INTENSITY4:
379 case GL_INTENSITY8:
380 case GL_INTENSITY12:
381 case GL_INTENSITY16:
382 case GL_COMPRESSED_INTENSITY:
383 return _dri_texformat_i8;
384
385 case GL_YCBCR_MESA:
386 if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
387 type == GL_UNSIGNED_BYTE)
388 return &_mesa_texformat_ycbcr;
389 else
390 return &_mesa_texformat_ycbcr_rev;
391
392 case GL_RGB_S3TC:
393 case GL_RGB4_S3TC:
394 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
395 return &_mesa_texformat_rgb_dxt1;
396
397 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
398 return &_mesa_texformat_rgba_dxt1;
399
400 case GL_RGBA_S3TC:
401 case GL_RGBA4_S3TC:
402 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
403 return &_mesa_texformat_rgba_dxt3;
404
405 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
406 return &_mesa_texformat_rgba_dxt5;
407
408 case GL_ALPHA16F_ARB:
409 return &_mesa_texformat_alpha_float16;
410 case GL_ALPHA32F_ARB:
411 return &_mesa_texformat_alpha_float32;
412 case GL_LUMINANCE16F_ARB:
413 return &_mesa_texformat_luminance_float16;
414 case GL_LUMINANCE32F_ARB:
415 return &_mesa_texformat_luminance_float32;
416 case GL_LUMINANCE_ALPHA16F_ARB:
417 return &_mesa_texformat_luminance_alpha_float16;
418 case GL_LUMINANCE_ALPHA32F_ARB:
419 return &_mesa_texformat_luminance_alpha_float32;
420 case GL_INTENSITY16F_ARB:
421 return &_mesa_texformat_intensity_float16;
422 case GL_INTENSITY32F_ARB:
423 return &_mesa_texformat_intensity_float32;
424 case GL_RGB16F_ARB:
425 return &_mesa_texformat_rgba_float16;
426 case GL_RGB32F_ARB:
427 return &_mesa_texformat_rgba_float32;
428 case GL_RGBA16F_ARB:
429 return &_mesa_texformat_rgba_float16;
430 case GL_RGBA32F_ARB:
431 return &_mesa_texformat_rgba_float32;
432
433 case GL_DEPTH_COMPONENT:
434 case GL_DEPTH_COMPONENT16:
435 case GL_DEPTH_COMPONENT24:
436 case GL_DEPTH_COMPONENT32:
437 #if 0
438 switch (type) {
439 case GL_UNSIGNED_BYTE:
440 case GL_UNSIGNED_SHORT:
441 return &_mesa_texformat_z16;
442 case GL_UNSIGNED_INT:
443 return &_mesa_texformat_z32;
444 case GL_UNSIGNED_INT_24_8_EXT:
445 default:
446 return &_mesa_texformat_z24_s8;
447 }
448 #else
449 return &_mesa_texformat_z16;
450 #endif
451
452 default:
453 _mesa_problem(ctx,
454 "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
455 (int)internalFormat);
456 return NULL;
457 }
458
459 return NULL; /* never get here */
460 }
461
462 /**
463 * All glTexImage calls go through this function.
464 */
465 static void radeon_teximage(
466 GLcontext *ctx, int dims,
467 GLint face, GLint level,
468 GLint internalFormat,
469 GLint width, GLint height, GLint depth,
470 GLsizei imageSize,
471 GLenum format, GLenum type, const GLvoid * pixels,
472 const struct gl_pixelstore_attrib *packing,
473 struct gl_texture_object *texObj,
474 struct gl_texture_image *texImage,
475 int compressed)
476 {
477 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
478 radeonTexObj* t = radeon_tex_obj(texObj);
479 radeon_texture_image* image = get_radeon_texture_image(texImage);
480 GLuint dstRowStride;
481 GLint postConvWidth = width;
482 GLint postConvHeight = height;
483 GLuint texelBytes;
484
485 radeon_firevertices(rmesa);
486
487 t->validated = GL_FALSE;
488
489 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
490 _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
491 &postConvHeight);
492 }
493
494 /* Choose and fill in the texture format for this image */
495 texImage->TexFormat = radeonChooseTextureFormat(ctx, internalFormat, format, type);
496 _mesa_set_fetch_functions(texImage, dims);
497
498 if (texImage->TexFormat->TexelBytes == 0) {
499 texelBytes = 0;
500 texImage->IsCompressed = GL_TRUE;
501 texImage->CompressedSize =
502 ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
503 texImage->Height, texImage->Depth,
504 texImage->TexFormat->MesaFormat);
505 } else {
506 texImage->IsCompressed = GL_FALSE;
507 texImage->CompressedSize = 0;
508
509 texelBytes = texImage->TexFormat->TexelBytes;
510 /* Minimum pitch of 32 bytes */
511 if (postConvWidth * texelBytes < 32) {
512 postConvWidth = 32 / texelBytes;
513 texImage->RowStride = postConvWidth;
514 }
515 if (!image->mt) {
516 assert(texImage->RowStride == postConvWidth);
517 }
518 }
519
520 /* Allocate memory for image */
521 radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */
522
523 if (t->mt &&
524 t->mt->firstLevel == level &&
525 t->mt->lastLevel == level &&
526 t->mt->target != GL_TEXTURE_CUBE_MAP_ARB &&
527 !radeon_miptree_matches_image(t->mt, texImage, face, level)) {
528 radeon_miptree_unreference(t->mt);
529 t->mt = NULL;
530 }
531
532 if (!t->mt)
533 radeon_try_alloc_miptree(rmesa, t, texImage, face, level);
534 if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) {
535 radeon_mipmap_level *lvl;
536 image->mt = t->mt;
537 image->mtlevel = level - t->mt->firstLevel;
538 image->mtface = face;
539 radeon_miptree_reference(t->mt);
540 lvl = &image->mt->levels[image->mtlevel];
541 dstRowStride = lvl->rowstride;
542 } else {
543 int size;
544 if (texImage->IsCompressed) {
545 size = texImage->CompressedSize;
546 } else {
547 size = texImage->Width * texImage->Height * texImage->Depth * texImage->TexFormat->TexelBytes;
548 }
549 texImage->Data = _mesa_alloc_texmemory(size);
550 }
551
552 /* Upload texture image; note that the spec allows pixels to be NULL */
553 if (compressed) {
554 pixels = _mesa_validate_pbo_compressed_teximage(
555 ctx, imageSize, pixels, packing, "glCompressedTexImage");
556 } else {
557 pixels = _mesa_validate_pbo_teximage(
558 ctx, dims, width, height, depth,
559 format, type, pixels, packing, "glTexImage");
560 }
561
562 if (pixels) {
563 radeon_teximage_map(image, GL_TRUE);
564
565 if (compressed) {
566 memcpy(texImage->Data, pixels, imageSize);
567 } else {
568 GLuint dstRowStride;
569 if (image->mt) {
570 radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
571 dstRowStride = lvl->rowstride;
572 } else {
573 dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
574 }
575
576 if (!texImage->TexFormat->StoreImage(ctx, dims,
577 texImage->_BaseFormat,
578 texImage->TexFormat,
579 texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
580 dstRowStride,
581 texImage->ImageOffsets,
582 width, height, depth,
583 format, type, pixels, packing))
584 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
585 }
586
587 }
588
589 /* SGIS_generate_mipmap */
590 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
591 radeon_generate_mipmap(ctx, texObj->Target, texObj);
592 }
593
594 _mesa_unmap_teximage_pbo(ctx, packing);
595
596 if (pixels)
597 radeon_teximage_unmap(image);
598
599
600 }
601
602 void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level,
603 GLint internalFormat,
604 GLint width, GLint border,
605 GLenum format, GLenum type, const GLvoid * pixels,
606 const struct gl_pixelstore_attrib *packing,
607 struct gl_texture_object *texObj,
608 struct gl_texture_image *texImage)
609 {
610 radeon_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1,
611 0, format, type, pixels, packing, texObj, texImage, 0);
612 }
613
614 void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level,
615 GLint internalFormat,
616 GLint width, GLint height, GLint border,
617 GLenum format, GLenum type, const GLvoid * pixels,
618 const struct gl_pixelstore_attrib *packing,
619 struct gl_texture_object *texObj,
620 struct gl_texture_image *texImage)
621
622 {
623 GLuint face = radeon_face_for_target(target);
624
625 radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
626 0, format, type, pixels, packing, texObj, texImage, 0);
627 }
628
629 void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target,
630 GLint level, GLint internalFormat,
631 GLint width, GLint height, GLint border,
632 GLsizei imageSize, const GLvoid * data,
633 struct gl_texture_object *texObj,
634 struct gl_texture_image *texImage)
635 {
636 GLuint face = radeon_face_for_target(target);
637
638 radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
639 imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1);
640 }
641
642 void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
643 GLint internalFormat,
644 GLint width, GLint height, GLint depth,
645 GLint border,
646 GLenum format, GLenum type, const GLvoid * pixels,
647 const struct gl_pixelstore_attrib *packing,
648 struct gl_texture_object *texObj,
649 struct gl_texture_image *texImage)
650 {
651 radeon_teximage(ctx, 3, 0, level, internalFormat, width, height, depth,
652 0, format, type, pixels, packing, texObj, texImage, 0);
653 }
654
655 /**
656 * Update a subregion of the given texture image.
657 */
658 static void radeon_texsubimage(GLcontext* ctx, int dims, int level,
659 GLint xoffset, GLint yoffset, GLint zoffset,
660 GLsizei width, GLsizei height, GLsizei depth,
661 GLsizei imageSize,
662 GLenum format, GLenum type,
663 const GLvoid * pixels,
664 const struct gl_pixelstore_attrib *packing,
665 struct gl_texture_object *texObj,
666 struct gl_texture_image *texImage,
667 int compressed)
668 {
669 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
670 radeonTexObj* t = radeon_tex_obj(texObj);
671 radeon_texture_image* image = get_radeon_texture_image(texImage);
672
673 radeon_firevertices(rmesa);
674
675 t->validated = GL_FALSE;
676 if (compressed) {
677 pixels = _mesa_validate_pbo_compressed_teximage(
678 ctx, imageSize, pixels, packing, "glCompressedTexImage");
679 } else {
680 pixels = _mesa_validate_pbo_teximage(ctx, dims,
681 width, height, depth, format, type, pixels, packing, "glTexSubImage1D");
682 }
683
684 if (pixels) {
685 GLint dstRowStride;
686 radeon_teximage_map(image, GL_TRUE);
687
688 if (image->mt) {
689 radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
690 dstRowStride = lvl->rowstride;
691 } else {
692 dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
693 }
694
695 if (compressed) {
696 uint32_t srcRowStride, bytesPerRow, rows;
697 dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, texImage->Width);
698 srcRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
699 bytesPerRow = srcRowStride;
700 rows = height / 4;
701
702 copy_rows(texImage->Data, dstRowStride, image->base.Data, srcRowStride, rows,
703 bytesPerRow);
704
705 } else {
706 if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
707 texImage->TexFormat, texImage->Data,
708 xoffset, yoffset, zoffset,
709 dstRowStride,
710 texImage->ImageOffsets,
711 width, height, depth,
712 format, type, pixels, packing))
713 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
714 }
715
716 }
717
718 /* GL_SGIS_generate_mipmap */
719 if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
720 radeon_generate_mipmap(ctx, texObj->Target, texObj);
721 }
722 radeon_teximage_unmap(image);
723
724 _mesa_unmap_teximage_pbo(ctx, packing);
725
726
727 }
728
729 void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
730 GLint xoffset,
731 GLsizei width,
732 GLenum format, GLenum type,
733 const GLvoid * pixels,
734 const struct gl_pixelstore_attrib *packing,
735 struct gl_texture_object *texObj,
736 struct gl_texture_image *texImage)
737 {
738 radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1, 0,
739 format, type, pixels, packing, texObj, texImage, 0);
740 }
741
742 void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
743 GLint xoffset, GLint yoffset,
744 GLsizei width, GLsizei height,
745 GLenum format, GLenum type,
746 const GLvoid * pixels,
747 const struct gl_pixelstore_attrib *packing,
748 struct gl_texture_object *texObj,
749 struct gl_texture_image *texImage)
750 {
751 radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
752 0, format, type, pixels, packing, texObj, texImage,
753 0);
754 }
755
756 void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target,
757 GLint level, GLint xoffset,
758 GLint yoffset, GLsizei width,
759 GLsizei height, GLenum format,
760 GLsizei imageSize, const GLvoid * data,
761 struct gl_texture_object *texObj,
762 struct gl_texture_image *texImage)
763 {
764 radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
765 imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1);
766 }
767
768
769 void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
770 GLint xoffset, GLint yoffset, GLint zoffset,
771 GLsizei width, GLsizei height, GLsizei depth,
772 GLenum format, GLenum type,
773 const GLvoid * pixels,
774 const struct gl_pixelstore_attrib *packing,
775 struct gl_texture_object *texObj,
776 struct gl_texture_image *texImage)
777 {
778 radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth, 0,
779 format, type, pixels, packing, texObj, texImage, 0);
780 }
781
782
783
784 /**
785 * Ensure that the given image is stored in the given miptree from now on.
786 */
787 static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, int face, int level)
788 {
789 radeon_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel];
790 unsigned char *dest;
791
792 assert(image->mt != mt);
793 assert(dstlvl->width == image->base.Width);
794 assert(dstlvl->height == image->base.Height);
795 assert(dstlvl->depth == image->base.Depth);
796
797
798 radeon_bo_map(mt->bo, GL_TRUE);
799 dest = mt->bo->ptr + dstlvl->faces[face].offset;
800
801 if (image->mt) {
802 /* Format etc. should match, so we really just need a memcpy().
803 * In fact, that memcpy() could be done by the hardware in many
804 * cases, provided that we have a proper memory manager.
805 */
806 radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel];
807
808 assert(srclvl->size == dstlvl->size);
809 assert(srclvl->rowstride == dstlvl->rowstride);
810
811 radeon_bo_map(image->mt->bo, GL_FALSE);
812
813 memcpy(dest,
814 image->mt->bo->ptr + srclvl->faces[face].offset,
815 dstlvl->size);
816 radeon_bo_unmap(image->mt->bo);
817
818 radeon_miptree_unreference(image->mt);
819 } else {
820 uint32_t srcrowstride;
821 uint32_t height;
822 /* need to confirm this value is correct */
823 if (mt->compressed) {
824 height = image->base.Height / 4;
825 srcrowstride = image->base.RowStride * mt->bpp;
826 } else {
827 height = image->base.Height * image->base.Depth;
828 srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
829 }
830
831 // if (mt->tilebits)
832 // WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
833
834 copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride,
835 height, srcrowstride);
836
837 _mesa_free_texmemory(image->base.Data);
838 image->base.Data = 0;
839 }
840
841 radeon_bo_unmap(mt->bo);
842
843 image->mt = mt;
844 image->mtface = face;
845 image->mtlevel = level;
846 radeon_miptree_reference(image->mt);
847 }
848
849 int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj)
850 {
851 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
852 radeonTexObj *t = radeon_tex_obj(texObj);
853 radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[0][texObj->BaseLevel]);
854 int face, level;
855
856 if (t->validated || t->image_override)
857 return GL_TRUE;
858
859 if (RADEON_DEBUG & DEBUG_TEXTURE)
860 fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj);
861
862 if (baseimage->base.Border > 0)
863 return GL_FALSE;
864
865 /* Ensure a matching miptree exists.
866 *
867 * Differing mipmap trees can result when the app uses TexImage to
868 * change texture dimensions.
869 *
870 * Prefer to use base image's miptree if it
871 * exists, since that most likely contains more valid data (remember
872 * that the base level is usually significantly larger than the rest
873 * of the miptree, so cubemaps are the only possible exception).
874 */
875 if (baseimage->mt &&
876 baseimage->mt != t->mt &&
877 radeon_miptree_matches_texture(baseimage->mt, &t->base)) {
878 radeon_miptree_unreference(t->mt);
879 t->mt = baseimage->mt;
880 radeon_miptree_reference(t->mt);
881 } else if (t->mt && !radeon_miptree_matches_texture(t->mt, &t->base)) {
882 radeon_miptree_unreference(t->mt);
883 t->mt = 0;
884 }
885
886 if (!t->mt) {
887 if (RADEON_DEBUG & DEBUG_TEXTURE)
888 fprintf(stderr, " Allocate new miptree\n");
889 radeon_try_alloc_miptree(rmesa, t, &baseimage->base, 0, texObj->BaseLevel);
890 if (!t->mt) {
891 _mesa_problem(ctx, "r300_validate_texture failed to alloc miptree");
892 return GL_FALSE;
893 }
894 }
895
896 /* Ensure all images are stored in the single main miptree */
897 for(face = 0; face < t->mt->faces; ++face) {
898 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) {
899 radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]);
900 if (RADEON_DEBUG & DEBUG_TEXTURE)
901 fprintf(stderr, " face %i, level %i... %p vs %p ", face, level, t->mt, image->mt);
902 if (t->mt == image->mt) {
903 if (RADEON_DEBUG & DEBUG_TEXTURE)
904 fprintf(stderr, "OK\n");
905 continue;
906 }
907
908 if (RADEON_DEBUG & DEBUG_TEXTURE)
909 fprintf(stderr, "migrating\n");
910 migrate_image_to_miptree(t->mt, image, face, level);
911 }
912 }
913
914 return GL_TRUE;
915 }
916
917
918 /**
919 * Need to map texture image into memory before copying image data,
920 * then unmap it.
921 */
922 static void
923 radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
924 GLenum format, GLenum type, GLvoid * pixels,
925 struct gl_texture_object *texObj,
926 struct gl_texture_image *texImage, int compressed)
927 {
928 radeon_texture_image *image = get_radeon_texture_image(texImage);
929
930 if (image->mt) {
931 /* Map the texture image read-only */
932 radeon_teximage_map(image, GL_FALSE);
933 } else {
934 /* Image hasn't been uploaded to a miptree yet */
935 assert(image->base.Data);
936 }
937
938 if (compressed) {
939 _mesa_get_compressed_teximage(ctx, target, level, pixels,
940 texObj, texImage);
941 } else {
942 _mesa_get_teximage(ctx, target, level, format, type, pixels,
943 texObj, texImage);
944 }
945
946 if (image->mt) {
947 radeon_teximage_unmap(image);
948 }
949 }
950
951 void
952 radeonGetTexImage(GLcontext * ctx, GLenum target, GLint level,
953 GLenum format, GLenum type, GLvoid * pixels,
954 struct gl_texture_object *texObj,
955 struct gl_texture_image *texImage)
956 {
957 radeon_get_tex_image(ctx, target, level, format, type, pixels,
958 texObj, texImage, 0);
959 }
960
961 void
962 radeonGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
963 GLvoid *pixels,
964 struct gl_texture_object *texObj,
965 struct gl_texture_image *texImage)
966 {
967 radeon_get_tex_image(ctx, target, level, 0, 0, pixels,
968 texObj, texImage, 1);
969 }