2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
29 #include "main/glheader.h"
30 #include "main/macros.h"
31 #include "main/mtypes.h"
32 #include "main/enums.h"
33 #include "main/formats.h"
34 #include "main/context.h"
35 #include "main/mipmap.h"
38 #include "main/simple_list.h"
39 #include "main/texobj.h"
40 #include "main/texstore.h"
42 #include "via_context.h"
45 #include "via_ioctl.h"
46 #include "via_3d_reg.h"
49 viaChooseTexFormat( struct gl_context *ctx, GLint internalFormat,
50 GLenum format, GLenum type )
52 struct via_context *vmesa = VIA_CONTEXT(ctx);
53 const GLboolean do32bpt = ( vmesa->viaScreen->bitsPerPixel == 32
54 /* && vmesa->viaScreen->textureSize > 4*1024*1024 */
58 switch ( internalFormat ) {
61 case GL_COMPRESSED_RGBA:
62 if ( format == GL_BGRA ) {
63 if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ||
64 type == GL_UNSIGNED_BYTE ) {
65 return MESA_FORMAT_ARGB8888;
67 else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
68 return MESA_FORMAT_ARGB4444;
70 else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
71 return MESA_FORMAT_ARGB1555;
74 else if ( type == GL_UNSIGNED_BYTE ||
75 type == GL_UNSIGNED_INT_8_8_8_8_REV ||
76 type == GL_UNSIGNED_INT_8_8_8_8 ) {
77 return MESA_FORMAT_ARGB8888;
79 return do32bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB4444;
83 case GL_COMPRESSED_RGB:
84 if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
85 return MESA_FORMAT_RGB565;
87 else if ( type == GL_UNSIGNED_BYTE ) {
88 return MESA_FORMAT_ARGB8888;
90 return do32bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_RGB565;
96 return MESA_FORMAT_ARGB8888;
100 return MESA_FORMAT_ARGB4444;
103 return MESA_FORMAT_ARGB1555;
109 return MESA_FORMAT_ARGB8888;
114 return MESA_FORMAT_RGB565;
121 case GL_COMPRESSED_ALPHA:
122 return MESA_FORMAT_A8;
130 case GL_COMPRESSED_LUMINANCE:
131 return MESA_FORMAT_L8;
134 case GL_LUMINANCE_ALPHA:
135 case GL_LUMINANCE4_ALPHA4:
136 case GL_LUMINANCE6_ALPHA2:
137 case GL_LUMINANCE8_ALPHA8:
138 case GL_LUMINANCE12_ALPHA4:
139 case GL_LUMINANCE12_ALPHA12:
140 case GL_LUMINANCE16_ALPHA16:
141 case GL_COMPRESSED_LUMINANCE_ALPHA:
142 return MESA_FORMAT_AL88;
149 case GL_COMPRESSED_INTENSITY:
150 return MESA_FORMAT_I8;
153 if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
154 type == GL_UNSIGNED_BYTE)
155 return MESA_FORMAT_YCBCR;
157 return MESA_FORMAT_YCBCR_REV;
159 case GL_COMPRESSED_RGB_FXT1_3DFX:
160 return MESA_FORMAT_RGB_FXT1;
161 case GL_COMPRESSED_RGBA_FXT1_3DFX:
162 return MESA_FORMAT_RGBA_FXT1;
166 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
167 return MESA_FORMAT_RGB_DXT1;
169 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
170 return MESA_FORMAT_RGBA_DXT1;
174 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
175 return MESA_FORMAT_RGBA_DXT3;
177 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
178 return MESA_FORMAT_RGBA_DXT5;
181 case GL_COLOR_INDEX1_EXT:
182 case GL_COLOR_INDEX2_EXT:
183 case GL_COLOR_INDEX4_EXT:
184 case GL_COLOR_INDEX8_EXT:
185 case GL_COLOR_INDEX12_EXT:
186 case GL_COLOR_INDEX16_EXT:
187 return MESA_FORMAT_CI8;
190 fprintf(stderr, "unexpected texture format %s in %s\n",
191 _mesa_lookup_enum_by_nr(internalFormat),
193 return MESA_FORMAT_NONE;
196 return MESA_FORMAT_NONE; /* never get here */
200 static const char *get_memtype_name( GLint memType )
202 static const char *names[] = {
210 return names[memType];
214 static GLboolean viaMoveTexBuffers( struct via_context *vmesa,
215 struct via_tex_buffer **buffers,
219 struct via_tex_buffer *newTexBuf[VIA_MAX_TEXLEVELS];
222 if (VIA_DEBUG & DEBUG_TEXTURE)
223 fprintf(stderr, "%s to %s\n",
225 get_memtype_name(newMemType));
227 memset(newTexBuf, 0, sizeof(newTexBuf));
229 /* First do all the allocations (or fail):
231 for (i = 0; i < nr; i++) {
232 if (buffers[i]->memType != newMemType) {
234 /* Don't allow uploads in a thrash state. Should try and
235 * catch this earlier.
237 if (vmesa->thrashing && newMemType != VIA_MEM_SYSTEM)
240 newTexBuf[i] = via_alloc_texture(vmesa,
249 /* Now copy all the image data and free the old texture memory.
251 for (i = 0; i < nr; i++) {
253 memcpy(newTexBuf[i]->bufAddr,
257 newTexBuf[i]->image = buffers[i]->image;
258 newTexBuf[i]->image->texMem = newTexBuf[i];
259 newTexBuf[i]->image->image.Data = newTexBuf[i]->bufAddr;
260 via_free_texture(vmesa, buffers[i]);
264 if (VIA_DEBUG & DEBUG_TEXTURE)
265 fprintf(stderr, "%s - success\n", __FUNCTION__);
270 /* Release any allocations made prior to failure:
272 if (VIA_DEBUG & DEBUG_TEXTURE)
273 fprintf(stderr, "%s - failed\n", __FUNCTION__);
275 for (i = 0; i < nr; i++) {
277 via_free_texture(vmesa, newTexBuf[i]);
285 static GLboolean viaMoveTexObject( struct via_context *vmesa,
286 struct via_texture_object *viaObj,
289 struct via_texture_image **viaImage =
290 (struct via_texture_image **)&viaObj->obj.Image[0][0];
291 struct via_tex_buffer *buffers[VIA_MAX_TEXLEVELS];
294 for (i = viaObj->firstLevel; i <= viaObj->lastLevel; i++)
295 buffers[nr++] = viaImage[i]->texMem;
297 if (viaMoveTexBuffers( vmesa, &buffers[0], nr, newMemType )) {
298 viaObj->memType = newMemType;
307 static GLboolean viaSwapInTexObject( struct via_context *vmesa,
308 struct via_texture_object *viaObj )
310 const struct via_texture_image *baseImage =
311 (struct via_texture_image *)viaObj->obj.Image[0][viaObj->obj.BaseLevel];
313 if (VIA_DEBUG & DEBUG_TEXTURE)
314 fprintf(stderr, "%s\n", __FUNCTION__);
316 if (baseImage->texMem->memType != VIA_MEM_SYSTEM)
317 return viaMoveTexObject( vmesa, viaObj, baseImage->texMem->memType );
319 return (viaMoveTexObject( vmesa, viaObj, VIA_MEM_AGP ) ||
320 viaMoveTexObject( vmesa, viaObj, VIA_MEM_VIDEO ));
324 /* This seems crude, but it asks a fairly pertinent question and gives
325 * an accurate answer:
327 static GLboolean viaIsTexMemLow( struct via_context *vmesa,
330 struct via_tex_buffer *buf = via_alloc_texture(vmesa, 512 * 1024, heap );
334 via_free_texture(vmesa, buf);
339 /* Speculatively move texture images which haven't been used in a
340 * while back to system memory.
342 * TODO: only do this when texture memory is low.
346 * TODO: keep the fb/agp version hanging around and use the local
347 * version as backing store, so re-upload might be avoided.
349 * TODO: do this properly in the kernel...
351 GLboolean viaSwapOutWork( struct via_context *vmesa )
353 struct via_tex_buffer *s, *tmp;
357 if (VIA_DEBUG & DEBUG_TEXTURE)
358 fprintf(stderr, "%s VID %d AGP %d SYS %d\n", __FUNCTION__,
359 vmesa->total_alloc[VIA_MEM_VIDEO],
360 vmesa->total_alloc[VIA_MEM_AGP],
361 vmesa->total_alloc[VIA_MEM_SYSTEM]);
364 for (heap = VIA_MEM_VIDEO; heap <= VIA_MEM_AGP; heap++) {
365 GLuint nr = 0, sz = 0;
367 if (vmesa->thrashing) {
368 if (VIA_DEBUG & DEBUG_TEXTURE)
369 fprintf(stderr, "Heap %d: trash flag\n", heap);
370 target = 1*1024*1024;
372 else if (viaIsTexMemLow(vmesa, heap)) {
373 if (VIA_DEBUG & DEBUG_TEXTURE)
374 fprintf(stderr, "Heap %d: low memory\n", heap);
378 if (VIA_DEBUG & DEBUG_TEXTURE)
379 fprintf(stderr, "Heap %d: nothing to do\n", heap);
383 foreach_s( s, tmp, &vmesa->tex_image_list[heap] ) {
384 if (s->lastUsed < vmesa->lastSwap[1]) {
385 struct via_texture_object *viaObj =
386 (struct via_texture_object *) s->image->image.TexObject;
388 if (VIA_DEBUG & DEBUG_TEXTURE)
390 "back copy tex sz %d, lastUsed %d lastSwap %d\n",
391 s->size, s->lastUsed, vmesa->lastSwap[1]);
393 if (viaMoveTexBuffers( vmesa, &s, 1, VIA_MEM_SYSTEM )) {
394 viaObj->memType = VIA_MEM_MIXED;
398 if (VIA_DEBUG & DEBUG_TEXTURE)
399 fprintf(stderr, "Failed to back copy texture!\n");
409 vmesa->thrashing = GL_FALSE; /* might not get set otherwise? */
414 assert(sz == vmesa->total_alloc[heap]);
416 if (VIA_DEBUG & DEBUG_TEXTURE)
417 fprintf(stderr, "Heap %d: nr %d tot sz %d\n", heap, nr, sz);
426 /* Basically, just collect the image dimensions and addresses for each
427 * image and update the texture object state accordingly.
429 static GLboolean viaSetTexImages(struct gl_context *ctx,
430 struct gl_texture_object *texObj)
432 struct via_context *vmesa = VIA_CONTEXT(ctx);
433 struct via_texture_object *viaObj = (struct via_texture_object *)texObj;
434 const struct via_texture_image *baseImage =
435 (struct via_texture_image *)texObj->Image[0][texObj->BaseLevel];
436 GLint firstLevel, lastLevel, numLevels;
439 GLint i, j = 0, k = 0, l = 0, m = 0;
443 GLuint heightExp = 0;
445 switch (baseImage->image.TexFormat) {
446 case MESA_FORMAT_ARGB8888:
447 texFormat = HC_HTXnFM_ARGB8888;
449 case MESA_FORMAT_ARGB4444:
450 texFormat = HC_HTXnFM_ARGB4444;
452 case MESA_FORMAT_RGB565:
453 texFormat = HC_HTXnFM_RGB565;
455 case MESA_FORMAT_ARGB1555:
456 texFormat = HC_HTXnFM_ARGB1555;
458 case MESA_FORMAT_RGB888:
459 texFormat = HC_HTXnFM_ARGB0888;
462 texFormat = HC_HTXnFM_L8;
465 texFormat = HC_HTXnFM_T8;
467 case MESA_FORMAT_CI8:
468 texFormat = HC_HTXnFM_Index8;
470 case MESA_FORMAT_AL88:
471 texFormat = HC_HTXnFM_AL88;
474 texFormat = HC_HTXnFM_A8;
477 _mesa_problem(vmesa->glCtx, "Bad texture format in viaSetTexImages");
481 /* Compute which mipmap levels we really want to send to the hardware.
482 * This depends on the base image size, GL_TEXTURE_MIN_LOD,
483 * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
484 * Yes, this looks overly complicated, but it's all needed.
486 if (texObj->Sampler.MinFilter == GL_LINEAR || texObj->Sampler.MinFilter == GL_NEAREST) {
487 firstLevel = lastLevel = texObj->BaseLevel;
490 firstLevel = texObj->BaseLevel + (GLint)(texObj->Sampler.MinLod + 0.5);
491 firstLevel = MAX2(firstLevel, texObj->BaseLevel);
492 lastLevel = texObj->BaseLevel + (GLint)(texObj->Sampler.MaxLod + 0.5);
493 lastLevel = MAX2(lastLevel, texObj->BaseLevel);
494 lastLevel = MIN2(lastLevel, texObj->BaseLevel + baseImage->image.MaxLog2);
495 lastLevel = MIN2(lastLevel, texObj->MaxLevel);
496 lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
499 numLevels = lastLevel - firstLevel + 1;
501 /* The hardware supports only 10 mipmap levels; ignore higher levels.
503 if ((numLevels > 10) && (ctx->Const.MaxTextureLevels > 10)) {
504 lastLevel -= numLevels - 10;
508 /* save these values, check if they effect the residency of the
511 if (viaObj->firstLevel != firstLevel ||
512 viaObj->lastLevel != lastLevel) {
513 viaObj->firstLevel = firstLevel;
514 viaObj->lastLevel = lastLevel;
515 viaObj->memType = VIA_MEM_MIXED;
518 if (VIA_DEBUG & DEBUG_TEXTURE & 0)
519 fprintf(stderr, "%s, current memType: %s\n",
521 get_memtype_name(viaObj->memType));
524 if (viaObj->memType == VIA_MEM_MIXED ||
525 viaObj->memType == VIA_MEM_SYSTEM) {
526 if (!viaSwapInTexObject(vmesa, viaObj)) {
527 if (VIA_DEBUG & DEBUG_TEXTURE)
528 if (!vmesa->thrashing)
529 fprintf(stderr, "Thrashing flag set for frame %d\n",
531 vmesa->thrashing = GL_TRUE;
536 if (viaObj->memType == VIA_MEM_AGP)
537 viaObj->regTexFM = (HC_SubA_HTXnFM << 24) | HC_HTXnLoc_AGP | texFormat;
539 viaObj->regTexFM = (HC_SubA_HTXnFM << 24) | HC_HTXnLoc_Local | texFormat;
542 for (i = 0; i < numLevels; i++) {
543 struct via_texture_image *viaImage =
544 (struct via_texture_image *)texObj->Image[0][firstLevel + i];
546 w = viaImage->image.WidthLog2;
547 h = viaImage->image.HeightLog2;
548 p = viaImage->pitchLog2;
550 assert(viaImage->texMem->memType == viaObj->memType);
552 texBase = viaImage->texMem->texBase;
554 if (VIA_DEBUG & DEBUG_TEXTURE)
555 fprintf(stderr, "%s: no texBase[%d]\n", __FUNCTION__, i);
559 /* Image has to remain resident until the coming fence is retired.
561 move_to_head( &vmesa->tex_image_list[viaImage->texMem->memType],
563 viaImage->texMem->lastUsed = vmesa->lastBreadcrumbWrite;
566 viaObj->regTexBaseAndPitch[i].baseL =
567 ((HC_SubA_HTXnL0BasL + i) << 24) | (texBase & 0xFFFFFF);
569 viaObj->regTexBaseAndPitch[i].pitchLog2 =
570 ((HC_SubA_HTXnL0Pit + i) << 24) | (p << 20);
573 /* The base high bytes for each 3 levels are packed
574 * together into one register:
578 basH |= ((texBase & 0xFF000000) >> (k << 3));
580 viaObj->regTexBaseH[j] = ((j + HC_SubA_HTXnL012BasH) << 24) | basH;
584 /* Likewise, sets of 6 log2width and log2height values are
585 * packed into individual registers:
589 widthExp |= (((GLuint)w & 0xF) << (m << 2));
590 heightExp |= (((GLuint)h & 0xF) << (m << 2));
592 viaObj->regTexWidthLog2[l] =
593 (l + HC_SubA_HTXnL0_5WE) << 24 | widthExp;
594 viaObj->regTexHeightLog2[l] =
595 (l + HC_SubA_HTXnL0_5HE) << 24 | heightExp;
605 viaObj->regTexBaseH[j] = ((j + HC_SubA_HTXnL012BasH) << 24) | basH;
608 viaObj->regTexWidthLog2[l] = (l + HC_SubA_HTXnL0_5WE) << 24 | widthExp;
609 viaObj->regTexHeightLog2[l] = (l + HC_SubA_HTXnL0_5HE) << 24 | heightExp;
616 GLboolean viaUpdateTextureState( struct gl_context *ctx )
618 struct gl_texture_unit *texUnit = ctx->Texture.Unit;
621 for (i = 0; i < 2; i++) {
622 if (texUnit[i]._ReallyEnabled == TEXTURE_2D_BIT ||
623 texUnit[i]._ReallyEnabled == TEXTURE_1D_BIT) {
625 if (!viaSetTexImages(ctx, texUnit[i]._Current))
628 else if (texUnit[i]._ReallyEnabled) {
643 static void viaTexImage(struct gl_context *ctx,
645 GLenum target, GLint level,
646 GLint internalFormat,
647 GLint width, GLint height, GLint border,
648 GLenum format, GLenum type, const void *pixels,
649 const struct gl_pixelstore_attrib *packing,
650 struct gl_texture_object *texObj,
651 struct gl_texture_image *texImage)
653 struct via_context *vmesa = VIA_CONTEXT(ctx);
654 GLint postConvWidth = width;
655 GLint postConvHeight = height;
656 GLint texelBytes, sizeInBytes;
657 struct via_texture_object *viaObj = (struct via_texture_object *)texObj;
658 struct via_texture_image *viaImage = (struct via_texture_image *)texImage;
659 int heaps[3], nheaps, i;
661 if (!is_empty_list(&vmesa->freed_tex_buffers)) {
662 viaCheckBreadcrumb(vmesa, 0);
663 via_release_pending_textures(vmesa);
666 /* choose the texture format */
667 texImage->TexFormat = viaChooseTexFormat(ctx, internalFormat,
670 assert(texImage->TexFormat);
672 texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
674 /* Minimum pitch of 32 bytes */
675 if (postConvWidth * texelBytes < 32) {
676 postConvWidth = 32 / texelBytes;
677 texImage->RowStride = postConvWidth;
680 assert(texImage->RowStride == postConvWidth);
681 viaImage->pitchLog2 = _mesa_logbase2(postConvWidth * texelBytes);
683 /* allocate memory */
684 if (_mesa_is_format_compressed(texImage->TexFormat))
685 sizeInBytes = _mesa_format_image_size(texImage->TexFormat,
690 sizeInBytes = postConvWidth * postConvHeight * texelBytes;
693 /* Attempt to allocate texture memory directly, otherwise use main
694 * memory and this texture will always be a fallback. FIXME!
696 * TODO: make room in agp if this fails.
697 * TODO: use fb ram for textures as well.
701 switch (viaObj->memType) {
702 case VIA_MEM_UNKNOWN:
703 heaps[0] = VIA_MEM_AGP;
704 heaps[1] = VIA_MEM_VIDEO;
705 heaps[2] = VIA_MEM_SYSTEM;
710 heaps[0] = viaObj->memType;
711 heaps[1] = VIA_MEM_SYSTEM;
717 heaps[0] = VIA_MEM_SYSTEM;
722 for (i = 0; i < nheaps && !viaImage->texMem; i++) {
723 if (VIA_DEBUG & DEBUG_TEXTURE)
724 fprintf(stderr, "try %s (obj %s)\n", get_memtype_name(heaps[i]),
725 get_memtype_name(viaObj->memType));
726 viaImage->texMem = via_alloc_texture(vmesa, sizeInBytes, heaps[i]);
729 if (!viaImage->texMem) {
730 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
734 if (VIA_DEBUG & DEBUG_TEXTURE)
735 fprintf(stderr, "upload %d bytes to %s\n", sizeInBytes,
736 get_memtype_name(viaImage->texMem->memType));
738 viaImage->texMem->image = viaImage;
739 texImage->Data = viaImage->texMem->bufAddr;
741 if (viaObj->memType == VIA_MEM_UNKNOWN)
742 viaObj->memType = viaImage->texMem->memType;
743 else if (viaObj->memType != viaImage->texMem->memType)
744 viaObj->memType = VIA_MEM_MIXED;
746 if (VIA_DEBUG & DEBUG_TEXTURE)
747 fprintf(stderr, "%s, obj %s, image : %s\n",
749 get_memtype_name(viaObj->memType),
750 get_memtype_name(viaImage->texMem->memType));
752 vmesa->clearTexCache = 1;
754 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
756 pixels, packing, "glTexImage");
758 /* Note: we check for a NULL image pointer here, _after_ we allocated
759 * memory for the texture. That's what the GL spec calls for.
767 if (_mesa_is_format_compressed(texImage->TexFormat)) {
768 dstRowStride = _mesa_format_row_stride(texImage->TexFormat, width);
771 dstRowStride = postConvWidth * _mesa_get_format_bytes(texImage->TexFormat);
773 success = _mesa_texstore(ctx, dims,
774 texImage->_BaseFormat,
777 0, 0, 0, /* dstX/Y/Zoffset */
779 texImage->ImageOffsets,
781 format, type, pixels, packing);
783 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
787 _mesa_unmap_teximage_pbo(ctx, packing);
790 static void viaTexImage2D(struct gl_context *ctx,
791 GLenum target, GLint level,
792 GLint internalFormat,
793 GLint width, GLint height, GLint border,
794 GLenum format, GLenum type, const void *pixels,
795 const struct gl_pixelstore_attrib *packing,
796 struct gl_texture_object *texObj,
797 struct gl_texture_image *texImage)
799 viaTexImage( ctx, 2, target, level,
800 internalFormat, width, height, border,
801 format, type, pixels,
802 packing, texObj, texImage );
805 static void viaTexSubImage2D(struct gl_context *ctx,
808 GLint xoffset, GLint yoffset,
809 GLsizei width, GLsizei height,
810 GLenum format, GLenum type,
811 const GLvoid *pixels,
812 const struct gl_pixelstore_attrib *packing,
813 struct gl_texture_object *texObj,
814 struct gl_texture_image *texImage)
816 struct via_context *vmesa = VIA_CONTEXT(ctx);
818 viaWaitIdle(vmesa, GL_TRUE);
819 vmesa->clearTexCache = 1;
821 _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
822 height, format, type, pixels, packing, texObj,
826 static void viaTexImage1D(struct gl_context *ctx,
827 GLenum target, GLint level,
828 GLint internalFormat,
829 GLint width, GLint border,
830 GLenum format, GLenum type, const void *pixels,
831 const struct gl_pixelstore_attrib *packing,
832 struct gl_texture_object *texObj,
833 struct gl_texture_image *texImage)
835 viaTexImage( ctx, 1, target, level,
836 internalFormat, width, 1, border,
837 format, type, pixels,
838 packing, texObj, texImage );
841 static void viaTexSubImage1D(struct gl_context *ctx,
846 GLenum format, GLenum type,
847 const GLvoid *pixels,
848 const struct gl_pixelstore_attrib *packing,
849 struct gl_texture_object *texObj,
850 struct gl_texture_image *texImage)
852 struct via_context *vmesa = VIA_CONTEXT(ctx);
854 viaWaitIdle(vmesa, GL_TRUE);
855 vmesa->clearTexCache = 1;
857 _mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
858 format, type, pixels, packing, texObj,
864 static GLboolean viaIsTextureResident(struct gl_context *ctx,
865 struct gl_texture_object *texObj)
867 struct via_texture_object *viaObj =
868 (struct via_texture_object *)texObj;
870 return (viaObj->memType == VIA_MEM_AGP ||
871 viaObj->memType == VIA_MEM_VIDEO);
876 static struct gl_texture_image *viaNewTextureImage( struct gl_context *ctx )
879 return (struct gl_texture_image *)CALLOC_STRUCT(via_texture_image);
883 static struct gl_texture_object *viaNewTextureObject( struct gl_context *ctx,
887 struct via_texture_object *obj = CALLOC_STRUCT(via_texture_object);
889 _mesa_initialize_texture_object(&obj->obj, name, target);
892 obj->memType = VIA_MEM_UNKNOWN;
898 static void viaFreeTextureImageData( struct gl_context *ctx,
899 struct gl_texture_image *texImage )
901 struct via_context *vmesa = VIA_CONTEXT(ctx);
902 struct via_texture_image *image = (struct via_texture_image *)texImage;
905 via_free_texture(vmesa, image->texMem);
906 image->texMem = NULL;
909 texImage->Data = NULL;
915 void viaInitTextureFuncs(struct dd_function_table * functions)
917 functions->ChooseTextureFormat = viaChooseTexFormat;
918 functions->TexImage1D = viaTexImage1D;
919 functions->TexImage2D = viaTexImage2D;
920 functions->TexSubImage1D = viaTexSubImage1D;
921 functions->TexSubImage2D = viaTexSubImage2D;
923 functions->NewTextureObject = viaNewTextureObject;
924 functions->NewTextureImage = viaNewTextureImage;
925 functions->DeleteTexture = _mesa_delete_texture_object;
926 functions->FreeTexImageData = viaFreeTextureImageData;
928 #if 0 && defined( USE_SSE_ASM )
930 * XXX this code is disabled for now because the via_sse_memcpy()
931 * routine causes segfaults with flightgear.
932 * See Mesa3d-dev mail list messages from 7/15/2005 for details.
933 * Note that this function is currently disabled in via_tris.c too.
935 if (getenv("VIA_NO_SSE"))
936 functions->TextureMemCpy = memcpy;
938 functions->TextureMemCpy = via_sse_memcpy;
940 functions->TextureMemCpy = memcpy;
943 functions->IsTextureResident = viaIsTextureResident;