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