1 /**************************************************************************
3 Copyright 2003 Eric Anholt
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 on the rights to use, copy, modify, merge, publish, distribute, sub
10 license, and/or sell copies of the Software, and to permit persons to whom
11 the Software is furnished to do so, subject to the following conditions:
13 The above copyright notice and this permission notice (including the next
14 paragraph) shall be included in all copies or substantial portions of the
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20 ERIC ANHOLT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 **************************************************************************/
29 * Eric Anholt <anholt@FreeBSD.org>
32 #include "sis_context.h"
33 #include "sis_alloc.h"
36 #include "swrast/swrast.h"
38 #include "texformat.h"
42 #define ALIGN(value, align) (char *)((long)(value + align - 1) & ~(align - 1))
44 #define TEXTURE_HW_ALIGNMENT 4
45 #define TEXTURE_HW_PLUS (4 + 4)
48 sisAllocTexObj( struct gl_texture_object
*texObj
)
52 t
= (sisTexObjPtr
) CALLOC_STRUCT( sis_tex_obj
);
53 texObj
->DriverData
= t
;
58 sisAllocTexImage( sisContextPtr smesa
, sisTexObjPtr t
, int level
,
59 const struct gl_texture_image
*image
)
65 t
->format
= image
->Format
;
69 t
->hwformat
= TEXEL_ARGB_8888_32
;
72 t
->hwformat
= TEXEL_I8
;
75 t
->hwformat
= TEXEL_A8
;
78 t
->hwformat
= TEXEL_L8
;
80 case GL_LUMINANCE_ALPHA
:
81 t
->hwformat
= TEXEL_AL88
;
84 t
->hwformat
= TEXEL_ARGB_0888_32
;
90 assert(t
->format
== image
->Format
);
92 texel_size
= image
->TexFormat
->TexelBytes
;
93 size
= image
->Width
* image
->Height
* texel_size
+ TEXTURE_HW_PLUS
;
95 addr
= sisAllocFB( smesa
, size
, &t
->image
[level
].handle
);
97 addr
= sisAllocAGP( smesa
, size
, &t
->image
[level
].handle
);
99 fprintf (stderr
, "SIS driver : out of video/agp memory\n");
102 t
->image
[level
].memType
= AGP_TYPE
;
105 t
->image
[level
].memType
= VIDEO_TYPE
;
107 t
->image
[level
].Data
= ALIGN(addr
, TEXTURE_HW_ALIGNMENT
);
108 t
->image
[level
].pitch
= image
->Width
* texel_size
;
109 t
->image
[level
].size
= image
->Width
* image
->Height
* texel_size
;
114 sisFreeTexImage( sisContextPtr smesa
, sisTexObjPtr t
, int level
)
116 if (t
->image
[level
].Data
== NULL
)
119 switch (t
->image
[level
].memType
)
122 sisFreeFB( smesa
, t
->image
[level
].handle
);
125 sisFreeAGP( smesa
, t
->image
[level
].handle
);
128 t
->image
[level
].Data
= NULL
;
129 t
->image
[level
].handle
= NULL
;
130 /* If there are no textures loaded any more, reset the hw format so the
131 * object can be reused for new formats
134 if (t
->numImages
== 0) {
141 sisDDTexEnv( GLcontext
*ctx
, GLenum target
, GLenum pname
, const GLfloat
*param
)
143 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
145 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
149 sisDDTexParameter( GLcontext
*ctx
, GLenum target
,
150 struct gl_texture_object
*texObj
, GLenum pname
,
151 const GLfloat
*params
)
153 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
155 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
159 sisDDBindTexture( GLcontext
*ctx
, GLenum target
,
160 struct gl_texture_object
*texObj
)
162 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
165 if ( target
== GL_TEXTURE_2D
|| target
== GL_TEXTURE_1D
) {
166 if ( texObj
->DriverData
== NULL
) {
167 sisAllocTexObj( texObj
);
171 t
= texObj
->DriverData
;
176 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
) {
177 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
178 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
180 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
184 sisDDDeleteTexture( GLcontext
* ctx
, struct gl_texture_object
*texObj
)
186 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
190 smesa
->clearTexCache
= GL_TRUE
;
192 t
= texObj
->DriverData
;
195 * this shows the texture is default object and never be a
196 * argument of sisDDTexImage*
200 for (i
= 0; i
< MAX_TEXTURE_LEVELS
; i
++) {
201 sisFreeTexImage( smesa
, t
, i
);
205 texObj
->DriverData
= NULL
;
208 static GLboolean
sisDDIsTextureResident( GLcontext
* ctx
,
209 struct gl_texture_object
*texObj
)
211 return (texObj
->DriverData
!= NULL
);
214 static const struct gl_texture_format
*
215 sisDDChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
216 GLenum format
, GLenum type
)
218 /* XXX 16-bit internal texture formats? */
219 switch ( internalFormat
) {
225 return &_mesa_texformat_a8
;
232 return &_mesa_texformat_l8
;
234 case GL_LUMINANCE_ALPHA
:
235 case GL_LUMINANCE4_ALPHA4
:
236 case GL_LUMINANCE6_ALPHA2
:
237 case GL_LUMINANCE8_ALPHA8
:
238 case GL_LUMINANCE12_ALPHA4
:
239 case GL_LUMINANCE12_ALPHA12
:
240 case GL_LUMINANCE16_ALPHA16
:
241 return &_mesa_texformat_al88
;
247 return &_mesa_texformat_i8
;
257 return &_mesa_texformat_argb8888
/*_mesa_texformat_rgb888*/; /* XXX */
267 return &_mesa_texformat_argb8888
;
269 _mesa_problem(ctx
, "unexpected format in tdfxDDChooseTextureFormat: %d",
275 static void sisDDTexImage1D( GLcontext
*ctx
, GLenum target
, GLint level
,
276 GLint internalFormat
,
277 GLint width
, GLint border
,
278 GLenum format
, GLenum type
, const GLvoid
*pixels
,
279 const struct gl_pixelstore_attrib
*packing
,
280 struct gl_texture_object
*texObj
,
281 struct gl_texture_image
*texImage
)
283 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
286 if ( texObj
->DriverData
== NULL
)
287 sisAllocTexObj( texObj
);
288 t
= texObj
->DriverData
;
290 /* Note, this will call sisDDChooseTextureFormat */
291 _mesa_store_teximage1d( ctx
, target
, level
, internalFormat
,
292 width
, border
, format
, type
,
293 pixels
, packing
, texObj
, texImage
);
295 /* Allocate offscreen space for the texture */
296 sisFreeTexImage(smesa
, t
, level
);
297 sisAllocTexImage(smesa
, t
, level
, texImage
);
299 /* Upload the texture */
300 memcpy(t
->image
[level
].Data
, texImage
->Data
, t
->image
[level
].size
);
302 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
304 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
305 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
307 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
311 static void sisDDTexSubImage1D( GLcontext
*ctx
,
316 GLenum format
, GLenum type
,
317 const GLvoid
*pixels
,
318 const struct gl_pixelstore_attrib
*packing
,
319 struct gl_texture_object
*texObj
,
320 struct gl_texture_image
*texImage
)
322 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
328 if ( texObj
->DriverData
== NULL
)
329 sisAllocTexObj( texObj
);
330 t
= texObj
->DriverData
;
332 _mesa_store_texsubimage1d(ctx
, target
, level
, xoffset
, width
,
333 format
, type
, pixels
, packing
, texObj
,
336 /* Allocate offscreen space for the texture */
337 sisFreeTexImage(smesa
, t
, level
);
338 sisAllocTexImage(smesa
, t
, level
, texImage
);
340 /* Upload the texture */
341 texelBytes
= texImage
->TexFormat
->TexelBytes
;
343 copySize
= width
* texelBytes
;
344 src
= (char *)texImage
->Data
+ xoffset
* texelBytes
;
345 dst
= t
->image
[level
].Data
+ xoffset
* texelBytes
;
347 memcpy( dst
, src
, copySize
);
349 smesa
->clearTexCache
= GL_TRUE
;
351 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
353 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
354 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
356 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
359 static void sisDDTexImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
360 GLint internalFormat
,
361 GLint width
, GLint height
, GLint border
,
362 GLenum format
, GLenum type
, const GLvoid
*pixels
,
363 const struct gl_pixelstore_attrib
*packing
,
364 struct gl_texture_object
*texObj
,
365 struct gl_texture_image
*texImage
)
367 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
370 if ( texObj
->DriverData
== NULL
)
371 sisAllocTexObj( texObj
);
372 t
= texObj
->DriverData
;
374 /* Note, this will call sisDDChooseTextureFormat */
375 _mesa_store_teximage2d(ctx
, target
, level
, internalFormat
,
376 width
, height
, border
, format
, type
, pixels
,
377 &ctx
->Unpack
, texObj
, texImage
);
379 /* Allocate offscreen space for the texture */
380 sisFreeTexImage(smesa
, t
, level
);
381 sisAllocTexImage(smesa
, t
, level
, texImage
);
383 /* Upload the texture */
384 memcpy(t
->image
[level
].Data
, texImage
->Data
, t
->image
[level
].size
);
386 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
388 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
389 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
391 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
394 static void sisDDTexSubImage2D( GLcontext
*ctx
,
397 GLint xoffset
, GLint yoffset
,
398 GLsizei width
, GLsizei height
,
399 GLenum format
, GLenum type
,
400 const GLvoid
*pixels
,
401 const struct gl_pixelstore_attrib
*packing
,
402 struct gl_texture_object
*texObj
,
403 struct gl_texture_image
*texImage
)
405 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
413 if ( texObj
->DriverData
== NULL
)
414 sisAllocTexObj( texObj
);
415 t
= texObj
->DriverData
;
417 _mesa_store_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
418 height
, format
, type
, pixels
, packing
, texObj
,
421 /* Allocate offscreen space for the texture */
422 sisFreeTexImage(smesa
, t
, level
);
423 sisAllocTexImage(smesa
, t
, level
, texImage
);
425 /* Upload the texture */
426 texelBytes
= texImage
->TexFormat
->TexelBytes
;
428 copySize
= width
* texelBytes
;
429 src
= (char *)texImage
->Data
+ (xoffset
+ yoffset
* texImage
->Width
) *
431 dst
= t
->image
[level
].Data
+ (xoffset
+ yoffset
* texImage
->Width
) *
433 soffset
= texImage
->Width
* texelBytes
;
435 for (j
= yoffset
; j
< yoffset
+ height
; j
++) {
436 memcpy( dst
, src
, copySize
);
441 smesa
->clearTexCache
= GL_TRUE
;
443 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
445 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
446 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
448 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
452 void sisDDInitTextureFuncs( GLcontext
*ctx
)
454 ctx
->Driver
.TexEnv
= sisDDTexEnv
;
455 ctx
->Driver
.ChooseTextureFormat
= sisDDChooseTextureFormat
;
456 ctx
->Driver
.TexImage1D
= sisDDTexImage1D
;
457 ctx
->Driver
.TexSubImage1D
= sisDDTexSubImage1D
;
458 ctx
->Driver
.TexImage2D
= sisDDTexImage2D
;
459 ctx
->Driver
.TexSubImage2D
= sisDDTexSubImage2D
;
460 ctx
->Driver
.TexImage3D
= _mesa_store_teximage3d
;
461 ctx
->Driver
.TexSubImage3D
= _mesa_store_texsubimage3d
;
462 ctx
->Driver
.CopyTexImage1D
= _swrast_copy_teximage1d
;
463 ctx
->Driver
.CopyTexImage2D
= _swrast_copy_teximage2d
;
464 ctx
->Driver
.CopyTexSubImage1D
= _swrast_copy_texsubimage1d
;
465 ctx
->Driver
.CopyTexSubImage2D
= _swrast_copy_texsubimage2d
;
466 ctx
->Driver
.CopyTexSubImage3D
= _swrast_copy_texsubimage3d
;
467 ctx
->Driver
.TestProxyTexImage
= _mesa_test_proxy_teximage
;
468 ctx
->Driver
.TexParameter
= sisDDTexParameter
;
469 ctx
->Driver
.BindTexture
= sisDDBindTexture
;
470 ctx
->Driver
.DeleteTexture
= sisDDDeleteTexture
;
471 ctx
->Driver
.IsTextureResident
= sisDDIsTextureResident
;
472 ctx
->Driver
.PrioritizeTexture
= NULL
;