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
;