mesa: move mesa_set_fetch_functions()
[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/texfetch.h"
38 #include "main/texformat.h"
39 #include "main/texstore.h"
40 #include "main/teximage.h"
41 #include "main/texobj.h"
42 #include "main/texgetimage.h"
43
44 #include "xmlpool.h" /* for symbolic values of enum-type options */
45
46 #include "radeon_common.h"
47
48 #include "radeon_mipmap_tree.h"
49
50
51 static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
52 GLuint numrows, GLuint rowsize)
53 {
54 assert(rowsize <= dststride);
55 assert(rowsize <= srcstride);
56
57 if (rowsize == srcstride && rowsize == dststride) {
58 memcpy(dst, src, numrows*rowsize);
59 } else {
60 GLuint i;
61 for(i = 0; i < numrows; ++i) {
62 memcpy(dst, src, rowsize);
63 dst += dststride;
64 src += srcstride;
65 }
66 }
67 }
68
69 /* textures */
70 /**
71 * Allocate an empty texture image object.
72 */
73 struct gl_texture_image *radeonNewTextureImage(GLcontext *ctx)
74 {
75 return CALLOC(sizeof(radeon_texture_image));
76 }
77
78 /**
79 * Free memory associated with this texture image.
80 */
81 void radeonFreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage)
82 {
83 radeon_texture_image* image = get_radeon_texture_image(timage);
84
85 if (image->mt) {
86 radeon_miptree_unreference(image->mt);
87 image->mt = 0;
88 assert(!image->base.Data);
89 } else {
90 _mesa_free_texture_image_data(ctx, timage);
91 }
92 if (image->bo) {
93 radeon_bo_unref(image->bo);
94 image->bo = NULL;
95 }
96 if (timage->Data) {
97 _mesa_free_texmemory(timage->Data);
98 timage->Data = NULL;
99 }
100 }
101
102 /* Set Data pointer and additional data for mapped texture image */
103 static void teximage_set_map_data(radeon_texture_image *image)
104 {
105 radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
106
107 image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset;
108 image->base.RowStride = lvl->rowstride / image->mt->bpp;
109 }
110
111
112 /**
113 * Map a single texture image for glTexImage and friends.
114 */
115 void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable)
116 {
117 if (image->mt) {
118 assert(!image->base.Data);
119
120 radeon_bo_map(image->mt->bo, write_enable);
121 teximage_set_map_data(image);
122 }
123 }
124
125
126 void radeon_teximage_unmap(radeon_texture_image *image)
127 {
128 if (image->mt) {
129 assert(image->base.Data);
130
131 image->base.Data = 0;
132 radeon_bo_unmap(image->mt->bo);
133 }
134 }
135
136 static void map_override(GLcontext *ctx, radeonTexObj *t)
137 {
138 radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
139
140 radeon_bo_map(t->bo, GL_FALSE);
141
142 img->base.Data = t->bo->ptr;
143 _mesa_set_fetch_functions(&img->base, 2);
144 }
145
146 static void unmap_override(GLcontext *ctx, radeonTexObj *t)
147 {
148 radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
149
150 radeon_bo_unmap(t->bo);
151
152 img->base.Data = NULL;
153 }
154
155 /**
156 * Map a validated texture for reading during software rendering.
157 */
158 void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
159 {
160 radeonTexObj* t = radeon_tex_obj(texObj);
161 int face, level;
162
163 if (!radeon_validate_texture_miptree(ctx, texObj))
164 return;
165
166 /* for r100 3D sw fallbacks don't have mt */
167 if (t->image_override && t->bo)
168 map_override(ctx, t);
169
170 if (!t->mt)
171 return;
172
173 radeon_bo_map(t->mt->bo, GL_FALSE);
174 for(face = 0; face < t->mt->faces; ++face) {
175 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level)
176 teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level]));
177 }
178 }
179
180 void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
181 {
182 radeonTexObj* t = radeon_tex_obj(texObj);
183 int face, level;
184
185 if (t->image_override && t->bo)
186 unmap_override(ctx, t);
187 /* for r100 3D sw fallbacks don't have mt */
188 if (!t->mt)
189 return;
190
191 for(face = 0; face < t->mt->faces; ++face) {
192 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level)
193 texObj->Image[face][level]->Data = 0;
194 }
195 radeon_bo_unmap(t->mt->bo);
196 }
197
198 GLuint radeon_face_for_target(GLenum target)
199 {
200 switch (target) {
201 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
202 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
203 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
204 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
205 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
206 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
207 return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
208 default:
209 return 0;
210 }
211 }
212
213 /**
214 * Wraps Mesa's implementation to ensure that the base level image is mapped.
215 *
216 * This relies on internal details of _mesa_generate_mipmap, in particular
217 * the fact that the memory for recreated texture images is always freed.
218 */
219 static void radeon_generate_mipmap(GLcontext *ctx, GLenum target,
220 struct gl_texture_object *texObj)
221 {
222 radeonTexObj* t = radeon_tex_obj(texObj);
223 GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
224 int i, face;
225
226
227 _mesa_generate_mipmap(ctx, target, texObj);
228
229 for (face = 0; face < nr_faces; face++) {
230 for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) {
231 radeon_texture_image *image;
232
233 image = get_radeon_texture_image(texObj->Image[face][i]);
234
235 if (image == NULL)
236 break;
237
238 image->mtlevel = i;
239 image->mtface = face;
240
241 radeon_miptree_unreference(image->mt);
242 image->mt = NULL;
243 }
244 }
245
246 }
247
248 void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj)
249 {
250 GLuint face = radeon_face_for_target(target);
251 radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]);
252
253 radeon_teximage_map(baseimage, GL_FALSE);
254 radeon_generate_mipmap(ctx, target, texObj);
255 radeon_teximage_unmap(baseimage);
256 }
257
258
259 /* try to find a format which will only need a memcopy */
260 static gl_format radeonChoose8888TexFormat(radeonContextPtr rmesa,
261 GLenum srcFormat,
262 GLenum srcType, GLboolean fbo)
263 {
264 const GLuint ui = 1;
265 const GLubyte littleEndian = *((const GLubyte *)&ui);
266
267 /* r100 can only do this */
268 if (IS_R100_CLASS(rmesa->radeonScreen) || fbo)
269 return _dri_texformat_argb8888;
270
271 if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
272 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
273 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
274 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
275 return MESA_FORMAT_RGBA8888;
276 } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
277 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
278 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
279 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
280 return MESA_FORMAT_RGBA8888_REV;
281 } else if (IS_R200_CLASS(rmesa->radeonScreen)) {
282 return _dri_texformat_argb8888;
283 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
284 srcType == GL_UNSIGNED_INT_8_8_8_8)) {
285 return MESA_FORMAT_ARGB8888_REV;
286 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
287 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
288 return MESA_FORMAT_ARGB8888;
289 } else
290 return _dri_texformat_argb8888;
291 }
292
293 gl_format radeonChooseTextureFormat_mesa(GLcontext * ctx,
294 GLint internalFormat,
295 GLenum format,
296 GLenum type)
297 {
298 return radeonChooseTextureFormat(ctx, internalFormat, format,
299 type, 0);
300 }
301
302 gl_format radeonChooseTextureFormat(GLcontext * ctx,
303 GLint internalFormat,
304 GLenum format,
305 GLenum type, GLboolean fbo)
306 {
307 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
308 const GLboolean do32bpt =
309 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32);
310 const GLboolean force16bpt =
311 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16);
312 (void)format;
313
314 #if 0
315 fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n",
316 _mesa_lookup_enum_by_nr(internalFormat), internalFormat,
317 _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format));
318 fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt);
319 #endif
320
321 switch (internalFormat) {
322 case 4:
323 case GL_RGBA:
324 case GL_COMPRESSED_RGBA:
325 switch (type) {
326 case GL_UNSIGNED_INT_10_10_10_2:
327 case GL_UNSIGNED_INT_2_10_10_10_REV:
328 return do32bpt ? _dri_texformat_argb8888 :
329 _dri_texformat_argb1555;
330 case GL_UNSIGNED_SHORT_4_4_4_4:
331 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
332 return _dri_texformat_argb4444;
333 case GL_UNSIGNED_SHORT_5_5_5_1:
334 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
335 return _dri_texformat_argb1555;
336 default:
337 return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type, fbo) :
338 _dri_texformat_argb4444;
339 }
340
341 case 3:
342 case GL_RGB:
343 case GL_COMPRESSED_RGB:
344 switch (type) {
345 case GL_UNSIGNED_SHORT_4_4_4_4:
346 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
347 return _dri_texformat_argb4444;
348 case GL_UNSIGNED_SHORT_5_5_5_1:
349 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
350 return _dri_texformat_argb1555;
351 case GL_UNSIGNED_SHORT_5_6_5:
352 case GL_UNSIGNED_SHORT_5_6_5_REV:
353 return _dri_texformat_rgb565;
354 default:
355 return do32bpt ? _dri_texformat_argb8888 :
356 _dri_texformat_rgb565;
357 }
358
359 case GL_RGBA8:
360 case GL_RGB10_A2:
361 case GL_RGBA12:
362 case GL_RGBA16:
363 return !force16bpt ?
364 radeonChoose8888TexFormat(rmesa, format, type, fbo) :
365 _dri_texformat_argb4444;
366
367 case GL_RGBA4:
368 case GL_RGBA2:
369 return _dri_texformat_argb4444;
370
371 case GL_RGB5_A1:
372 return _dri_texformat_argb1555;
373
374 case GL_RGB8:
375 case GL_RGB10:
376 case GL_RGB12:
377 case GL_RGB16:
378 return !force16bpt ? _dri_texformat_argb8888 :
379 _dri_texformat_rgb565;
380
381 case GL_RGB5:
382 case GL_RGB4:
383 case GL_R3_G3_B2:
384 return _dri_texformat_rgb565;
385
386 case GL_ALPHA:
387 case GL_ALPHA4:
388 case GL_ALPHA8:
389 case GL_ALPHA12:
390 case GL_ALPHA16:
391 case GL_COMPRESSED_ALPHA:
392 /* r200: can't use a8 format since interpreting hw I8 as a8 would result
393 in wrong rgb values (same as alpha value instead of 0). */
394 if (IS_R200_CLASS(rmesa->radeonScreen))
395 return _dri_texformat_al88;
396 else
397 return _dri_texformat_a8;
398 case 1:
399 case GL_LUMINANCE:
400 case GL_LUMINANCE4:
401 case GL_LUMINANCE8:
402 case GL_LUMINANCE12:
403 case GL_LUMINANCE16:
404 case GL_COMPRESSED_LUMINANCE:
405 return _dri_texformat_l8;
406
407 case 2:
408 case GL_LUMINANCE_ALPHA:
409 case GL_LUMINANCE4_ALPHA4:
410 case GL_LUMINANCE6_ALPHA2:
411 case GL_LUMINANCE8_ALPHA8:
412 case GL_LUMINANCE12_ALPHA4:
413 case GL_LUMINANCE12_ALPHA12:
414 case GL_LUMINANCE16_ALPHA16:
415 case GL_COMPRESSED_LUMINANCE_ALPHA:
416 return _dri_texformat_al88;
417
418 case GL_INTENSITY:
419 case GL_INTENSITY4:
420 case GL_INTENSITY8:
421 case GL_INTENSITY12:
422 case GL_INTENSITY16:
423 case GL_COMPRESSED_INTENSITY:
424 return _dri_texformat_i8;
425
426 case GL_YCBCR_MESA:
427 if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
428 type == GL_UNSIGNED_BYTE)
429 return MESA_FORMAT_YCBCR;
430 else
431 return MESA_FORMAT_YCBCR_REV;
432
433 case GL_RGB_S3TC:
434 case GL_RGB4_S3TC:
435 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
436 return MESA_FORMAT_RGB_DXT1;
437
438 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
439 return MESA_FORMAT_RGBA_DXT1;
440
441 case GL_RGBA_S3TC:
442 case GL_RGBA4_S3TC:
443 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
444 return MESA_FORMAT_RGBA_DXT3;
445
446 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
447 return MESA_FORMAT_RGBA_DXT5;
448
449 case GL_ALPHA16F_ARB:
450 return MESA_FORMAT_ALPHA_FLOAT16;
451 case GL_ALPHA32F_ARB:
452 return MESA_FORMAT_ALPHA_FLOAT32;
453 case GL_LUMINANCE16F_ARB:
454 return MESA_FORMAT_LUMINANCE_FLOAT16;
455 case GL_LUMINANCE32F_ARB:
456 return MESA_FORMAT_LUMINANCE_FLOAT32;
457 case GL_LUMINANCE_ALPHA16F_ARB:
458 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16;
459 case GL_LUMINANCE_ALPHA32F_ARB:
460 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32;
461 case GL_INTENSITY16F_ARB:
462 return MESA_FORMAT_INTENSITY_FLOAT16;
463 case GL_INTENSITY32F_ARB:
464 return MESA_FORMAT_INTENSITY_FLOAT32;
465 case GL_RGB16F_ARB:
466 return MESA_FORMAT_RGBA_FLOAT16;
467 case GL_RGB32F_ARB:
468 return MESA_FORMAT_RGBA_FLOAT32;
469 case GL_RGBA16F_ARB:
470 return MESA_FORMAT_RGBA_FLOAT16;
471 case GL_RGBA32F_ARB:
472 return MESA_FORMAT_RGBA_FLOAT32;
473
474 case GL_DEPTH_COMPONENT:
475 case GL_DEPTH_COMPONENT16:
476 case GL_DEPTH_COMPONENT24:
477 case GL_DEPTH_COMPONENT32:
478 case GL_DEPTH_STENCIL_EXT:
479 case GL_DEPTH24_STENCIL8_EXT:
480 return MESA_FORMAT_S8_Z24;
481
482 /* EXT_texture_sRGB */
483 case GL_SRGB:
484 case GL_SRGB8:
485 case GL_SRGB_ALPHA:
486 case GL_SRGB8_ALPHA8:
487 case GL_COMPRESSED_SRGB:
488 case GL_COMPRESSED_SRGB_ALPHA:
489 return MESA_FORMAT_SRGBA8;
490
491 case GL_SLUMINANCE:
492 case GL_SLUMINANCE8:
493 case GL_COMPRESSED_SLUMINANCE:
494 return MESA_FORMAT_SL8;
495
496 case GL_SLUMINANCE_ALPHA:
497 case GL_SLUMINANCE8_ALPHA8:
498 case GL_COMPRESSED_SLUMINANCE_ALPHA:
499 return MESA_FORMAT_SLA8;
500
501 default:
502 _mesa_problem(ctx,
503 "unexpected internalFormat 0x%x in %s",
504 (int)internalFormat, __func__);
505 return MESA_FORMAT_NONE;
506 }
507
508 return MESA_FORMAT_NONE; /* never get here */
509 }
510
511 /**
512 * All glTexImage calls go through this function.
513 */
514 static void radeon_teximage(
515 GLcontext *ctx, int dims,
516 GLenum target, GLint level,
517 GLint internalFormat,
518 GLint width, GLint height, GLint depth,
519 GLsizei imageSize,
520 GLenum format, GLenum type, const GLvoid * pixels,
521 const struct gl_pixelstore_attrib *packing,
522 struct gl_texture_object *texObj,
523 struct gl_texture_image *texImage,
524 int compressed)
525 {
526 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
527 radeonTexObj* t = radeon_tex_obj(texObj);
528 radeon_texture_image* image = get_radeon_texture_image(texImage);
529 GLuint dstRowStride;
530 GLint postConvWidth = width;
531 GLint postConvHeight = height;
532 GLuint texelBytes;
533 GLuint face = radeon_face_for_target(target);
534
535 radeon_firevertices(rmesa);
536
537 t->validated = GL_FALSE;
538
539 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
540 _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
541 &postConvHeight);
542 }
543
544 /* Choose and fill in the texture format for this image */
545 texImage->TexFormat = radeonChooseTextureFormat(ctx, internalFormat, format, type, 0);
546 _mesa_set_fetch_functions(texImage, dims);
547
548 if (_mesa_is_format_compressed(texImage->TexFormat)) {
549 texelBytes = 0;
550 texImage->CompressedSize =
551 ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
552 texImage->Height, texImage->Depth,
553 texImage->TexFormat);
554 } else {
555 texImage->CompressedSize = 0;
556
557 texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
558 /* Minimum pitch of 32 bytes */
559 if (postConvWidth * texelBytes < 32) {
560 postConvWidth = 32 / texelBytes;
561 texImage->RowStride = postConvWidth;
562 }
563 if (!image->mt) {
564 assert(texImage->RowStride == postConvWidth);
565 }
566 }
567
568 /* Allocate memory for image */
569 radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */
570
571 if (t->mt &&
572 t->mt->firstLevel == level &&
573 t->mt->lastLevel == level &&
574 t->mt->target != GL_TEXTURE_CUBE_MAP_ARB &&
575 !radeon_miptree_matches_image(t->mt, texImage, face, level)) {
576 radeon_miptree_unreference(t->mt);
577 t->mt = NULL;
578 }
579
580 if (!t->mt)
581 radeon_try_alloc_miptree(rmesa, t, image, face, level);
582 if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) {
583 radeon_mipmap_level *lvl;
584 image->mt = t->mt;
585 image->mtlevel = level - t->mt->firstLevel;
586 image->mtface = face;
587 radeon_miptree_reference(t->mt);
588 lvl = &image->mt->levels[image->mtlevel];
589 dstRowStride = lvl->rowstride;
590 } else {
591 int size;
592 if (_mesa_is_format_compressed(texImage->TexFormat)) {
593 size = texImage->CompressedSize;
594 } else {
595 size = texImage->Width * texImage->Height * texImage->Depth * _mesa_get_format_bytes(texImage->TexFormat);
596 }
597 texImage->Data = _mesa_alloc_texmemory(size);
598 }
599
600 /* Upload texture image; note that the spec allows pixels to be NULL */
601 if (compressed) {
602 pixels = _mesa_validate_pbo_compressed_teximage(
603 ctx, imageSize, pixels, packing, "glCompressedTexImage");
604 } else {
605 pixels = _mesa_validate_pbo_teximage(
606 ctx, dims, width, height, depth,
607 format, type, pixels, packing, "glTexImage");
608 }
609
610 if (pixels) {
611 radeon_teximage_map(image, GL_TRUE);
612 if (compressed) {
613 if (image->mt) {
614 uint32_t srcRowStride, bytesPerRow, rows;
615 srcRowStride = _mesa_compressed_row_stride(texImage->TexFormat, width);
616 bytesPerRow = srcRowStride;
617 rows = (height + 3) / 4;
618 copy_rows(texImage->Data, image->mt->levels[level].rowstride,
619 pixels, srcRowStride, rows, bytesPerRow);
620 } else {
621 memcpy(texImage->Data, pixels, imageSize);
622 }
623 } else {
624 GLuint dstRowStride;
625 GLuint *dstImageOffsets;
626
627 if (image->mt) {
628 radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
629 dstRowStride = lvl->rowstride;
630 } else {
631 dstRowStride = texImage->Width * _mesa_get_format_bytes(texImage->TexFormat);
632 }
633
634 if (dims == 3) {
635 int i;
636
637 dstImageOffsets = _mesa_malloc(depth * sizeof(GLuint)) ;
638 if (!dstImageOffsets)
639 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
640
641 for (i = 0; i < depth; ++i) {
642 dstImageOffsets[i] = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat) * height * i;
643 }
644 } else {
645 dstImageOffsets = texImage->ImageOffsets;
646 }
647
648 if (!_mesa_texstore(ctx, dims,
649 texImage->_BaseFormat,
650 texImage->TexFormat,
651 texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
652 dstRowStride,
653 dstImageOffsets,
654 width, height, depth,
655 format, type, pixels, packing)) {
656 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
657 }
658
659 if (dims == 3)
660 _mesa_free(dstImageOffsets);
661 }
662 }
663
664 _mesa_unmap_teximage_pbo(ctx, packing);
665
666 if (pixels)
667 radeon_teximage_unmap(image);
668
669
670 }
671
672 void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level,
673 GLint internalFormat,
674 GLint width, GLint border,
675 GLenum format, GLenum type, const GLvoid * pixels,
676 const struct gl_pixelstore_attrib *packing,
677 struct gl_texture_object *texObj,
678 struct gl_texture_image *texImage)
679 {
680 radeon_teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
681 0, format, type, pixels, packing, texObj, texImage, 0);
682 }
683
684 void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level,
685 GLint internalFormat,
686 GLint width, GLint height, GLint border,
687 GLenum format, GLenum type, const GLvoid * pixels,
688 const struct gl_pixelstore_attrib *packing,
689 struct gl_texture_object *texObj,
690 struct gl_texture_image *texImage)
691
692 {
693 radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
694 0, format, type, pixels, packing, texObj, texImage, 0);
695 }
696
697 void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target,
698 GLint level, GLint internalFormat,
699 GLint width, GLint height, GLint border,
700 GLsizei imageSize, const GLvoid * data,
701 struct gl_texture_object *texObj,
702 struct gl_texture_image *texImage)
703 {
704 radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
705 imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1);
706 }
707
708 void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
709 GLint internalFormat,
710 GLint width, GLint height, GLint depth,
711 GLint border,
712 GLenum format, GLenum type, const GLvoid * pixels,
713 const struct gl_pixelstore_attrib *packing,
714 struct gl_texture_object *texObj,
715 struct gl_texture_image *texImage)
716 {
717 radeon_teximage(ctx, 3, target, level, internalFormat, width, height, depth,
718 0, format, type, pixels, packing, texObj, texImage, 0);
719 }
720
721 /**
722 * Update a subregion of the given texture image.
723 */
724 static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int level,
725 GLint xoffset, GLint yoffset, GLint zoffset,
726 GLsizei width, GLsizei height, GLsizei depth,
727 GLsizei imageSize,
728 GLenum format, GLenum type,
729 const GLvoid * pixels,
730 const struct gl_pixelstore_attrib *packing,
731 struct gl_texture_object *texObj,
732 struct gl_texture_image *texImage,
733 int compressed)
734 {
735 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
736 radeonTexObj* t = radeon_tex_obj(texObj);
737 radeon_texture_image* image = get_radeon_texture_image(texImage);
738
739 radeon_firevertices(rmesa);
740
741 t->validated = GL_FALSE;
742 if (compressed) {
743 pixels = _mesa_validate_pbo_compressed_teximage(
744 ctx, imageSize, pixels, packing, "glCompressedTexImage");
745 } else {
746 pixels = _mesa_validate_pbo_teximage(ctx, dims,
747 width, height, depth, format, type, pixels, packing, "glTexSubImage1D");
748 }
749
750 if (pixels) {
751 GLint dstRowStride;
752 radeon_teximage_map(image, GL_TRUE);
753
754 if (image->mt) {
755 radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
756 dstRowStride = lvl->rowstride;
757 } else {
758 dstRowStride = texImage->RowStride * _mesa_get_format_bytes(texImage->TexFormat);
759 }
760
761 if (compressed) {
762 uint32_t srcRowStride, bytesPerRow, rows;
763 GLubyte *img_start;
764 if (!image->mt) {
765 dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat, texImage->Width);
766 img_start = _mesa_compressed_image_address(xoffset, yoffset, 0,
767 texImage->TexFormat,
768 texImage->Width, texImage->Data);
769 }
770 else {
771 uint32_t blocks_x = dstRowStride / (image->mt->bpp * 4);
772 img_start = texImage->Data + image->mt->bpp * 4 * (blocks_x * (yoffset / 4) + xoffset / 4);
773 }
774 srcRowStride = _mesa_compressed_row_stride(texImage->TexFormat, width);
775 bytesPerRow = srcRowStride;
776 rows = (height + 3) / 4;
777
778 copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow);
779
780 }
781 else {
782 if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
783 texImage->TexFormat, texImage->Data,
784 xoffset, yoffset, zoffset,
785 dstRowStride,
786 texImage->ImageOffsets,
787 width, height, depth,
788 format, type, pixels, packing)) {
789 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
790 }
791 }
792 }
793
794 radeon_teximage_unmap(image);
795
796 _mesa_unmap_teximage_pbo(ctx, packing);
797
798
799 }
800
801 void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
802 GLint xoffset,
803 GLsizei width,
804 GLenum format, GLenum type,
805 const GLvoid * pixels,
806 const struct gl_pixelstore_attrib *packing,
807 struct gl_texture_object *texObj,
808 struct gl_texture_image *texImage)
809 {
810 radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0,
811 format, type, pixels, packing, texObj, texImage, 0);
812 }
813
814 void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
815 GLint xoffset, GLint yoffset,
816 GLsizei width, GLsizei height,
817 GLenum format, GLenum type,
818 const GLvoid * pixels,
819 const struct gl_pixelstore_attrib *packing,
820 struct gl_texture_object *texObj,
821 struct gl_texture_image *texImage)
822 {
823 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
824 0, format, type, pixels, packing, texObj, texImage,
825 0);
826 }
827
828 void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target,
829 GLint level, GLint xoffset,
830 GLint yoffset, GLsizei width,
831 GLsizei height, GLenum format,
832 GLsizei imageSize, const GLvoid * data,
833 struct gl_texture_object *texObj,
834 struct gl_texture_image *texImage)
835 {
836 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
837 imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1);
838 }
839
840
841 void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
842 GLint xoffset, GLint yoffset, GLint zoffset,
843 GLsizei width, GLsizei height, GLsizei depth,
844 GLenum format, GLenum type,
845 const GLvoid * pixels,
846 const struct gl_pixelstore_attrib *packing,
847 struct gl_texture_object *texObj,
848 struct gl_texture_image *texImage)
849 {
850 radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0,
851 format, type, pixels, packing, texObj, texImage, 0);
852 }
853
854
855
856 /**
857 * Ensure that the given image is stored in the given miptree from now on.
858 */
859 static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, int face, int level)
860 {
861 radeon_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel];
862 unsigned char *dest;
863
864 assert(image->mt != mt);
865 assert(dstlvl->width == image->base.Width);
866 assert(dstlvl->height == image->base.Height);
867 assert(dstlvl->depth == image->base.Depth);
868
869
870 radeon_bo_map(mt->bo, GL_TRUE);
871 dest = mt->bo->ptr + dstlvl->faces[face].offset;
872
873 if (image->mt) {
874 /* Format etc. should match, so we really just need a memcpy().
875 * In fact, that memcpy() could be done by the hardware in many
876 * cases, provided that we have a proper memory manager.
877 */
878 radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel-image->mt->firstLevel];
879
880 assert(srclvl->size == dstlvl->size);
881 assert(srclvl->rowstride == dstlvl->rowstride);
882
883 radeon_bo_map(image->mt->bo, GL_FALSE);
884
885 memcpy(dest,
886 image->mt->bo->ptr + srclvl->faces[face].offset,
887 dstlvl->size);
888 radeon_bo_unmap(image->mt->bo);
889
890 radeon_miptree_unreference(image->mt);
891 } else {
892 uint32_t srcrowstride;
893 uint32_t height;
894 /* need to confirm this value is correct */
895 if (mt->compressed) {
896 height = (image->base.Height + 3) / 4;
897 srcrowstride = _mesa_compressed_row_stride(image->base.TexFormat, image->base.Width);
898 } else {
899 height = image->base.Height * image->base.Depth;
900 srcrowstride = image->base.Width * _mesa_get_format_bytes(image->base.TexFormat);
901 }
902
903 // if (mt->tilebits)
904 // WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
905
906 copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride,
907 height, srcrowstride);
908
909 _mesa_free_texmemory(image->base.Data);
910 image->base.Data = 0;
911 }
912
913 radeon_bo_unmap(mt->bo);
914
915 image->mt = mt;
916 image->mtface = face;
917 image->mtlevel = level;
918 radeon_miptree_reference(image->mt);
919 }
920
921 int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj)
922 {
923 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
924 radeonTexObj *t = radeon_tex_obj(texObj);
925 radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[0][texObj->BaseLevel]);
926 int face, level;
927
928 if (t->validated || t->image_override)
929 return GL_TRUE;
930
931 if (RADEON_DEBUG & RADEON_TEXTURE)
932 fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj);
933
934 if (baseimage->base.Border > 0)
935 return GL_FALSE;
936
937 /* Ensure a matching miptree exists.
938 *
939 * Differing mipmap trees can result when the app uses TexImage to
940 * change texture dimensions.
941 *
942 * Prefer to use base image's miptree if it
943 * exists, since that most likely contains more valid data (remember
944 * that the base level is usually significantly larger than the rest
945 * of the miptree, so cubemaps are the only possible exception).
946 */
947 if (baseimage->mt &&
948 baseimage->mt != t->mt &&
949 radeon_miptree_matches_texture(baseimage->mt, &t->base)) {
950 radeon_miptree_unreference(t->mt);
951 t->mt = baseimage->mt;
952 radeon_miptree_reference(t->mt);
953 } else if (t->mt && !radeon_miptree_matches_texture(t->mt, &t->base)) {
954 radeon_miptree_unreference(t->mt);
955 t->mt = 0;
956 }
957
958 if (!t->mt) {
959 if (RADEON_DEBUG & RADEON_TEXTURE)
960 fprintf(stderr, " Allocate new miptree\n");
961 radeon_try_alloc_miptree(rmesa, t, baseimage, 0, texObj->BaseLevel);
962 if (!t->mt) {
963 _mesa_problem(ctx, "radeon_validate_texture failed to alloc miptree");
964 return GL_FALSE;
965 }
966 }
967
968 /* Ensure all images are stored in the single main miptree */
969 for(face = 0; face < t->mt->faces; ++face) {
970 for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) {
971 radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]);
972 if (RADEON_DEBUG & RADEON_TEXTURE)
973 fprintf(stderr, " face %i, level %i... %p vs %p ", face, level, t->mt, image->mt);
974 if (t->mt == image->mt) {
975 if (RADEON_DEBUG & RADEON_TEXTURE)
976 fprintf(stderr, "OK\n");
977
978 continue;
979 }
980
981 if (RADEON_DEBUG & RADEON_TEXTURE)
982 fprintf(stderr, "migrating\n");
983 migrate_image_to_miptree(t->mt, image, face, level);
984 }
985 }
986
987 return GL_TRUE;
988 }
989
990
991 /**
992 * Need to map texture image into memory before copying image data,
993 * then unmap it.
994 */
995 static void
996 radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
997 GLenum format, GLenum type, GLvoid * pixels,
998 struct gl_texture_object *texObj,
999 struct gl_texture_image *texImage, int compressed)
1000 {
1001 radeon_texture_image *image = get_radeon_texture_image(texImage);
1002
1003 if (image->mt) {
1004 /* Map the texture image read-only */
1005 radeon_teximage_map(image, GL_FALSE);
1006 } else {
1007 /* Image hasn't been uploaded to a miptree yet */
1008 assert(image->base.Data);
1009 }
1010
1011 if (compressed) {
1012 /* FIXME: this can't work for small textures (mips) which
1013 use different hw stride */
1014 _mesa_get_compressed_teximage(ctx, target, level, pixels,
1015 texObj, texImage);
1016 } else {
1017 _mesa_get_teximage(ctx, target, level, format, type, pixels,
1018 texObj, texImage);
1019 }
1020
1021 if (image->mt) {
1022 radeon_teximage_unmap(image);
1023 }
1024 }
1025
1026 void
1027 radeonGetTexImage(GLcontext * ctx, GLenum target, GLint level,
1028 GLenum format, GLenum type, GLvoid * pixels,
1029 struct gl_texture_object *texObj,
1030 struct gl_texture_image *texImage)
1031 {
1032 radeon_get_tex_image(ctx, target, level, format, type, pixels,
1033 texObj, texImage, 0);
1034 }
1035
1036 void
1037 radeonGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
1038 GLvoid *pixels,
1039 struct gl_texture_object *texObj,
1040 struct gl_texture_image *texImage)
1041 {
1042 radeon_get_tex_image(ctx, target, level, 0, 0, pixels,
1043 texObj, texImage, 1);
1044 }