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.
32 #include "simple_list.h"
34 #include "texformat.h"
37 #include "via_context.h"
39 #include "via_state.h"
40 #include "via_ioctl.h"
42 /*=* John Sheng [2003.5.31] agp tex *=*/
43 GLuint agpFullCount
= 0;
45 void viaDestroyTexObj(viaContextPtr vmesa
, viaTextureObjectPtr t
)
48 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
53 /* This is sad - need to sync *in case* we upload a texture
54 * to this newly free memory...
57 via_free_texture(vmesa
, t
);
59 if (vmesa
&& t
->age
> vmesa
->dirtyAge
)
60 vmesa
->dirtyAge
= t
->age
;
64 t
->globj
->DriverData
= 0;
67 if (vmesa
->CurrentTexObj
[0] == t
) {
68 vmesa
->CurrentTexObj
[0] = 0;
69 vmesa
->dirty
&= ~VIA_UPLOAD_TEX0
;
72 if (vmesa
->CurrentTexObj
[1] == t
) {
73 vmesa
->CurrentTexObj
[1] = 0;
74 vmesa
->dirty
&= ~VIA_UPLOAD_TEX1
;
81 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
85 void viaSwapOutTexObj(viaContextPtr vmesa
, viaTextureObjectPtr t
)
88 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
91 via_free_texture(vmesa
, t
);
93 if (t
->age
> vmesa
->dirtyAge
)
94 vmesa
->dirtyAge
= t
->age
;
98 move_to_tail(&(vmesa
->SwappedOut
), t
);
100 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
104 /* Upload an image from mesa's internal copy.
106 static void viaUploadTexLevel(viaTextureObjectPtr t
, int level
)
108 const struct gl_texture_image
*image
= t
->image
[level
].image
;
112 fprintf(stderr
, "%s - in\n", __FUNCTION__
);
113 fprintf(stderr
, "width = %d, height = %d \n", image
->Width
, image
->Height
);
116 switch (t
->image
[level
].internalFormat
) {
119 if (image
->TexFormat
->MesaFormat
== MESA_FORMAT_ARGB8888
) {
120 GLuint
*dst
= (GLuint
*)(t
->bufAddr
+ t
->image
[level
].offset
);
121 GLuint
*src
= (GLuint
*)image
->Data
;
123 if (VIA_DEBUG
) fprintf(stderr
, "GL_RGB MESA_FORMAT_ARGB8888\n");
125 if (image
->Width
< 8) {
126 for (i
= 0; i
< image
->Height
; i
++) {
127 for (j
= 0; j
< image
->Width
; j
++) {
135 for (j
= 0; j
< image
->Height
* image
->Width
; j
++) {
141 /*memcpy(dst, src, image->Height * image->Width * sizeof(GLuint));*/
144 GLushort
*dst
= (GLushort
*)(t
->bufAddr
+ t
->image
[level
].offset
);
145 GLushort
*src
= (GLushort
*)image
->Data
;
147 if (VIA_DEBUG
) fprintf(stderr
, "GL_RGB !MESA_FORMAT_ARGB8888\n");
149 if (image
->Width
< 16) {
150 for (i
= 0; i
< image
->Height
; i
++) {
151 for (j
= 0; j
< image
->Width
; j
++) {
159 for (j
= 0; j
< image
->Height
* image
->Width
; j
++) {
165 /*memcpy(dst, src, image->Height * image->Width * sizeof(GLushort));*/
172 if (image
->TexFormat
->MesaFormat
== MESA_FORMAT_ARGB4444
) {
174 GLushort
*dst
= (GLushort
*)(t
->bufAddr
+ t
->image
[level
].offset
);
175 GLushort
*src
= (GLushort
*)image
->Data
;
176 if (image
->Width
< 16) {
177 for (i
= 0; i
< image
->Height
; i
++) {
178 for (j
= 0; j
< image
->Width
; j
++) {
186 for (j
= 0; j
< image
->Height
* image
->Width
; j
++) {
192 /*memcpy(dst, src, image->Height * image->Width * sizeof(GLushort));*/
194 if (VIA_DEBUG
) fprintf(stderr
, "GL_RGBA MESA_FORMAT_ARGB4444\n");
197 else if(image
->TexFormat
->MesaFormat
== MESA_FORMAT_ARGB8888
) {
198 GLuint
*dst
= (GLuint
*)(t
->bufAddr
+ t
->image
[level
].offset
);
199 GLuint
*src
= (GLuint
*)image
->Data
;
201 if (VIA_DEBUG
) fprintf(stderr
, "GL_RGBA !MESA_FORMAT_ARGB4444\n");
203 if (image
->Width
< 8) {
204 for (i
= 0; i
< image
->Height
; i
++) {
205 for (j
= 0; j
< image
->Width
; j
++) {
213 for (j
= 0; j
< image
->Height
* image
->Width
; j
++) {
219 /*memcpy(dst, src, image->Height * image->Width * sizeof(GLuint));*/
221 else if(image
->TexFormat
->MesaFormat
== MESA_FORMAT_ARGB1555
) {
222 GLushort
*dst
= (GLushort
*)(t
->bufAddr
+ t
->image
[level
].offset
);
223 GLushort
*src
= (GLushort
*)image
->Data
;
224 if (image
->Width
< 16) {
225 for (i
= 0; i
< image
->Height
; i
++) {
226 for (j
= 0; j
< image
->Width
; j
++) {
234 for (j
= 0; j
< image
->Height
* image
->Width
; j
++) {
240 /*memcpy(dst, src, image->Height * image->Width * sizeof(GLushort));*/
242 if (VIA_DEBUG
) fprintf(stderr
, "GL_RGBA MESA_FORMAT_ARGB1555\n");
250 GLubyte
*dst
= (GLubyte
*)(t
->bufAddr
+ t
->image
[level
].offset
);
251 GLubyte
*src
= (GLubyte
*)image
->Data
;
253 for (j
= 0; j
< image
->Height
* image
->Width
; j
++) {
263 GLubyte
*dst
= (GLubyte
*)(t
->bufAddr
+ t
->image
[level
].offset
);
264 GLubyte
*src
= (GLubyte
*)image
->Data
;
266 for (j
= 0; j
< image
->Height
* image
->Width
; j
++) {
274 case GL_LUMINANCE_ALPHA
:
276 GLushort
*dst
= (GLushort
*)(t
->bufAddr
+ t
->image
[level
].offset
);
277 GLushort
*src
= (GLushort
*)image
->Data
;
279 for (j
= 0; j
< image
->Height
* image
->Width
; j
++) {
289 GLubyte
*dst
= (GLubyte
*)(t
->bufAddr
+ t
->image
[level
].offset
);
290 GLubyte
*src
= (GLubyte
*)image
->Data
;
292 for (j
= 0; j
< image
->Height
* image
->Width
; j
++) {
300 /* TODO: Translate color indices *now*:
304 GLubyte
*dst
= (GLubyte
*)(t
->bufAddr
+ t
->image
[level
].offset
);
305 GLubyte
*src
= (GLubyte
*)image
->Data
;
307 for (j
= 0; j
< image
->Height
* image
->Width
; j
++) {
317 if (VIA_DEBUG
) fprintf(stderr
, "Not supported texture format %s\n",
318 _mesa_lookup_enum_by_nr(image
->Format
));
322 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
326 void viaPrintLocalLRU(viaContextPtr vmesa
)
328 viaTextureObjectPtr t
;
330 foreach (t
, &vmesa
->TexObjList
) {
334 fprintf(stderr
, "offset = %x, index = %x, size = %x\n",
341 fprintf(stderr
, "offset = %x, siez = %x\n",
351 void viaPrintGlobalLRU(viaContextPtr vmesa
)
354 drm_via_tex_region_t
*list
= vmesa
->sarea
->texList
;
356 for (i
= 0, j
= VIA_NR_TEX_REGIONS
; i
< VIA_NR_TEX_REGIONS
; i
++) {
358 if (VIA_DEBUG
) fprintf(stderr
, "list[%d] age %d next %d prev %d\n",
359 j
, list
[j
].age
, list
[j
].next
, list
[j
].prev
);
362 if (j
== VIA_NR_TEX_REGIONS
) break;
365 if (j
!= VIA_NR_TEX_REGIONS
)
366 if (VIA_DEBUG
) fprintf(stderr
, "Loop detected in global LRU\n");
370 void viaResetGlobalLRU(viaContextPtr vmesa
)
372 drm_via_tex_region_t
*list
= vmesa
->sarea
->texList
;
373 int sz
= 1 << vmesa
->viaScreen
->logTextureGranularity
;
376 /* (Re)initialize the global circular LRU list. The last element
377 * in the array (VIA_NR_TEX_REGIONS) is the sentinal. Keeping it
378 * at the end of the array allows it to be addressed rationally
379 * when looking up objects at a particular location in texture
382 for (i
= 0; (i
+ 1) * sz
<= vmesa
->viaScreen
->textureSize
; i
++) {
383 list
[i
].prev
= i
- 1;
384 list
[i
].next
= i
+ 1;
389 list
[0].prev
= VIA_NR_TEX_REGIONS
;
390 list
[i
].prev
= i
- 1;
391 list
[i
].next
= VIA_NR_TEX_REGIONS
;
392 list
[VIA_NR_TEX_REGIONS
].prev
= i
;
393 list
[VIA_NR_TEX_REGIONS
].next
= 0;
394 vmesa
->sarea
->texAge
= 0;
397 void viaUpdateTexLRU(viaContextPtr vmesa
, viaTextureObjectPtr t
)
399 vmesa
->texAge
= ++vmesa
->sarea
->texAge
;
400 move_to_head(&(vmesa
->TexObjList
), t
);
403 /* Called for every shared texture region which has increased in age
404 * since we last held the lock.
406 * Figures out which of our textures have been ejected by other clients,
407 * and pushes a placeholder texture onto the LRU list to represent
408 * the other client's textures.
410 void viaTexturesGone(viaContextPtr vmesa
,
415 viaTextureObjectPtr t
, tmp
;
417 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
419 foreach_s (t
, tmp
, &vmesa
->TexObjList
) {
420 viaSwapOutTexObj(vmesa
, t
);
423 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
427 /* This is called with the lock held. May have to eject our own and/or
428 * other client's texture objects to make room for the upload.
430 void viaUploadTexImages(viaContextPtr vmesa
, viaTextureObjectPtr t
)
435 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
437 LOCK_HARDWARE(vmesa
);
443 /*=* John Sheng [2003.5.31] agp tex *=*/
444 via_alloc_texture(vmesa
, t
);
445 /*via_alloc_texture_agp(vmesa, t);*/
447 if (t
->texMem
.offset
)
452 if (vmesa
->TexObjList
.prev
== vmesa
->CurrentTexObj
[0] ||
453 vmesa
->TexObjList
.prev
== vmesa
->CurrentTexObj
[1]) {
455 if (VIA_DEBUG
) fprintf(stderr
, "Hit bound texture in upload\n");
457 viaPrintLocalLRU(vmesa
);
458 UNLOCK_HARDWARE(vmesa
);
462 if (vmesa
->TexObjList
.prev
== &(vmesa
->TexObjList
)) {
464 if (VIA_DEBUG
) fprintf(stderr
, "Failed to upload texture, sz %d\n", t
->totalSize
);
466 mmDumpMemInfo(vmesa
->texHeap
);
467 UNLOCK_HARDWARE(vmesa
);
471 viaSwapOutTexObj(vmesa
, vmesa
->TexObjList
.prev
);
473 /*=* John Sheng [2003.5.31] agp tex *=*/
474 /*t->bufAddr = (char *)((GLuint)vmesa->driScreen->pFB + t->texMem.offset);*/
476 if (t
== vmesa
->CurrentTexObj
[0])
477 VIA_STATECHANGE(vmesa
, VIA_UPLOAD_TEX0
);
479 if (t
== vmesa
->CurrentTexObj
[1])
480 VIA_STATECHANGE(vmesa
, VIA_UPLOAD_TEX1
);
482 viaUpdateTexLRU(vmesa
, t
);
487 numLevels
= t
->lastLevel
- t
->firstLevel
+ 1;
489 for (i
= 0; i
< numLevels
; i
++)
490 if (t
->dirtyImages
& (1 << i
))
491 viaUploadTexLevel(t
, i
);
495 UNLOCK_HARDWARE(vmesa
);
497 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);