radeon: fix glCompressedTexSubImage
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_texture.c
1 /*
2 * Copyright (C) 2009 Maciej Cencora.
3 * Copyright (C) 2008 Nicolai Haehnle.
4 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
5 *
6 * The Weather Channel (TM) funded Tungsten Graphics to develop the
7 * initial release of the Radeon 8500 driver under the XFree86 license.
8 * This notice must be preserved.
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining
11 * a copy of this software and associated documentation files (the
12 * "Software"), to deal in the Software without restriction, including
13 * without limitation the rights to use, copy, modify, merge, publish,
14 * distribute, sublicense, and/or sell copies of the Software, and to
15 * permit persons to whom the Software is furnished to do so, subject to
16 * the following conditions:
17 *
18 * The above copyright notice and this permission notice (including the
19 * next paragraph) shall be included in all copies or substantial
20 * portions of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
26 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 *
30 */
31
32 #include "main/glheader.h"
33 #include "main/imports.h"
34 #include "main/context.h"
35 #include "main/convolve.h"
36 #include "main/mipmap.h"
37 #include "main/texcompress.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 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 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;
104
105 if (!image->mt)
106 return;
107
108 lvl = &image->mt->levels[image->mtlevel];
109
110 image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset;
111 image->base.RowStride = lvl->rowstride / _mesa_get_format_bytes(image->base.TexFormat);
112 }
113
114
115 /**
116 * Map a single texture image for glTexImage and friends.
117 */
118 void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable)
119 {
120 if (image->mt) {
121 assert(!image->base.Data);
122
123 radeon_bo_map(image->mt->bo, write_enable);
124 teximage_set_map_data(image);
125 }
126 }
127
128
129 void radeon_teximage_unmap(radeon_texture_image *image)
130 {
131 if (image->mt) {
132 assert(image->base.Data);
133
134 image->base.Data = 0;
135 radeon_bo_unmap(image->mt->bo);
136 }
137 }
138
139 static void map_override(GLcontext *ctx, radeonTexObj *t)
140 {
141 radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
142
143 radeon_bo_map(t->bo, GL_FALSE);
144
145 img->base.Data = t->bo->ptr;
146 }
147
148 static void unmap_override(GLcontext *ctx, radeonTexObj *t)
149 {
150 radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]);
151
152 radeon_bo_unmap(t->bo);
153
154 img->base.Data = NULL;
155 }
156
157 /**
158 * Map a validated texture for reading during software rendering.
159 */
160 void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
161 {
162 radeonTexObj* t = radeon_tex_obj(texObj);
163 int face, level;
164
165 if (!radeon_validate_texture_miptree(ctx, texObj))
166 return;
167
168 /* for r100 3D sw fallbacks don't have mt */
169 if (t->image_override && t->bo)
170 map_override(ctx, t);
171
172 if (!t->mt)
173 return;
174
175 radeon_bo_map(t->mt->bo, GL_FALSE);
176 for(face = 0; face < t->mt->faces; ++face) {
177 for(level = t->minLod; level <= t->maxLod; ++level)
178 teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level]));
179 }
180 }
181
182 void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj)
183 {
184 radeonTexObj* t = radeon_tex_obj(texObj);
185 int face, level;
186
187 if (t->image_override && t->bo)
188 unmap_override(ctx, t);
189 /* for r100 3D sw fallbacks don't have mt */
190 if (!t->mt)
191 return;
192
193 for(face = 0; face < t->mt->faces; ++face) {
194 for(level = t->minLod; level <= t->maxLod; ++level)
195 texObj->Image[face][level]->Data = 0;
196 }
197 radeon_bo_unmap(t->mt->bo);
198 }
199
200 GLuint radeon_face_for_target(GLenum target)
201 {
202 switch (target) {
203 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
204 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
205 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
206 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
207 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
208 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
209 return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
210 default:
211 return 0;
212 }
213 }
214
215 /**
216 * Wraps Mesa's implementation to ensure that the base level image is mapped.
217 *
218 * This relies on internal details of _mesa_generate_mipmap, in particular
219 * the fact that the memory for recreated texture images is always freed.
220 */
221 static void radeon_generate_mipmap(GLcontext *ctx, GLenum target,
222 struct gl_texture_object *texObj)
223 {
224 radeonTexObj* t = radeon_tex_obj(texObj);
225 GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
226 int i, face;
227
228
229 _mesa_generate_mipmap(ctx, target, texObj);
230
231 for (face = 0; face < nr_faces; face++) {
232 for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) {
233 radeon_texture_image *image;
234
235 image = get_radeon_texture_image(texObj->Image[face][i]);
236
237 if (image == NULL)
238 break;
239
240 image->mtlevel = i;
241 image->mtface = face;
242
243 radeon_miptree_unreference(&image->mt);
244 }
245 }
246
247 }
248
249 void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj)
250 {
251 GLuint face = radeon_face_for_target(target);
252 radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[face][texObj->BaseLevel]);
253
254 radeon_teximage_map(baseimage, GL_FALSE);
255 radeon_generate_mipmap(ctx, target, texObj);
256 radeon_teximage_unmap(baseimage);
257 }
258
259
260 /* try to find a format which will only need a memcopy */
261 static gl_format radeonChoose8888TexFormat(radeonContextPtr rmesa,
262 GLenum srcFormat,
263 GLenum srcType, GLboolean fbo)
264 {
265 const GLuint ui = 1;
266 const GLubyte littleEndian = *((const GLubyte *)&ui);
267
268 /* r100 can only do this */
269 if (IS_R100_CLASS(rmesa->radeonScreen) || fbo)
270 return _dri_texformat_argb8888;
271
272 if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
273 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
274 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
275 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
276 return MESA_FORMAT_RGBA8888;
277 } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
278 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
279 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
280 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
281 return MESA_FORMAT_RGBA8888_REV;
282 } else if (IS_R200_CLASS(rmesa->radeonScreen)) {
283 return _dri_texformat_argb8888;
284 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
285 srcType == GL_UNSIGNED_INT_8_8_8_8)) {
286 return MESA_FORMAT_ARGB8888_REV;
287 } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
288 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
289 return MESA_FORMAT_ARGB8888;
290 } else
291 return _dri_texformat_argb8888;
292 }
293
294 gl_format radeonChooseTextureFormat_mesa(GLcontext * ctx,
295 GLint internalFormat,
296 GLenum format,
297 GLenum type)
298 {
299 return radeonChooseTextureFormat(ctx, internalFormat, format,
300 type, 0);
301 }
302
303 gl_format radeonChooseTextureFormat(GLcontext * ctx,
304 GLint internalFormat,
305 GLenum format,
306 GLenum type, GLboolean fbo)
307 {
308 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
309 const GLboolean do32bpt =
310 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32);
311 const GLboolean force16bpt =
312 (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16);
313 (void)format;
314
315 #if 0
316 fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n",
317 _mesa_lookup_enum_by_nr(internalFormat), internalFormat,
318 _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format));
319 fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt);
320 #endif
321
322 switch (internalFormat) {
323 case 4:
324 case GL_RGBA:
325 case GL_COMPRESSED_RGBA:
326 switch (type) {
327 case GL_UNSIGNED_INT_10_10_10_2:
328 case GL_UNSIGNED_INT_2_10_10_10_REV:
329 return do32bpt ? _dri_texformat_argb8888 :
330 _dri_texformat_argb1555;
331 case GL_UNSIGNED_SHORT_4_4_4_4:
332 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
333 return _dri_texformat_argb4444;
334 case GL_UNSIGNED_SHORT_5_5_5_1:
335 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
336 return _dri_texformat_argb1555;
337 default:
338 return do32bpt ? radeonChoose8888TexFormat(rmesa, format, type, fbo) :
339 _dri_texformat_argb4444;
340 }
341
342 case 3:
343 case GL_RGB:
344 case GL_COMPRESSED_RGB:
345 switch (type) {
346 case GL_UNSIGNED_SHORT_4_4_4_4:
347 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
348 return _dri_texformat_argb4444;
349 case GL_UNSIGNED_SHORT_5_5_5_1:
350 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
351 return _dri_texformat_argb1555;
352 case GL_UNSIGNED_SHORT_5_6_5:
353 case GL_UNSIGNED_SHORT_5_6_5_REV:
354 return _dri_texformat_rgb565;
355 default:
356 return do32bpt ? _dri_texformat_argb8888 :
357 _dri_texformat_rgb565;
358 }
359
360 case GL_RGBA8:
361 case GL_RGB10_A2:
362 case GL_RGBA12:
363 case GL_RGBA16:
364 return !force16bpt ?
365 radeonChoose8888TexFormat(rmesa, format, type, fbo) :
366 _dri_texformat_argb4444;
367
368 case GL_RGBA4:
369 case GL_RGBA2:
370 return _dri_texformat_argb4444;
371
372 case GL_RGB5_A1:
373 return _dri_texformat_argb1555;
374
375 case GL_RGB8:
376 case GL_RGB10:
377 case GL_RGB12:
378 case GL_RGB16:
379 return !force16bpt ? _dri_texformat_argb8888 :
380 _dri_texformat_rgb565;
381
382 case GL_RGB5:
383 case GL_RGB4:
384 case GL_R3_G3_B2:
385 return _dri_texformat_rgb565;
386
387 case GL_ALPHA:
388 case GL_ALPHA4:
389 case GL_ALPHA8:
390 case GL_ALPHA12:
391 case GL_ALPHA16:
392 case GL_COMPRESSED_ALPHA:
393 /* r200: can't use a8 format since interpreting hw I8 as a8 would result
394 in wrong rgb values (same as alpha value instead of 0). */
395 if (IS_R200_CLASS(rmesa->radeonScreen))
396 return _dri_texformat_al88;
397 else
398 return _dri_texformat_a8;
399 case 1:
400 case GL_LUMINANCE:
401 case GL_LUMINANCE4:
402 case GL_LUMINANCE8:
403 case GL_LUMINANCE12:
404 case GL_LUMINANCE16:
405 case GL_COMPRESSED_LUMINANCE:
406 return _dri_texformat_l8;
407
408 case 2:
409 case GL_LUMINANCE_ALPHA:
410 case GL_LUMINANCE4_ALPHA4:
411 case GL_LUMINANCE6_ALPHA2:
412 case GL_LUMINANCE8_ALPHA8:
413 case GL_LUMINANCE12_ALPHA4:
414 case GL_LUMINANCE12_ALPHA12:
415 case GL_LUMINANCE16_ALPHA16:
416 case GL_COMPRESSED_LUMINANCE_ALPHA:
417 return _dri_texformat_al88;
418
419 case GL_INTENSITY:
420 case GL_INTENSITY4:
421 case GL_INTENSITY8:
422 case GL_INTENSITY12:
423 case GL_INTENSITY16:
424 case GL_COMPRESSED_INTENSITY:
425 return _dri_texformat_i8;
426
427 case GL_YCBCR_MESA:
428 if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
429 type == GL_UNSIGNED_BYTE)
430 return MESA_FORMAT_YCBCR;
431 else
432 return MESA_FORMAT_YCBCR_REV;
433
434 case GL_RGB_S3TC:
435 case GL_RGB4_S3TC:
436 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
437 return MESA_FORMAT_RGB_DXT1;
438
439 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
440 return MESA_FORMAT_RGBA_DXT1;
441
442 case GL_RGBA_S3TC:
443 case GL_RGBA4_S3TC:
444 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
445 return MESA_FORMAT_RGBA_DXT3;
446
447 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
448 return MESA_FORMAT_RGBA_DXT5;
449
450 case GL_ALPHA16F_ARB:
451 return MESA_FORMAT_ALPHA_FLOAT16;
452 case GL_ALPHA32F_ARB:
453 return MESA_FORMAT_ALPHA_FLOAT32;
454 case GL_LUMINANCE16F_ARB:
455 return MESA_FORMAT_LUMINANCE_FLOAT16;
456 case GL_LUMINANCE32F_ARB:
457 return MESA_FORMAT_LUMINANCE_FLOAT32;
458 case GL_LUMINANCE_ALPHA16F_ARB:
459 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16;
460 case GL_LUMINANCE_ALPHA32F_ARB:
461 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32;
462 case GL_INTENSITY16F_ARB:
463 return MESA_FORMAT_INTENSITY_FLOAT16;
464 case GL_INTENSITY32F_ARB:
465 return MESA_FORMAT_INTENSITY_FLOAT32;
466 case GL_RGB16F_ARB:
467 return MESA_FORMAT_RGBA_FLOAT16;
468 case GL_RGB32F_ARB:
469 return MESA_FORMAT_RGBA_FLOAT32;
470 case GL_RGBA16F_ARB:
471 return MESA_FORMAT_RGBA_FLOAT16;
472 case GL_RGBA32F_ARB:
473 return MESA_FORMAT_RGBA_FLOAT32;
474
475 case GL_DEPTH_COMPONENT:
476 case GL_DEPTH_COMPONENT16:
477 case GL_DEPTH_COMPONENT24:
478 case GL_DEPTH_COMPONENT32:
479 case GL_DEPTH_STENCIL_EXT:
480 case GL_DEPTH24_STENCIL8_EXT:
481 return MESA_FORMAT_S8_Z24;
482
483 /* EXT_texture_sRGB */
484 case GL_SRGB:
485 case GL_SRGB8:
486 case GL_SRGB_ALPHA:
487 case GL_SRGB8_ALPHA8:
488 case GL_COMPRESSED_SRGB:
489 case GL_COMPRESSED_SRGB_ALPHA:
490 return MESA_FORMAT_SRGBA8;
491
492 case GL_SLUMINANCE:
493 case GL_SLUMINANCE8:
494 case GL_COMPRESSED_SLUMINANCE:
495 return MESA_FORMAT_SL8;
496
497 case GL_SLUMINANCE_ALPHA:
498 case GL_SLUMINANCE8_ALPHA8:
499 case GL_COMPRESSED_SLUMINANCE_ALPHA:
500 return MESA_FORMAT_SLA8;
501
502 default:
503 _mesa_problem(ctx,
504 "unexpected internalFormat 0x%x in %s",
505 (int)internalFormat, __func__);
506 return MESA_FORMAT_NONE;
507 }
508
509 return MESA_FORMAT_NONE; /* never get here */
510 }
511
512 static void teximage_assign_miptree(radeonContextPtr rmesa,
513 struct gl_texture_object *texObj,
514 struct gl_texture_image *texImage,
515 unsigned face,
516 unsigned level)
517 {
518 radeonTexObj *t = radeon_tex_obj(texObj);
519 radeon_texture_image* image = get_radeon_texture_image(texImage);
520
521 /* Try using current miptree, or create new if there isn't any */
522 if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face,
523 radeon_gl_level_to_miptree_level(texObj, level))) {
524 radeon_miptree_unreference(&t->mt);
525 radeon_try_alloc_miptree(rmesa, t);
526 }
527
528 /* Miptree alocation may have failed,
529 * when there was no image for baselevel specified */
530 if (t->mt) {
531 image->mtface = face;
532 image->mtlevel = radeon_gl_level_to_miptree_level(texObj, level);
533 radeon_miptree_reference(t->mt, &image->mt);
534 }
535 }
536
537 static GLuint * allocate_image_offsets(GLcontext *ctx,
538 unsigned alignedWidth,
539 unsigned height,
540 unsigned depth)
541 {
542 int i;
543 GLuint *offsets;
544
545 offsets = _mesa_malloc(depth * sizeof(GLuint)) ;
546 if (!offsets) {
547 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex[Sub]Image");
548 return NULL;
549 }
550
551 for (i = 0; i < depth; ++i) {
552 offsets[i] = alignedWidth * height * i;
553 }
554
555 return offsets;
556 }
557
558 /**
559 * Update a subregion of the given texture image.
560 */
561 static void radeon_store_teximage(GLcontext* ctx, int dims,
562 GLint xoffset, GLint yoffset, GLint zoffset,
563 GLsizei width, GLsizei height, GLsizei depth,
564 GLsizei imageSize,
565 GLenum format, GLenum type,
566 const GLvoid * pixels,
567 const struct gl_pixelstore_attrib *packing,
568 struct gl_texture_object *texObj,
569 struct gl_texture_image *texImage,
570 int compressed)
571 {
572 radeonTexObj *t = radeon_tex_obj(texObj);
573 radeon_texture_image* image = get_radeon_texture_image(texImage);
574
575 GLuint dstRowStride;
576 GLuint *dstImageOffsets;
577
578 if (image->mt) {
579 dstRowStride = image->mt->levels[image->mtlevel].rowstride;
580 } else if (t->bo) {
581 /* TFP case */
582 /* TODO */
583 assert(0);
584 } else {
585 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
586 }
587
588 if (dims == 3) {
589 unsigned alignedWidth = dstRowStride/_mesa_get_format_bytes(texImage->TexFormat);
590 dstImageOffsets = allocate_image_offsets(ctx, alignedWidth, texImage->Height, texImage->Depth);
591 if (!dstImageOffsets) {
592 return;
593 }
594 } else {
595 dstImageOffsets = texImage->ImageOffsets;
596 }
597
598 radeon_teximage_map(image, GL_TRUE);
599
600 if (compressed) {
601 uint32_t srcRowStride, bytesPerRow, rows, block_width, block_height;
602 GLubyte *img_start;
603
604 _mesa_get_format_block_size(texImage->TexFormat, &block_width, &block_height);
605
606 if (!image->mt) {
607 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width);
608 img_start = _mesa_compressed_image_address(xoffset, yoffset, 0,
609 texImage->TexFormat,
610 texImage->Width, texImage->Data);
611 }
612 else {
613 uint32_t offset;
614 offset = dstRowStride / _mesa_get_format_bytes(texImage->TexFormat) * yoffset / block_height + xoffset / block_width;
615 offset *= _mesa_get_format_bytes(texImage->TexFormat);
616 img_start = texImage->Data + offset;
617 }
618 srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
619 bytesPerRow = srcRowStride;
620 rows = (height + block_height - 1) / block_height;
621
622 copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow);
623 }
624 else {
625 if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat,
626 texImage->TexFormat, texImage->Data,
627 xoffset, yoffset, zoffset,
628 dstRowStride,
629 dstImageOffsets,
630 width, height, depth,
631 format, type, pixels, packing)) {
632 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
633 }
634 }
635
636 if (dims == 3) {
637 _mesa_free(dstImageOffsets);
638 }
639
640 radeon_teximage_unmap(image);
641 }
642
643 /**
644 * All glTexImage calls go through this function.
645 */
646 static void radeon_teximage(
647 GLcontext *ctx, int dims,
648 GLenum target, GLint level,
649 GLint internalFormat,
650 GLint width, GLint height, GLint depth,
651 GLsizei imageSize,
652 GLenum format, GLenum type, const GLvoid * pixels,
653 const struct gl_pixelstore_attrib *packing,
654 struct gl_texture_object *texObj,
655 struct gl_texture_image *texImage,
656 int compressed)
657 {
658 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
659 radeonTexObj* t = radeon_tex_obj(texObj);
660 radeon_texture_image* image = get_radeon_texture_image(texImage);
661 GLint postConvWidth = width;
662 GLint postConvHeight = height;
663 GLuint face = radeon_face_for_target(target);
664
665 {
666 struct radeon_bo *bo;
667 bo = !image->mt ? image->bo : image->mt->bo;
668 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
669 radeon_firevertices(rmesa);
670 }
671 }
672
673 t->validated = GL_FALSE;
674
675 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
676 _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
677 &postConvHeight);
678 }
679
680 if (!_mesa_is_format_compressed(texImage->TexFormat)) {
681 GLuint texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
682 /* Minimum pitch of 32 bytes */
683 if (postConvWidth * texelBytes < 32) {
684 postConvWidth = 32 / texelBytes;
685 texImage->RowStride = postConvWidth;
686 }
687 if (!image->mt) {
688 assert(texImage->RowStride == postConvWidth);
689 }
690 }
691
692 /* Mesa core only clears texImage->Data but not image->mt */
693 radeonFreeTexImageData(ctx, texImage);
694
695 if (!t->bo) {
696 teximage_assign_miptree(rmesa, texObj, texImage, face, level);
697 if (!t->mt) {
698 int size = _mesa_format_image_size(texImage->TexFormat,
699 texImage->Width,
700 texImage->Height,
701 texImage->Depth);
702 texImage->Data = _mesa_alloc_texmemory(size);
703 }
704 }
705
706 /* Upload texture image; note that the spec allows pixels to be NULL */
707 if (compressed) {
708 pixels = _mesa_validate_pbo_compressed_teximage(
709 ctx, imageSize, pixels, packing, "glCompressedTexImage");
710 } else {
711 pixels = _mesa_validate_pbo_teximage(
712 ctx, dims, width, height, depth,
713 format, type, pixels, packing, "glTexImage");
714 }
715
716 if (pixels) {
717 radeon_store_teximage(ctx, dims,
718 0, 0, 0,
719 width, height, depth,
720 imageSize, format, type,
721 pixels, packing,
722 texObj, texImage,
723 compressed);
724 }
725
726 _mesa_unmap_teximage_pbo(ctx, packing);
727 }
728
729 void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level,
730 GLint internalFormat,
731 GLint width, GLint border,
732 GLenum format, GLenum type, const GLvoid * pixels,
733 const struct gl_pixelstore_attrib *packing,
734 struct gl_texture_object *texObj,
735 struct gl_texture_image *texImage)
736 {
737 radeon_teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
738 0, format, type, pixels, packing, texObj, texImage, 0);
739 }
740
741 void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level,
742 GLint internalFormat,
743 GLint width, GLint height, GLint border,
744 GLenum format, GLenum type, const GLvoid * pixels,
745 const struct gl_pixelstore_attrib *packing,
746 struct gl_texture_object *texObj,
747 struct gl_texture_image *texImage)
748
749 {
750 radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
751 0, format, type, pixels, packing, texObj, texImage, 0);
752 }
753
754 void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target,
755 GLint level, GLint internalFormat,
756 GLint width, GLint height, GLint border,
757 GLsizei imageSize, const GLvoid * data,
758 struct gl_texture_object *texObj,
759 struct gl_texture_image *texImage)
760 {
761 radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1,
762 imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1);
763 }
764
765 void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
766 GLint internalFormat,
767 GLint width, GLint height, GLint depth,
768 GLint border,
769 GLenum format, GLenum type, const GLvoid * pixels,
770 const struct gl_pixelstore_attrib *packing,
771 struct gl_texture_object *texObj,
772 struct gl_texture_image *texImage)
773 {
774 radeon_teximage(ctx, 3, target, level, internalFormat, width, height, depth,
775 0, format, type, pixels, packing, texObj, texImage, 0);
776 }
777
778 /**
779 * All glTexSubImage calls go through this function.
780 */
781 static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int level,
782 GLint xoffset, GLint yoffset, GLint zoffset,
783 GLsizei width, GLsizei height, GLsizei depth,
784 GLsizei imageSize,
785 GLenum format, GLenum type,
786 const GLvoid * pixels,
787 const struct gl_pixelstore_attrib *packing,
788 struct gl_texture_object *texObj,
789 struct gl_texture_image *texImage,
790 int compressed)
791 {
792 radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
793 radeonTexObj* t = radeon_tex_obj(texObj);
794 radeon_texture_image* image = get_radeon_texture_image(texImage);
795
796 {
797 struct radeon_bo *bo;
798 bo = !image->mt ? image->bo : image->mt->bo;
799 if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) {
800 radeon_firevertices(rmesa);
801 }
802 }
803
804 t->validated = GL_FALSE;
805 if (compressed) {
806 pixels = _mesa_validate_pbo_compressed_teximage(
807 ctx, imageSize, pixels, packing, "glCompressedTexSubImage");
808 } else {
809 pixels = _mesa_validate_pbo_teximage(ctx, dims,
810 width, height, depth, format, type, pixels, packing, "glTexSubImage");
811 }
812
813 if (pixels) {
814 radeon_store_teximage(ctx, dims,
815 xoffset, yoffset, zoffset,
816 width, height, depth,
817 imageSize, format, type,
818 pixels, packing,
819 texObj, texImage,
820 compressed);
821 }
822
823 _mesa_unmap_teximage_pbo(ctx, packing);
824 }
825
826 void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
827 GLint xoffset,
828 GLsizei width,
829 GLenum format, GLenum type,
830 const GLvoid * pixels,
831 const struct gl_pixelstore_attrib *packing,
832 struct gl_texture_object *texObj,
833 struct gl_texture_image *texImage)
834 {
835 radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0,
836 format, type, pixels, packing, texObj, texImage, 0);
837 }
838
839 void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
840 GLint xoffset, GLint yoffset,
841 GLsizei width, GLsizei height,
842 GLenum format, GLenum type,
843 const GLvoid * pixels,
844 const struct gl_pixelstore_attrib *packing,
845 struct gl_texture_object *texObj,
846 struct gl_texture_image *texImage)
847 {
848 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
849 0, format, type, pixels, packing, texObj, texImage,
850 0);
851 }
852
853 void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target,
854 GLint level, GLint xoffset,
855 GLint yoffset, GLsizei width,
856 GLsizei height, GLenum format,
857 GLsizei imageSize, const GLvoid * data,
858 struct gl_texture_object *texObj,
859 struct gl_texture_image *texImage)
860 {
861 radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1,
862 imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1);
863 }
864
865
866 void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
867 GLint xoffset, GLint yoffset, GLint zoffset,
868 GLsizei width, GLsizei height, GLsizei depth,
869 GLenum format, GLenum type,
870 const GLvoid * pixels,
871 const struct gl_pixelstore_attrib *packing,
872 struct gl_texture_object *texObj,
873 struct gl_texture_image *texImage)
874 {
875 radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0,
876 format, type, pixels, packing, texObj, texImage, 0);
877 }
878
879 /**
880 * Need to map texture image into memory before copying image data,
881 * then unmap it.
882 */
883 static void
884 radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
885 GLenum format, GLenum type, GLvoid * pixels,
886 struct gl_texture_object *texObj,
887 struct gl_texture_image *texImage, int compressed)
888 {
889 radeon_texture_image *image = get_radeon_texture_image(texImage);
890
891 if (image->mt) {
892 /* Map the texture image read-only */
893 radeon_teximage_map(image, GL_FALSE);
894 } else {
895 /* Image hasn't been uploaded to a miptree yet */
896 assert(image->base.Data);
897 }
898
899 if (compressed) {
900 /* FIXME: this can't work for small textures (mips) which
901 use different hw stride */
902 _mesa_get_compressed_teximage(ctx, target, level, pixels,
903 texObj, texImage);
904 } else {
905 _mesa_get_teximage(ctx, target, level, format, type, pixels,
906 texObj, texImage);
907 }
908
909 if (image->mt) {
910 radeon_teximage_unmap(image);
911 }
912 }
913
914 void
915 radeonGetTexImage(GLcontext * ctx, GLenum target, GLint level,
916 GLenum format, GLenum type, GLvoid * pixels,
917 struct gl_texture_object *texObj,
918 struct gl_texture_image *texImage)
919 {
920 radeon_get_tex_image(ctx, target, level, format, type, pixels,
921 texObj, texImage, 0);
922 }
923
924 void
925 radeonGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
926 GLvoid *pixels,
927 struct gl_texture_object *texObj,
928 struct gl_texture_image *texImage)
929 {
930 radeon_get_tex_image(ctx, target, level, 0, 0, pixels,
931 texObj, texImage, 1);
932 }