2 * GLX Hardware Device Driver for Intel i810
3 * Copyright (C) 1999 Keith Whitwell
4 * Texmem interface changes (C) 2003 Dave Airlie
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 #include "main/glheader.h"
27 #include "main/macros.h"
28 #include "main/mtypes.h"
29 #include "main/simple_list.h"
30 #include "main/enums.h"
31 #include "main/colormac.h"
34 #include "i810screen.h"
36 #include "i810context.h"
38 #include "i810ioctl.h"
41 void i810DestroyTexObj(i810ContextPtr imesa
, i810TextureObjectPtr t
)
43 /* See if it was the driver's current object.
45 if ( imesa
!= NULL
) {
46 if (imesa
->CurrentTexObj
[0] == t
) {
47 imesa
->CurrentTexObj
[0] = 0;
48 imesa
->dirty
&= ~I810_UPLOAD_TEX0
;
51 if (imesa
->CurrentTexObj
[1] == t
) {
52 imesa
->CurrentTexObj
[1] = 0;
53 imesa
->dirty
&= ~I810_UPLOAD_TEX1
;
60 #if defined(i386) || defined(__i386__)
61 /* From linux kernel i386 header files, copes with odd sizes better
62 * than COPY_DWORDS would:
64 static INLINE
void * __memcpy(void * to
, const void * from
, size_t n
)
72 "1:\ttestb $1,%b4\n\t"
76 : "=&c" (d0
), "=&D" (d1
), "=&S" (d2
)
77 :"0" (n
/4), "q" (n
),"1" ((long) to
),"2" ((long) from
)
82 /* Allow compilation on other architectures */
83 #define __memcpy memcpy
86 /* Upload an image from mesa's internal copy.
88 static void i810UploadTexLevel( i810ContextPtr imesa
,
89 i810TextureObjectPtr t
, int hwlevel
)
91 const struct gl_texture_image
*image
= t
->image
[hwlevel
].image
;
95 if (!image
|| !image
->Data
)
98 texelBytes
= _mesa_get_format_bytes(image
->TexFormat
);
100 if (image
->Width
* texelBytes
== t
->Pitch
) {
101 GLubyte
*dst
= (GLubyte
*)(t
->BufAddr
+ t
->image
[hwlevel
].offset
);
102 GLubyte
*src
= (GLubyte
*)image
->Data
;
104 memcpy( dst
, src
, t
->Pitch
* image
->Height
);
107 switch (texelBytes
) {
110 GLubyte
*dst
= (GLubyte
*)(t
->BufAddr
+ t
->image
[hwlevel
].offset
);
111 GLubyte
*src
= (GLubyte
*)image
->Data
;
113 for (j
= 0 ; j
< image
->Height
; j
++, dst
+= t
->Pitch
) {
114 __memcpy(dst
, src
, image
->Width
);
121 GLushort
*dst
= (GLushort
*)(t
->BufAddr
+ t
->image
[hwlevel
].offset
);
122 GLushort
*src
= (GLushort
*)image
->Data
;
124 for (j
= 0 ; j
< image
->Height
; j
++, dst
+= (t
->Pitch
/2)) {
125 __memcpy(dst
, src
, image
->Width
* 2 );
131 fprintf(stderr
, "%s: Not supported texel size %d\n",
132 __FUNCTION__
, texelBytes
);
137 /* This is called with the lock held. May have to eject our own and/or
138 * other client's texture objects to make room for the upload.
140 int i810UploadTexImagesLocked( i810ContextPtr imesa
, i810TextureObjectPtr t
)
146 /* Do we need to eject LRU texture objects?
148 if (!t
->base
.memBlock
) {
151 heap
= driAllocateTexture( imesa
->texture_heaps
, imesa
->nr_heaps
,
152 (driTextureObject
*) t
);
158 ofs
= t
->base
.memBlock
->ofs
;
159 t
->BufAddr
= imesa
->i810Screen
->tex
.map
+ ofs
;
160 t
->Setup
[I810_TEXREG_MI3
] = imesa
->i810Screen
->textureOffset
+ ofs
;
162 if (t
== imesa
->CurrentTexObj
[0])
163 I810_STATECHANGE(imesa
, I810_UPLOAD_TEX0
);
165 if (t
== imesa
->CurrentTexObj
[1])
166 I810_STATECHANGE(imesa
, I810_UPLOAD_TEX1
);
168 /* i810UpdateTexLRU( imesa, t );*/
170 driUpdateTextureLRU( (driTextureObject
*) t
);
172 if (imesa
->texture_heaps
[0]->timestamp
>= GET_DISPATCH_AGE(imesa
))
173 i810WaitAgeLocked( imesa
, imesa
->texture_heaps
[0]->timestamp
);
175 numLevels
= t
->base
.lastLevel
- t
->base
.firstLevel
+ 1;
176 for (i
= 0 ; i
< numLevels
; i
++)
177 if (t
->base
.dirty_images
[0] & (1<<i
))
178 i810UploadTexLevel( imesa
, t
, i
);
180 t
->base
.dirty_images
[0] = 0;