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"
43 #define ALIGN(value, align) (GLubyte *)((long)(value + align - 1) & ~(align - 1))
45 #define TEXTURE_HW_ALIGNMENT 4
46 #define TEXTURE_HW_PLUS (4 + 4)
49 sisAllocTexObj( struct gl_texture_object
*texObj
)
53 t
= (sisTexObjPtr
) CALLOC_STRUCT( sis_tex_obj
);
54 texObj
->DriverData
= t
;
59 sisAllocTexImage( sisContextPtr smesa
, sisTexObjPtr t
, int level
,
60 const struct gl_texture_image
*image
)
66 t
->format
= image
->Format
;
70 t
->hwformat
= TEXEL_ARGB_8888_32
;
73 t
->hwformat
= TEXEL_I8
;
76 t
->hwformat
= TEXEL_A8
;
79 t
->hwformat
= TEXEL_L8
;
81 case GL_LUMINANCE_ALPHA
:
82 t
->hwformat
= TEXEL_AL88
;
85 t
->hwformat
= TEXEL_ARGB_0888_32
;
88 sis_fatal_error("Bad texture format.\n");
91 assert(t
->format
== image
->Format
);
93 texel_size
= image
->TexFormat
->TexelBytes
;
94 size
= image
->Width
* image
->Height
* texel_size
+ TEXTURE_HW_PLUS
;
96 addr
= sisAllocFB( smesa
, size
, &t
->image
[level
].handle
);
98 addr
= sisAllocAGP( smesa
, size
, &t
->image
[level
].handle
);
100 sis_fatal_error("Failure to allocate texture memory.\n");
101 t
->image
[level
].memType
= AGP_TYPE
;
104 t
->image
[level
].memType
= VIDEO_TYPE
;
106 t
->image
[level
].Data
= ALIGN(addr
, TEXTURE_HW_ALIGNMENT
);
107 t
->image
[level
].pitch
= image
->Width
* texel_size
;
108 t
->image
[level
].size
= image
->Width
* image
->Height
* texel_size
;
113 sisFreeTexImage( sisContextPtr smesa
, sisTexObjPtr t
, int level
)
115 if (t
->image
[level
].Data
== NULL
)
118 switch (t
->image
[level
].memType
)
121 sisFreeFB( smesa
, t
->image
[level
].handle
);
124 sisFreeAGP( smesa
, t
->image
[level
].handle
);
127 t
->image
[level
].Data
= NULL
;
128 t
->image
[level
].handle
= NULL
;
129 /* If there are no textures loaded any more, reset the hw format so the
130 * object can be reused for new formats
133 if (t
->numImages
== 0) {
140 sisTexEnv( GLcontext
*ctx
, GLenum target
, GLenum pname
, const GLfloat
*param
)
142 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
144 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
148 sisTexParameter( GLcontext
*ctx
, GLenum target
,
149 struct gl_texture_object
*texObj
, GLenum pname
,
150 const GLfloat
*params
)
152 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
154 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
158 sisBindTexture( GLcontext
*ctx
, GLenum target
,
159 struct gl_texture_object
*texObj
)
161 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
164 if ( target
== GL_TEXTURE_2D
|| target
== GL_TEXTURE_1D
) {
165 if ( texObj
->DriverData
== NULL
) {
166 sisAllocTexObj( texObj
);
170 t
= texObj
->DriverData
;
174 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
) {
175 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
176 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
178 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
182 sisDeleteTexture( GLcontext
* ctx
, struct gl_texture_object
*texObj
)
184 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
188 smesa
->clearTexCache
= GL_TRUE
;
190 t
= texObj
->DriverData
;
193 * this shows the texture is default object and never be a
194 * argument of sisTexImage*
198 for (i
= 0; i
< MAX_TEXTURE_LEVELS
; i
++) {
199 sisFreeTexImage( smesa
, t
, i
);
203 texObj
->DriverData
= NULL
;
204 /* Free mipmap images and the texture object itself */
205 _mesa_delete_texture_object(ctx
, texObj
);
208 static GLboolean
sisIsTextureResident( GLcontext
* ctx
,
209 struct gl_texture_object
*texObj
)
211 return (texObj
->DriverData
!= NULL
);
214 static const struct gl_texture_format
*
215 sisChooseTextureFormat( 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 sisTexImage1D( 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 sisChooseTextureFormat */
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 sisTexSubImage1D( 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
);
329 if ( texObj
->DriverData
== NULL
)
330 sisAllocTexObj( texObj
);
331 t
= texObj
->DriverData
;
333 _mesa_store_texsubimage1d(ctx
, target
, level
, xoffset
, width
,
334 format
, type
, pixels
, packing
, texObj
,
337 /* Allocate offscreen space for the texture */
338 sisFreeTexImage(smesa
, t
, level
);
339 sisAllocTexImage(smesa
, t
, level
, texImage
);
341 /* Upload the texture */
342 texelBytes
= texImage
->TexFormat
->TexelBytes
;
344 copySize
= width
* texelBytes
;
345 src
= (char *)texImage
->Data
+ xoffset
* texelBytes
;
346 dst
= t
->image
[level
].Data
+ xoffset
* texelBytes
;
348 memcpy( dst
, src
, copySize
);
350 smesa
->clearTexCache
= GL_TRUE
;
352 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
354 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
355 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
357 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
360 static void sisTexImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
361 GLint internalFormat
,
362 GLint width
, GLint height
, GLint border
,
363 GLenum format
, GLenum type
, const GLvoid
*pixels
,
364 const struct gl_pixelstore_attrib
*packing
,
365 struct gl_texture_object
*texObj
,
366 struct gl_texture_image
*texImage
)
368 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
371 if ( texObj
->DriverData
== NULL
)
372 sisAllocTexObj( texObj
);
373 t
= texObj
->DriverData
;
375 /* Note, this will call sisChooseTextureFormat */
376 _mesa_store_teximage2d(ctx
, target
, level
, internalFormat
,
377 width
, height
, border
, format
, type
, pixels
,
378 &ctx
->Unpack
, texObj
, texImage
);
380 /* Allocate offscreen space for the texture */
381 sisFreeTexImage(smesa
, t
, level
);
382 sisAllocTexImage(smesa
, t
, level
, texImage
);
384 /* Upload the texture */
385 memcpy(t
->image
[level
].Data
, texImage
->Data
, t
->image
[level
].size
);
387 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
389 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
390 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
392 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
395 static void sisTexSubImage2D( GLcontext
*ctx
,
398 GLint xoffset
, GLint yoffset
,
399 GLsizei width
, GLsizei height
,
400 GLenum format
, GLenum type
,
401 const GLvoid
*pixels
,
402 const struct gl_pixelstore_attrib
*packing
,
403 struct gl_texture_object
*texObj
,
404 struct gl_texture_image
*texImage
)
406 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
415 if ( texObj
->DriverData
== NULL
)
416 sisAllocTexObj( texObj
);
417 t
= texObj
->DriverData
;
419 _mesa_store_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
420 height
, format
, type
, pixels
, packing
, texObj
,
423 /* Allocate offscreen space for the texture */
424 sisFreeTexImage(smesa
, t
, level
);
425 sisAllocTexImage(smesa
, t
, level
, texImage
);
427 /* Upload the texture */
428 texelBytes
= texImage
->TexFormat
->TexelBytes
;
430 copySize
= width
* texelBytes
;
431 src
= (char *)texImage
->Data
+ (xoffset
+ yoffset
* texImage
->Width
) *
433 dst
= t
->image
[level
].Data
+ (xoffset
+ yoffset
* texImage
->Width
) *
435 soffset
= texImage
->Width
* texelBytes
;
437 for (j
= yoffset
; j
< yoffset
+ height
; j
++) {
438 memcpy( dst
, src
, copySize
);
443 smesa
->clearTexCache
= GL_TRUE
;
445 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
447 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
448 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
450 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
455 * Allocate a new texture object.
456 * Called via ctx->Driver.NewTextureObject.
457 * Note: this function will be called during context creation to
458 * allocate the default texture objects.
459 * Note: we could use containment here to 'derive' the driver-specific
460 * texture object from the core mesa gl_texture_object. Not done at this time.
462 static struct gl_texture_object
*
463 sisNewTextureObject( GLcontext
*ctx
, GLuint name
, GLenum target
)
465 struct gl_texture_object
*obj
;
466 obj
= _mesa_new_texture_object(ctx
, name
, target
);
471 void sisInitTextureFuncs( struct dd_function_table
*functions
)
473 functions
->TexEnv
= sisTexEnv
;
474 functions
->ChooseTextureFormat
= sisChooseTextureFormat
;
475 functions
->TexImage1D
= sisTexImage1D
;
476 functions
->TexSubImage1D
= sisTexSubImage1D
;
477 functions
->TexImage2D
= sisTexImage2D
;
478 functions
->TexSubImage2D
= sisTexSubImage2D
;
479 functions
->TexParameter
= sisTexParameter
;
480 functions
->BindTexture
= sisBindTexture
;
481 functions
->NewTextureObject
= sisNewTextureObject
;
482 functions
->DeleteTexture
= sisDeleteTexture
;
483 functions
->IsTextureResident
= sisIsTextureResident
;