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 *=*/
44 void viaDestroyTexObj(viaContextPtr vmesa
, viaTextureObjectPtr t
)
46 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
50 /* This is sad - need to sync *in case* we upload a texture
51 * to this newly free memory...
54 via_free_texture(vmesa
, t
);
56 if (vmesa
&& t
->age
> vmesa
->dirtyAge
)
57 vmesa
->dirtyAge
= t
->age
;
61 t
->globj
->DriverData
= 0;
64 if (vmesa
->CurrentTexObj
[0] == t
) {
65 vmesa
->CurrentTexObj
[0] = 0;
68 if (vmesa
->CurrentTexObj
[1] == t
) {
69 vmesa
->CurrentTexObj
[1] = 0;
75 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
78 void viaSwapOutTexObj(viaContextPtr vmesa
, viaTextureObjectPtr t
)
80 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
82 via_free_texture(vmesa
, t
);
84 if (t
->age
> vmesa
->dirtyAge
)
85 vmesa
->dirtyAge
= t
->age
;
89 move_to_tail(&(vmesa
->SwappedOut
), t
);
90 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
93 /* Upload an image from mesa's internal copy.
95 static void viaUploadTexLevel(viaTextureObjectPtr t
, int level
)
97 const struct gl_texture_image
*image
= t
->image
[level
].image
;
100 fprintf(stderr
, "%s - in\n", __FUNCTION__
);
101 fprintf(stderr
, "width = %d, height = %d \n", image
->Width
, image
->Height
);
103 switch (t
->image
[level
].internalFormat
) {
106 if (image
->TexFormat
->MesaFormat
== MESA_FORMAT_ARGB8888
) {
107 GLuint
*dst
= (GLuint
*)(t
->bufAddr
+ t
->image
[level
].offset
);
108 GLuint
*src
= (GLuint
*)image
->Data
;
109 if (VIA_DEBUG
) fprintf(stderr
, "GL_RGB MESA_FORMAT_ARGB8888\n");
110 if (image
->Width
< 8) {
111 for (i
= 0; i
< image
->Height
; i
++) {
112 for (j
= 0; j
< image
->Width
; j
++) {
120 for (j
= 0; j
< image
->Height
* image
->Width
; j
++) {
126 /*memcpy(dst, src, image->Height * image->Width * sizeof(GLuint));*/
129 GLushort
*dst
= (GLushort
*)(t
->bufAddr
+ t
->image
[level
].offset
);
130 GLushort
*src
= (GLushort
*)image
->Data
;
131 if (VIA_DEBUG
) fprintf(stderr
, "GL_RGB !MESA_FORMAT_ARGB8888\n");
132 if (image
->Width
< 16) {
133 for (i
= 0; i
< image
->Height
; i
++) {
134 for (j
= 0; j
< image
->Width
; j
++) {
142 for (j
= 0; j
< image
->Height
* image
->Width
; j
++) {
148 /*memcpy(dst, src, image->Height * image->Width * sizeof(GLushort));*/
155 if (image
->TexFormat
->MesaFormat
== MESA_FORMAT_ARGB4444
) {
157 GLushort
*dst
= (GLushort
*)(t
->bufAddr
+ t
->image
[level
].offset
);
158 GLushort
*src
= (GLushort
*)image
->Data
;
159 if (image
->Width
< 16) {
160 for (i
= 0; i
< image
->Height
; i
++) {
161 for (j
= 0; j
< image
->Width
; j
++) {
169 for (j
= 0; j
< image
->Height
* image
->Width
; j
++) {
175 /*memcpy(dst, src, image->Height * image->Width * sizeof(GLushort));*/
176 if (VIA_DEBUG
) fprintf(stderr
, "GL_RGBA MESA_FORMAT_ARGB4444\n");
178 else if(image
->TexFormat
->MesaFormat
== MESA_FORMAT_ARGB8888
) {
179 GLuint
*dst
= (GLuint
*)(t
->bufAddr
+ t
->image
[level
].offset
);
180 GLuint
*src
= (GLuint
*)image
->Data
;
181 if (VIA_DEBUG
) fprintf(stderr
, "GL_RGBA !MESA_FORMAT_ARGB4444\n");
182 if (image
->Width
< 8) {
183 for (i
= 0; i
< image
->Height
; i
++) {
184 for (j
= 0; j
< image
->Width
; j
++) {
192 for (j
= 0; j
< image
->Height
* image
->Width
; j
++) {
198 /*memcpy(dst, src, image->Height * image->Width * sizeof(GLuint));*/
200 else if(image
->TexFormat
->MesaFormat
== MESA_FORMAT_ARGB1555
) {
201 GLushort
*dst
= (GLushort
*)(t
->bufAddr
+ t
->image
[level
].offset
);
202 GLushort
*src
= (GLushort
*)image
->Data
;
203 if (image
->Width
< 16) {
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(GLushort));*/
220 if (VIA_DEBUG
) fprintf(stderr
, "GL_RGBA MESA_FORMAT_ARGB1555\n");
227 GLubyte
*dst
= (GLubyte
*)(t
->bufAddr
+ t
->image
[level
].offset
);
228 GLubyte
*src
= (GLubyte
*)image
->Data
;
230 for (j
= 0; j
< image
->Height
* image
->Width
; j
++) {
240 GLubyte
*dst
= (GLubyte
*)(t
->bufAddr
+ t
->image
[level
].offset
);
241 GLubyte
*src
= (GLubyte
*)image
->Data
;
243 for (j
= 0; j
< image
->Height
* image
->Width
; j
++) {
251 case GL_LUMINANCE_ALPHA
:
253 GLushort
*dst
= (GLushort
*)(t
->bufAddr
+ t
->image
[level
].offset
);
254 GLushort
*src
= (GLushort
*)image
->Data
;
256 for (j
= 0; j
< image
->Height
* image
->Width
; j
++) {
266 GLubyte
*dst
= (GLubyte
*)(t
->bufAddr
+ t
->image
[level
].offset
);
267 GLubyte
*src
= (GLubyte
*)image
->Data
;
269 for (j
= 0; j
< image
->Height
* image
->Width
; j
++) {
277 /* TODO: Translate color indices *now*:
281 GLubyte
*dst
= (GLubyte
*)(t
->bufAddr
+ t
->image
[level
].offset
);
282 GLubyte
*src
= (GLubyte
*)image
->Data
;
284 for (j
= 0; j
< image
->Height
* image
->Width
; j
++) {
293 if (VIA_DEBUG
) fprintf(stderr
, "Not supported texture format %s\n",
294 _mesa_lookup_enum_by_nr(image
->Format
));
296 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
299 void viaPrintLocalLRU(viaContextPtr vmesa
)
301 viaTextureObjectPtr t
;
303 foreach (t
, &vmesa
->TexObjList
) {
306 fprintf(stderr
, "offset = %x, index = %x, size = %x\n",
313 fprintf(stderr
, "offset = %x, siez = %x\n",
322 void viaPrintGlobalLRU(viaContextPtr vmesa
)
325 drm_via_tex_region_t
*list
= vmesa
->sarea
->texList
;
327 for (i
= 0, j
= VIA_NR_TEX_REGIONS
; i
< VIA_NR_TEX_REGIONS
; i
++) {
328 if (VIA_DEBUG
) fprintf(stderr
, "list[%d] age %d next %d prev %d\n",
329 j
, list
[j
].age
, list
[j
].next
, list
[j
].prev
);
331 if (j
== VIA_NR_TEX_REGIONS
) break;
333 if (j
!= VIA_NR_TEX_REGIONS
)
334 if (VIA_DEBUG
) fprintf(stderr
, "Loop detected in global LRU\n");
337 void viaResetGlobalLRU(viaContextPtr vmesa
)
339 drm_via_tex_region_t
*list
= vmesa
->sarea
->texList
;
340 int sz
= 1 << vmesa
->viaScreen
->logTextureGranularity
;
343 /* (Re)initialize the global circular LRU list. The last element
344 * in the array (VIA_NR_TEX_REGIONS) is the sentinal. Keeping it
345 * at the end of the array allows it to be addressed rationally
346 * when looking up objects at a particular location in texture
349 for (i
= 0; (i
+ 1) * sz
<= vmesa
->viaScreen
->textureSize
; i
++) {
350 list
[i
].prev
= i
- 1;
351 list
[i
].next
= i
+ 1;
356 list
[0].prev
= VIA_NR_TEX_REGIONS
;
357 list
[i
].prev
= i
- 1;
358 list
[i
].next
= VIA_NR_TEX_REGIONS
;
359 list
[VIA_NR_TEX_REGIONS
].prev
= i
;
360 list
[VIA_NR_TEX_REGIONS
].next
= 0;
361 vmesa
->sarea
->texAge
= 0;
364 void viaUpdateTexLRU(viaContextPtr vmesa
, viaTextureObjectPtr t
)
366 vmesa
->texAge
= ++vmesa
->sarea
->texAge
;
367 move_to_head(&(vmesa
->TexObjList
), t
);
370 /* Called for every shared texture region which has increased in age
371 * since we last held the lock.
373 * Figures out which of our textures have been ejected by other clients,
374 * and pushes a placeholder texture onto the LRU list to represent
375 * the other client's textures.
377 void viaTexturesGone(viaContextPtr vmesa
,
382 viaTextureObjectPtr t
, tmp
;
383 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
384 foreach_s (t
, tmp
, &vmesa
->TexObjList
) {
385 viaSwapOutTexObj(vmesa
, t
);
387 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
390 /* This is called with the lock held. May have to eject our own and/or
391 * other client's texture objects to make room for the upload.
393 void viaUploadTexImages(viaContextPtr vmesa
, viaTextureObjectPtr t
)
397 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
398 LOCK_HARDWARE(vmesa
);
404 /*=* John Sheng [2003.5.31] agp tex *=*/
405 if (via_alloc_texture_agp(vmesa
, t
))
407 if (via_alloc_texture(vmesa
, t
))
410 vmesa
->agpFullCount
++;
411 if (vmesa
->TexObjList
.prev
== vmesa
->CurrentTexObj
[0] ||
412 vmesa
->TexObjList
.prev
== vmesa
->CurrentTexObj
[1]) {
413 if (VIA_DEBUG
) fprintf(stderr
, "Hit bound texture in upload\n");
414 viaPrintLocalLRU(vmesa
);
415 UNLOCK_HARDWARE(vmesa
);
419 if (vmesa
->TexObjList
.prev
== &(vmesa
->TexObjList
)) {
420 if (VIA_DEBUG
) fprintf(stderr
, "Failed to upload texture, sz %d\n", t
->totalSize
);
421 mmDumpMemInfo(vmesa
->texHeap
);
422 UNLOCK_HARDWARE(vmesa
);
426 viaSwapOutTexObj(vmesa
, vmesa
->TexObjList
.prev
);
428 /*=* John Sheng [2003.5.31] agp tex *=*/
429 /*t->bufAddr = (char *)((GLuint)vmesa->driScreen->pFB + t->texMem.offset);*/
431 if (t
== vmesa
->CurrentTexObj
[0])
432 VIA_FLUSH_DMA(vmesa
);
434 if (t
== vmesa
->CurrentTexObj
[1])
435 VIA_FLUSH_DMA(vmesa
);
437 viaUpdateTexLRU(vmesa
, t
);
442 numLevels
= t
->lastLevel
- t
->firstLevel
+ 1;
444 for (i
= 0; i
< numLevels
; i
++)
445 if (t
->dirtyImages
& (1 << i
))
446 viaUploadTexLevel(t
, i
);
449 vmesa
->clearTexCache
= 1;
451 UNLOCK_HARDWARE(vmesa
);
452 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);