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.
36 #include "simple_list.h"
37 #include "texcompress.h"
38 #include "texformat.h"
43 #include "via_context.h"
46 #include "via_state.h"
47 #include "via_ioctl.h"
48 #include "via_3d_reg.h"
50 static const struct gl_texture_format
*
51 viaChooseTexFormat( GLcontext
*ctx
, GLint internalFormat
,
52 GLenum format
, GLenum type
)
54 struct via_context
*vmesa
= VIA_CONTEXT(ctx
);
55 const GLboolean do32bpt
= ( vmesa
->viaScreen
->bitsPerPixel
== 32
56 /* && vmesa->viaScreen->textureSize > 4*1024*1024 */
60 switch ( internalFormat
) {
63 case GL_COMPRESSED_RGBA
:
64 if ( format
== GL_BGRA
) {
65 if ( type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
66 type
== GL_UNSIGNED_BYTE
) {
67 return &_mesa_texformat_argb8888
;
69 else if ( type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
70 return &_mesa_texformat_argb4444
;
72 else if ( type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
73 return &_mesa_texformat_argb1555
;
76 else if ( type
== GL_UNSIGNED_BYTE
||
77 type
== GL_UNSIGNED_INT_8_8_8_8_REV
||
78 type
== GL_UNSIGNED_INT_8_8_8_8
) {
79 return &_mesa_texformat_argb8888
;
81 return do32bpt
? &_mesa_texformat_argb8888
: &_mesa_texformat_argb4444
;
85 case GL_COMPRESSED_RGB
:
86 if ( format
== GL_RGB
&& type
== GL_UNSIGNED_SHORT_5_6_5
) {
87 return &_mesa_texformat_rgb565
;
89 else if ( type
== GL_UNSIGNED_BYTE
) {
90 return &_mesa_texformat_argb8888
;
92 return do32bpt
? &_mesa_texformat_argb8888
: &_mesa_texformat_rgb565
;
98 return &_mesa_texformat_argb8888
;
102 return &_mesa_texformat_argb4444
;
105 return &_mesa_texformat_argb1555
;
111 return &_mesa_texformat_argb8888
;
116 return &_mesa_texformat_rgb565
;
123 case GL_COMPRESSED_ALPHA
:
124 return &_mesa_texformat_a8
;
132 case GL_COMPRESSED_LUMINANCE
:
133 return &_mesa_texformat_l8
;
136 case GL_LUMINANCE_ALPHA
:
137 case GL_LUMINANCE4_ALPHA4
:
138 case GL_LUMINANCE6_ALPHA2
:
139 case GL_LUMINANCE8_ALPHA8
:
140 case GL_LUMINANCE12_ALPHA4
:
141 case GL_LUMINANCE12_ALPHA12
:
142 case GL_LUMINANCE16_ALPHA16
:
143 case GL_COMPRESSED_LUMINANCE_ALPHA
:
144 return &_mesa_texformat_al88
;
151 case GL_COMPRESSED_INTENSITY
:
152 return &_mesa_texformat_i8
;
155 if (type
== GL_UNSIGNED_SHORT_8_8_MESA
||
156 type
== GL_UNSIGNED_BYTE
)
157 return &_mesa_texformat_ycbcr
;
159 return &_mesa_texformat_ycbcr_rev
;
161 case GL_COMPRESSED_RGB_FXT1_3DFX
:
162 return &_mesa_texformat_rgb_fxt1
;
163 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
164 return &_mesa_texformat_rgba_fxt1
;
168 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
169 return &_mesa_texformat_rgb_dxt1
;
171 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
172 return &_mesa_texformat_rgba_dxt1
;
176 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
177 return &_mesa_texformat_rgba_dxt3
;
179 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
180 return &_mesa_texformat_rgba_dxt5
;
183 case GL_COLOR_INDEX1_EXT
:
184 case GL_COLOR_INDEX2_EXT
:
185 case GL_COLOR_INDEX4_EXT
:
186 case GL_COLOR_INDEX8_EXT
:
187 case GL_COLOR_INDEX12_EXT
:
188 case GL_COLOR_INDEX16_EXT
:
189 return &_mesa_texformat_ci8
;
192 fprintf(stderr
, "unexpected texture format %s in %s\n",
193 _mesa_lookup_enum_by_nr(internalFormat
),
198 return NULL
; /* never get here */
201 static int logbase2(int n
)
214 static const char *get_memtype_name( GLint memType
)
216 static const char *names
[] = {
224 return names
[memType
];
228 static GLboolean
viaMoveTexBuffers( struct via_context
*vmesa
,
229 struct via_tex_buffer
**buffers
,
233 struct via_tex_buffer
*newTexBuf
[VIA_MAX_TEXLEVELS
];
236 if (VIA_DEBUG
& DEBUG_TEXTURE
)
237 fprintf(stderr
, "%s to %s\n",
239 get_memtype_name(newMemType
));
241 memset(newTexBuf
, 0, sizeof(newTexBuf
));
243 /* First do all the allocations (or fail):
245 for (i
= 0; i
< nr
; i
++) {
246 if (buffers
[i
]->memType
!= newMemType
) {
248 /* Don't allow uploads in a thrash state. Should try and
249 * catch this earlier.
251 if (vmesa
->thrashing
&& newMemType
!= VIA_MEM_SYSTEM
)
254 newTexBuf
[i
] = via_alloc_texture(vmesa
,
263 /* Now copy all the image data and free the old texture memory.
265 for (i
= 0; i
< nr
; i
++) {
267 memcpy(newTexBuf
[i
]->bufAddr
,
271 newTexBuf
[i
]->image
= buffers
[i
]->image
;
272 newTexBuf
[i
]->image
->texMem
= newTexBuf
[i
];
273 newTexBuf
[i
]->image
->image
.Data
= newTexBuf
[i
]->bufAddr
;
274 via_free_texture(vmesa
, buffers
[i
]);
278 if (VIA_DEBUG
& DEBUG_TEXTURE
)
279 fprintf(stderr
, "%s - success\n", __FUNCTION__
);
284 /* Release any allocations made prior to failure:
286 if (VIA_DEBUG
& DEBUG_TEXTURE
)
287 fprintf(stderr
, "%s - failed\n", __FUNCTION__
);
289 for (i
= 0; i
< nr
; i
++) {
291 via_free_texture(vmesa
, newTexBuf
[i
]);
299 static GLboolean
viaMoveTexObject( struct via_context
*vmesa
,
300 struct via_texture_object
*viaObj
,
303 struct via_texture_image
**viaImage
=
304 (struct via_texture_image
**)&viaObj
->obj
.Image
[0][0];
305 struct via_tex_buffer
*buffers
[VIA_MAX_TEXLEVELS
];
308 for (i
= viaObj
->firstLevel
; i
<= viaObj
->lastLevel
; i
++)
309 buffers
[nr
++] = viaImage
[i
]->texMem
;
311 if (viaMoveTexBuffers( vmesa
, &buffers
[0], nr
, newMemType
)) {
312 viaObj
->memType
= newMemType
;
321 static GLboolean
viaSwapInTexObject( struct via_context
*vmesa
,
322 struct via_texture_object
*viaObj
)
324 const struct via_texture_image
*baseImage
=
325 (struct via_texture_image
*)viaObj
->obj
.Image
[0][viaObj
->obj
.BaseLevel
];
327 if (VIA_DEBUG
& DEBUG_TEXTURE
)
328 fprintf(stderr
, "%s\n", __FUNCTION__
);
330 if (baseImage
->texMem
->memType
!= VIA_MEM_SYSTEM
)
331 return viaMoveTexObject( vmesa
, viaObj
, baseImage
->texMem
->memType
);
333 return (viaMoveTexObject( vmesa
, viaObj
, VIA_MEM_AGP
) ||
334 viaMoveTexObject( vmesa
, viaObj
, VIA_MEM_VIDEO
));
338 /* This seems crude, but it asks a fairly pertinent question and gives
339 * an accurate answer:
341 static GLboolean
viaIsTexMemLow( struct via_context
*vmesa
,
344 struct via_tex_buffer
*buf
= via_alloc_texture(vmesa
, 512 * 1024, heap
);
348 via_free_texture(vmesa
, buf
);
353 /* Speculatively move texture images which haven't been used in a
354 * while back to system memory.
356 * TODO: only do this when texture memory is low.
360 * TODO: keep the fb/agp version hanging around and use the local
361 * version as backing store, so re-upload might be avoided.
363 * TODO: do this properly in the kernel...
365 GLboolean
viaSwapOutWork( struct via_context
*vmesa
)
367 struct via_tex_buffer
*s
, *tmp
;
371 if (VIA_DEBUG
& DEBUG_TEXTURE
)
372 fprintf(stderr
, "%s VID %d AGP %d SYS %d\n", __FUNCTION__
,
373 vmesa
->total_alloc
[VIA_MEM_VIDEO
],
374 vmesa
->total_alloc
[VIA_MEM_AGP
],
375 vmesa
->total_alloc
[VIA_MEM_SYSTEM
]);
378 for (heap
= VIA_MEM_VIDEO
; heap
<= VIA_MEM_AGP
; heap
++) {
379 GLuint nr
= 0, sz
= 0;
381 if (vmesa
->thrashing
) {
382 if (VIA_DEBUG
& DEBUG_TEXTURE
)
383 fprintf(stderr
, "Heap %d: trash flag\n", heap
);
384 target
= 1*1024*1024;
386 else if (viaIsTexMemLow(vmesa
, heap
)) {
387 if (VIA_DEBUG
& DEBUG_TEXTURE
)
388 fprintf(stderr
, "Heap %d: low memory\n", heap
);
392 if (VIA_DEBUG
& DEBUG_TEXTURE
)
393 fprintf(stderr
, "Heap %d: nothing to do\n", heap
);
397 foreach_s( s
, tmp
, &vmesa
->tex_image_list
[heap
] ) {
398 if (s
->lastUsed
< vmesa
->lastSwap
[1]) {
399 struct via_texture_object
*viaObj
=
400 (struct via_texture_object
*) s
->image
->image
.TexObject
;
402 if (VIA_DEBUG
& DEBUG_TEXTURE
)
404 "back copy tex sz %d, lastUsed %d lastSwap %d\n",
405 s
->size
, s
->lastUsed
, vmesa
->lastSwap
[1]);
407 if (viaMoveTexBuffers( vmesa
, &s
, 1, VIA_MEM_SYSTEM
)) {
408 viaObj
->memType
= VIA_MEM_MIXED
;
412 if (VIA_DEBUG
& DEBUG_TEXTURE
)
413 fprintf(stderr
, "Failed to back copy texture!\n");
423 vmesa
->thrashing
= GL_FALSE
; /* might not get set otherwise? */
428 assert(sz
== vmesa
->total_alloc
[heap
]);
430 if (VIA_DEBUG
& DEBUG_TEXTURE
)
431 fprintf(stderr
, "Heap %d: nr %d tot sz %d\n", heap
, nr
, sz
);
440 /* Basically, just collect the image dimensions and addresses for each
441 * image and update the texture object state accordingly.
443 static GLboolean
viaSetTexImages(GLcontext
*ctx
,
444 struct gl_texture_object
*texObj
)
446 struct via_context
*vmesa
= VIA_CONTEXT(ctx
);
447 struct via_texture_object
*viaObj
= (struct via_texture_object
*)texObj
;
448 const struct via_texture_image
*baseImage
=
449 (struct via_texture_image
*)texObj
->Image
[0][texObj
->BaseLevel
];
450 GLint firstLevel
, lastLevel
, numLevels
;
453 GLint i
, j
= 0, k
= 0, l
= 0, m
= 0;
457 GLuint heightExp
= 0;
459 switch (baseImage
->image
.TexFormat
->MesaFormat
) {
460 case MESA_FORMAT_ARGB8888
:
461 texFormat
= HC_HTXnFM_ARGB8888
;
463 case MESA_FORMAT_ARGB4444
:
464 texFormat
= HC_HTXnFM_ARGB4444
;
466 case MESA_FORMAT_RGB565
:
467 texFormat
= HC_HTXnFM_RGB565
;
469 case MESA_FORMAT_ARGB1555
:
470 texFormat
= HC_HTXnFM_ARGB1555
;
472 case MESA_FORMAT_RGB888
:
473 texFormat
= HC_HTXnFM_ARGB0888
;
476 texFormat
= HC_HTXnFM_L8
;
479 texFormat
= HC_HTXnFM_T8
;
481 case MESA_FORMAT_CI8
:
482 texFormat
= HC_HTXnFM_Index8
;
484 case MESA_FORMAT_AL88
:
485 texFormat
= HC_HTXnFM_AL88
;
488 texFormat
= HC_HTXnFM_A8
;
491 _mesa_problem(vmesa
->glCtx
, "Bad texture format in viaSetTexImages");
495 /* Compute which mipmap levels we really want to send to the hardware.
496 * This depends on the base image size, GL_TEXTURE_MIN_LOD,
497 * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
498 * Yes, this looks overly complicated, but it's all needed.
500 if (texObj
->MinFilter
== GL_LINEAR
|| texObj
->MinFilter
== GL_NEAREST
) {
501 firstLevel
= lastLevel
= texObj
->BaseLevel
;
504 firstLevel
= texObj
->BaseLevel
+ (GLint
)(texObj
->MinLod
+ 0.5);
505 firstLevel
= MAX2(firstLevel
, texObj
->BaseLevel
);
506 lastLevel
= texObj
->BaseLevel
+ (GLint
)(texObj
->MaxLod
+ 0.5);
507 lastLevel
= MAX2(lastLevel
, texObj
->BaseLevel
);
508 lastLevel
= MIN2(lastLevel
, texObj
->BaseLevel
+ baseImage
->image
.MaxLog2
);
509 lastLevel
= MIN2(lastLevel
, texObj
->MaxLevel
);
510 lastLevel
= MAX2(firstLevel
, lastLevel
); /* need at least one level */
513 numLevels
= lastLevel
- firstLevel
+ 1;
515 /* save these values, check if they effect the residency of the
518 if (viaObj
->firstLevel
!= firstLevel
||
519 viaObj
->lastLevel
!= lastLevel
) {
520 viaObj
->firstLevel
= firstLevel
;
521 viaObj
->lastLevel
= lastLevel
;
522 viaObj
->memType
= VIA_MEM_MIXED
;
525 if (VIA_DEBUG
& DEBUG_TEXTURE
& 0)
526 fprintf(stderr
, "%s, current memType: %s\n",
528 get_memtype_name(viaObj
->memType
));
531 if (viaObj
->memType
== VIA_MEM_MIXED
||
532 viaObj
->memType
== VIA_MEM_SYSTEM
) {
533 if (!viaSwapInTexObject(vmesa
, viaObj
)) {
534 if (VIA_DEBUG
& DEBUG_TEXTURE
)
535 if (!vmesa
->thrashing
)
536 fprintf(stderr
, "Thrashing flag set for frame %d\n",
538 vmesa
->thrashing
= GL_TRUE
;
543 if (viaObj
->memType
== VIA_MEM_AGP
)
544 viaObj
->regTexFM
= (HC_SubA_HTXnFM
<< 24) | HC_HTXnLoc_AGP
| texFormat
;
546 viaObj
->regTexFM
= (HC_SubA_HTXnFM
<< 24) | HC_HTXnLoc_Local
| texFormat
;
549 for (i
= 0; i
< numLevels
; i
++) {
550 struct via_texture_image
*viaImage
=
551 (struct via_texture_image
*)texObj
->Image
[0][firstLevel
+ i
];
553 w
= viaImage
->image
.WidthLog2
;
554 h
= viaImage
->image
.HeightLog2
;
555 p
= viaImage
->pitchLog2
;
557 assert(viaImage
->texMem
->memType
== viaObj
->memType
);
559 texBase
= viaImage
->texMem
->texBase
;
561 if (VIA_DEBUG
& DEBUG_TEXTURE
)
562 fprintf(stderr
, "%s: no texBase[%d]\n", __FUNCTION__
, i
);
566 /* Image has to remain resident until the coming fence is retired.
568 move_to_head( &vmesa
->tex_image_list
[viaImage
->texMem
->memType
],
570 viaImage
->texMem
->lastUsed
= vmesa
->lastBreadcrumbWrite
;
573 viaObj
->regTexBaseAndPitch
[i
].baseL
=
574 ((HC_SubA_HTXnL0BasL
+ i
) << 24) | (texBase
& 0xFFFFFF);
576 viaObj
->regTexBaseAndPitch
[i
].pitchLog2
=
577 ((HC_SubA_HTXnL0Pit
+ i
) << 24) | (p
<< 20);
580 /* The base high bytes for each 3 levels are packed
581 * together into one register:
585 basH
|= ((texBase
& 0xFF000000) >> (k
<< 3));
587 viaObj
->regTexBaseH
[j
] = ((j
+ HC_SubA_HTXnL012BasH
) << 24) | basH
;
591 /* Likewise, sets of 6 log2width and log2height values are
592 * packed into individual registers:
596 widthExp
|= (((GLuint
)w
& 0xF) << (m
<< 2));
597 heightExp
|= (((GLuint
)h
& 0xF) << (m
<< 2));
599 viaObj
->regTexWidthLog2
[l
] =
600 (l
+ HC_SubA_HTXnL0_5WE
) << 24 | widthExp
;
601 viaObj
->regTexHeightLog2
[l
] =
602 (l
+ HC_SubA_HTXnL0_5HE
) << 24 | heightExp
;
612 viaObj
->regTexBaseH
[j
] = ((j
+ HC_SubA_HTXnL012BasH
) << 24) | basH
;
615 viaObj
->regTexWidthLog2
[l
] = (l
+ HC_SubA_HTXnL0_5WE
) << 24 | widthExp
;
616 viaObj
->regTexHeightLog2
[l
] = (l
+ HC_SubA_HTXnL0_5HE
) << 24 | heightExp
;
623 GLboolean
viaUpdateTextureState( GLcontext
*ctx
)
625 struct gl_texture_unit
*texUnit
= ctx
->Texture
.Unit
;
628 for (i
= 0; i
< 2; i
++) {
629 if (texUnit
[i
]._ReallyEnabled
== TEXTURE_2D_BIT
||
630 texUnit
[i
]._ReallyEnabled
== TEXTURE_1D_BIT
) {
632 if (!viaSetTexImages(ctx
, texUnit
[i
]._Current
))
635 else if (texUnit
[i
]._ReallyEnabled
) {
650 static void viaTexImage(GLcontext
*ctx
,
652 GLenum target
, GLint level
,
653 GLint internalFormat
,
654 GLint width
, GLint height
, GLint border
,
655 GLenum format
, GLenum type
, const void *pixels
,
656 const struct gl_pixelstore_attrib
*packing
,
657 struct gl_texture_object
*texObj
,
658 struct gl_texture_image
*texImage
)
660 struct via_context
*vmesa
= VIA_CONTEXT(ctx
);
661 GLint postConvWidth
= width
;
662 GLint postConvHeight
= height
;
663 GLint texelBytes
, sizeInBytes
;
664 struct via_texture_object
*viaObj
= (struct via_texture_object
*)texObj
;
665 struct via_texture_image
*viaImage
= (struct via_texture_image
*)texImage
;
666 int heaps
[3], nheaps
, i
;
668 if (!is_empty_list(&vmesa
->freed_tex_buffers
)) {
669 viaCheckBreadcrumb(vmesa
, 0);
670 via_release_pending_textures(vmesa
);
673 if (ctx
->_ImageTransferState
& IMAGE_CONVOLUTION_BIT
) {
674 _mesa_adjust_image_for_convolution(ctx
, dims
, &postConvWidth
,
678 /* choose the texture format */
679 texImage
->TexFormat
= viaChooseTexFormat(ctx
, internalFormat
,
682 assert(texImage
->TexFormat
);
685 texImage
->FetchTexelc
= texImage
->TexFormat
->FetchTexel1D
;
686 texImage
->FetchTexelf
= texImage
->TexFormat
->FetchTexel1Df
;
689 texImage
->FetchTexelc
= texImage
->TexFormat
->FetchTexel2D
;
690 texImage
->FetchTexelf
= texImage
->TexFormat
->FetchTexel2Df
;
692 texelBytes
= texImage
->TexFormat
->TexelBytes
;
695 /* Minimum pitch of 32 bytes */
696 if (postConvWidth
* texelBytes
< 32) {
697 postConvWidth
= 32 / texelBytes
;
698 texImage
->RowStride
= postConvWidth
;
701 assert(texImage
->RowStride
== postConvWidth
);
702 viaImage
->pitchLog2
= logbase2(postConvWidth
* texelBytes
);
704 /* allocate memory */
705 if (texImage
->IsCompressed
)
706 sizeInBytes
= texImage
->CompressedSize
;
708 sizeInBytes
= postConvWidth
* postConvHeight
* texelBytes
;
711 /* Attempt to allocate texture memory directly, otherwise use main
712 * memory and this texture will always be a fallback. FIXME!
714 * TODO: make room in agp if this fails.
715 * TODO: use fb ram for textures as well.
719 switch (viaObj
->memType
) {
720 case VIA_MEM_UNKNOWN
:
721 heaps
[0] = VIA_MEM_AGP
;
722 heaps
[1] = VIA_MEM_VIDEO
;
723 heaps
[2] = VIA_MEM_SYSTEM
;
728 heaps
[0] = viaObj
->memType
;
729 heaps
[1] = VIA_MEM_SYSTEM
;
735 heaps
[0] = VIA_MEM_SYSTEM
;
740 for (i
= 0; i
< nheaps
&& !viaImage
->texMem
; i
++) {
741 if (VIA_DEBUG
& DEBUG_TEXTURE
)
742 fprintf(stderr
, "try %s (obj %s)\n", get_memtype_name(heaps
[i
]),
743 get_memtype_name(viaObj
->memType
));
744 viaImage
->texMem
= via_alloc_texture(vmesa
, sizeInBytes
, heaps
[i
]);
747 if (!viaImage
->texMem
) {
748 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage");
752 if (VIA_DEBUG
& DEBUG_TEXTURE
)
753 fprintf(stderr
, "upload %d bytes to %s\n", sizeInBytes
,
754 get_memtype_name(viaImage
->texMem
->memType
));
756 viaImage
->texMem
->image
= viaImage
;
757 texImage
->Data
= viaImage
->texMem
->bufAddr
;
759 if (viaObj
->memType
== VIA_MEM_UNKNOWN
)
760 viaObj
->memType
= viaImage
->texMem
->memType
;
761 else if (viaObj
->memType
!= viaImage
->texMem
->memType
)
762 viaObj
->memType
= VIA_MEM_MIXED
;
764 if (VIA_DEBUG
& DEBUG_TEXTURE
)
765 fprintf(stderr
, "%s, obj %s, image : %s\n",
767 get_memtype_name(viaObj
->memType
),
768 get_memtype_name(viaImage
->texMem
->memType
));
770 vmesa
->clearTexCache
= 1;
772 pixels
= _mesa_validate_pbo_teximage(ctx
, dims
, width
, height
, 1,
774 pixels
, packing
, "glTexImage");
776 /* Note: we check for a NULL image pointer here, _after_ we allocated
777 * memory for the texture. That's what the GL spec calls for.
782 GLint dstRowStride
, dstImageStride
= 0;
784 if (texImage
->IsCompressed
) {
785 dstRowStride
= _mesa_compressed_row_stride(texImage
->InternalFormat
,width
);
788 dstRowStride
= postConvWidth
* texImage
->TexFormat
->TexelBytes
;
790 ASSERT(texImage
->TexFormat
->StoreImage
);
791 success
= texImage
->TexFormat
->StoreImage(ctx
, dims
,
792 texImage
->_BaseFormat
,
795 0, 0, 0, /* dstX/Y/Zoffset */
796 dstRowStride
, dstImageStride
,
798 format
, type
, pixels
, packing
);
800 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glTexImage");
804 /* GL_SGIS_generate_mipmap */
805 if (level
== texObj
->BaseLevel
&& texObj
->GenerateMipmap
) {
806 _mesa_generate_mipmap(ctx
, target
,
807 &ctx
->Texture
.Unit
[ctx
->Texture
.CurrentUnit
],
811 _mesa_unmap_teximage_pbo(ctx
, packing
);
814 static void viaTexImage2D(GLcontext
*ctx
,
815 GLenum target
, GLint level
,
816 GLint internalFormat
,
817 GLint width
, GLint height
, GLint border
,
818 GLenum format
, GLenum type
, const void *pixels
,
819 const struct gl_pixelstore_attrib
*packing
,
820 struct gl_texture_object
*texObj
,
821 struct gl_texture_image
*texImage
)
823 viaTexImage( ctx
, 2, target
, level
,
824 internalFormat
, width
, height
, border
,
825 format
, type
, pixels
,
826 packing
, texObj
, texImage
);
829 static void viaTexSubImage2D(GLcontext
*ctx
,
832 GLint xoffset
, GLint yoffset
,
833 GLsizei width
, GLsizei height
,
834 GLenum format
, GLenum type
,
835 const GLvoid
*pixels
,
836 const struct gl_pixelstore_attrib
*packing
,
837 struct gl_texture_object
*texObj
,
838 struct gl_texture_image
*texImage
)
840 struct via_context
*vmesa
= VIA_CONTEXT(ctx
);
842 VIA_FLUSH_DMA(vmesa
);
843 vmesa
->clearTexCache
= 1;
845 _mesa_store_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
846 height
, format
, type
, pixels
, packing
, texObj
,
850 static void viaTexImage1D(GLcontext
*ctx
,
851 GLenum target
, GLint level
,
852 GLint internalFormat
,
853 GLint width
, GLint border
,
854 GLenum format
, GLenum type
, const void *pixels
,
855 const struct gl_pixelstore_attrib
*packing
,
856 struct gl_texture_object
*texObj
,
857 struct gl_texture_image
*texImage
)
859 viaTexImage( ctx
, 1, target
, level
,
860 internalFormat
, width
, 1, border
,
861 format
, type
, pixels
,
862 packing
, texObj
, texImage
);
865 static void viaTexSubImage1D(GLcontext
*ctx
,
870 GLenum format
, GLenum type
,
871 const GLvoid
*pixels
,
872 const struct gl_pixelstore_attrib
*packing
,
873 struct gl_texture_object
*texObj
,
874 struct gl_texture_image
*texImage
)
876 struct via_context
*vmesa
= VIA_CONTEXT(ctx
);
878 VIA_FLUSH_DMA(vmesa
);
879 vmesa
->clearTexCache
= 1;
881 _mesa_store_texsubimage1d(ctx
, target
, level
, xoffset
, width
,
882 format
, type
, pixels
, packing
, texObj
,
888 static GLboolean
viaIsTextureResident(GLcontext
*ctx
,
889 struct gl_texture_object
*texObj
)
891 struct via_texture_object
*viaObj
=
892 (struct via_texture_object
*)texObj
;
894 return (viaObj
->memType
== VIA_MEM_AGP
||
895 viaObj
->memType
== VIA_MEM_VIDEO
);
900 static struct gl_texture_image
*viaNewTextureImage( GLcontext
*ctx
)
903 return (struct gl_texture_image
*)CALLOC_STRUCT(via_texture_image
);
907 static struct gl_texture_object
*viaNewTextureObject( GLcontext
*ctx
,
911 struct via_texture_object
*obj
= CALLOC_STRUCT(via_texture_object
);
913 _mesa_initialize_texture_object(&obj
->obj
, name
, target
);
916 obj
->memType
= VIA_MEM_UNKNOWN
;
922 static void viaFreeTextureImageData( GLcontext
*ctx
,
923 struct gl_texture_image
*texImage
)
925 struct via_context
*vmesa
= VIA_CONTEXT(ctx
);
926 struct via_texture_image
*image
= (struct via_texture_image
*)texImage
;
929 via_free_texture(vmesa
, image
->texMem
);
930 image
->texMem
= NULL
;
933 texImage
->Data
= NULL
;
939 void viaInitTextureFuncs(struct dd_function_table
* functions
)
941 functions
->ChooseTextureFormat
= viaChooseTexFormat
;
942 functions
->TexImage1D
= viaTexImage1D
;
943 functions
->TexImage2D
= viaTexImage2D
;
944 functions
->TexSubImage1D
= viaTexSubImage1D
;
945 functions
->TexSubImage2D
= viaTexSubImage2D
;
947 functions
->NewTextureObject
= viaNewTextureObject
;
948 functions
->NewTextureImage
= viaNewTextureImage
;
949 functions
->DeleteTexture
= _mesa_delete_texture_object
;
950 functions
->FreeTexImageData
= viaFreeTextureImageData
;
952 #if 0 && defined( USE_SSE_ASM )
954 * XXX this code is disabled for now because the via_sse_memcpy()
955 * routine causes segfaults with flightgear.
956 * See Mesa3d-dev mail list messages from 7/15/2005 for details.
957 * Note that this function is currently disabled in via_tris.c too.
959 if (getenv("VIA_NO_SSE"))
960 functions
->TextureMemCpy
= _mesa_memcpy
;
962 functions
->TextureMemCpy
= via_sse_memcpy
;
964 functions
->TextureMemCpy
= _mesa_memcpy
;
967 functions
->UpdateTexturePalette
= 0;
968 functions
->IsTextureResident
= viaIsTextureResident
;