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"
45 #define ALIGN(value, align) (GLubyte *)((long)(value + align - 1) & ~(align - 1))
47 #define TEXTURE_HW_ALIGNMENT 4
48 #define TEXTURE_HW_PLUS (4 + 4)
51 sisAllocTexObj( struct gl_texture_object
*texObj
)
55 t
= (sisTexObjPtr
) CALLOC_STRUCT( sis_tex_obj
);
56 texObj
->DriverData
= t
;
61 sisAllocTexImage( sisContextPtr smesa
, sisTexObjPtr t
, int level
,
62 const struct gl_texture_image
*image
)
68 t
->format
= image
->_BaseFormat
;
69 switch (image
->TexFormat
->MesaFormat
)
71 case MESA_FORMAT_ARGB8888
:
72 t
->hwformat
= TEXEL_ARGB_8888_32
;
74 case MESA_FORMAT_ARGB4444
:
75 t
->hwformat
= TEXEL_ARGB_4444_16
;
77 case MESA_FORMAT_ARGB1555
:
78 t
->hwformat
= TEXEL_ARGB_1555_16
;
80 case MESA_FORMAT_RGB565
:
81 t
->hwformat
= TEXEL_RGB_565_16
;
83 case MESA_FORMAT_RGB332
:
84 t
->hwformat
= TEXEL_RGB_332_8
;
87 t
->hwformat
= TEXEL_I8
;
90 t
->hwformat
= TEXEL_A8
;
93 t
->hwformat
= TEXEL_L8
;
95 case MESA_FORMAT_AL88
:
96 t
->hwformat
= TEXEL_AL88
;
98 case MESA_FORMAT_YCBCR
:
99 t
->hwformat
= TEXEL_YUV422
;
101 case MESA_FORMAT_YCBCR_REV
:
102 t
->hwformat
= TEXEL_VUY422
;
105 sis_fatal_error("Bad texture format 0x%x.\n",
106 image
->TexFormat
->MesaFormat
);
109 assert(t
->format
== image
->_BaseFormat
);
111 texel_size
= image
->TexFormat
->TexelBytes
;
112 size
= image
->Width
* image
->Height
* texel_size
+ TEXTURE_HW_PLUS
;
114 addr
= sisAllocFB( smesa
, size
, &t
->image
[level
].handle
);
116 addr
= sisAllocAGP( smesa
, size
, &t
->image
[level
].handle
);
118 sis_fatal_error("Failure to allocate texture memory.\n");
119 t
->image
[level
].memType
= AGP_TYPE
;
122 t
->image
[level
].memType
= VIDEO_TYPE
;
124 t
->image
[level
].Data
= ALIGN(addr
, TEXTURE_HW_ALIGNMENT
);
125 t
->image
[level
].pitch
= image
->Width
* texel_size
;
126 t
->image
[level
].size
= image
->Width
* image
->Height
* texel_size
;
131 sisFreeTexImage( sisContextPtr smesa
, sisTexObjPtr t
, int level
)
134 assert(level
< SIS_MAX_TEXTURE_LEVELS
);
135 if (t
->image
[level
].Data
== NULL
)
138 switch (t
->image
[level
].memType
)
141 sisFreeFB( smesa
, t
->image
[level
].handle
);
144 sisFreeAGP( smesa
, t
->image
[level
].handle
);
147 t
->image
[level
].Data
= NULL
;
148 t
->image
[level
].handle
= NULL
;
149 /* If there are no textures loaded any more, reset the hw format so the
150 * object can be reused for new formats
153 if (t
->numImages
== 0) {
160 sisTexEnv( GLcontext
*ctx
, GLenum target
, GLenum pname
, const GLfloat
*param
)
162 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
164 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
168 sisTexParameter( GLcontext
*ctx
, GLenum target
,
169 struct gl_texture_object
*texObj
, GLenum pname
,
170 const GLfloat
*params
)
172 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
174 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
178 sisBindTexture( GLcontext
*ctx
, GLenum target
,
179 struct gl_texture_object
*texObj
)
181 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
184 if ( target
== GL_TEXTURE_2D
|| target
== GL_TEXTURE_1D
) {
185 if ( texObj
->DriverData
== NULL
) {
186 sisAllocTexObj( texObj
);
190 t
= texObj
->DriverData
;
194 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
) {
195 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
196 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
198 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
202 sisDeleteTexture( GLcontext
* ctx
, struct gl_texture_object
*texObj
)
204 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
208 smesa
->clearTexCache
= GL_TRUE
;
210 t
= texObj
->DriverData
;
213 * this shows the texture is default object and never be a
214 * argument of sisTexImage*
218 for (i
= 0; i
< SIS_MAX_TEXTURE_LEVELS
; i
++) {
219 sisFreeTexImage( smesa
, t
, i
);
223 texObj
->DriverData
= NULL
;
224 /* Free mipmap images and the texture object itself */
225 _mesa_delete_texture_object(ctx
, texObj
);
228 static GLboolean
sisIsTextureResident( GLcontext
* ctx
,
229 struct gl_texture_object
*texObj
)
231 return (texObj
->DriverData
!= NULL
);
234 static const struct gl_texture_format
*
235 sisChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
236 GLenum format
, GLenum type
)
238 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
240 const GLboolean do32bpt
=
241 (smesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
242 const GLboolean force16bpt
=
243 (smesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
245 switch ( internalFormat
) {
248 case GL_COMPRESSED_RGBA
:
250 case GL_UNSIGNED_INT_10_10_10_2
:
251 case GL_UNSIGNED_INT_2_10_10_10_REV
:
252 return do32bpt
? &_mesa_texformat_argb8888
: &_mesa_texformat_argb1555
;
253 case GL_UNSIGNED_SHORT_4_4_4_4
:
254 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
255 return &_mesa_texformat_argb4444
;
256 case GL_UNSIGNED_SHORT_5_5_5_1
:
257 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
258 return &_mesa_texformat_argb1555
;
260 return do32bpt
? &_mesa_texformat_argb8888
: &_mesa_texformat_argb4444
;
265 case GL_COMPRESSED_RGB
:
267 case GL_UNSIGNED_SHORT_4_4_4_4
:
268 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
269 return &_mesa_texformat_argb4444
;
270 case GL_UNSIGNED_SHORT_5_5_5_1
:
271 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
272 return &_mesa_texformat_argb1555
;
273 case GL_UNSIGNED_SHORT_5_6_5
:
274 case GL_UNSIGNED_SHORT_5_6_5_REV
:
275 return &_mesa_texformat_rgb565
;
277 return do32bpt
? &_mesa_texformat_argb8888
: &_mesa_texformat_rgb565
;
284 &_mesa_texformat_argb8888
: &_mesa_texformat_argb4444
;
288 &_mesa_texformat_argb8888
: &_mesa_texformat_argb1555
;
292 return &_mesa_texformat_argb4444
;
295 return &_mesa_texformat_argb1555
;
301 return !force16bpt
? &_mesa_texformat_argb8888
: &_mesa_texformat_rgb565
;
305 return &_mesa_texformat_rgb565
;
308 return &_mesa_texformat_rgb332
;
311 case GL_ALPHA4
: /* FIXME: This could use its own texstore */
315 case GL_COMPRESSED_ALPHA
:
316 return &_mesa_texformat_a8
;
320 case GL_LUMINANCE4
: /* FIXME: This could use its own texstore */
324 case GL_COMPRESSED_LUMINANCE
:
325 return &_mesa_texformat_l8
;
328 case GL_LUMINANCE_ALPHA
:
329 case GL_LUMINANCE4_ALPHA4
: /* FIXME: This could use its own texstore */
330 case GL_LUMINANCE6_ALPHA2
: /* FIXME: This could use its own texstore */
331 case GL_LUMINANCE8_ALPHA8
:
332 case GL_LUMINANCE12_ALPHA4
: /* FIXME: This could use its own texstore */
333 case GL_LUMINANCE12_ALPHA12
:
334 case GL_LUMINANCE16_ALPHA16
:
335 case GL_COMPRESSED_LUMINANCE_ALPHA
:
336 return &_mesa_texformat_al88
;
343 case GL_COMPRESSED_INTENSITY
:
344 return &_mesa_texformat_i8
;
347 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
348 type
== GL_UNSIGNED_BYTE
)
349 return &_mesa_texformat_ycbcr
;
351 return &_mesa_texformat_ycbcr_rev
;
354 _mesa_problem(ctx
, "unexpected format in sisDDChooseTextureFormat: %d",
360 static void sisTexImage1D( GLcontext
*ctx
, GLenum target
, GLint level
,
361 GLint internalFormat
,
362 GLint width
, 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_teximage1d( ctx
, target
, level
, internalFormat
,
377 width
, border
, format
, type
,
378 pixels
, packing
, texObj
, texImage
);
380 /* Allocate offscreen space for the texture */
381 sisFreeTexImage(smesa
, t
, level
);
382 sisAllocTexImage(smesa
, t
, level
, texImage
);
384 /* Upload the texture */
386 memcpy(t
->image
[level
].Data
, texImage
->Data
, t
->image
[level
].size
);
388 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
390 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
391 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
393 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
397 static void sisTexSubImage1D( GLcontext
*ctx
,
402 GLenum format
, GLenum type
,
403 const GLvoid
*pixels
,
404 const struct gl_pixelstore_attrib
*packing
,
405 struct gl_texture_object
*texObj
,
406 struct gl_texture_image
*texImage
)
408 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
415 if ( texObj
->DriverData
== NULL
)
416 sisAllocTexObj( texObj
);
417 t
= texObj
->DriverData
;
419 _mesa_store_texsubimage1d(ctx
, target
, level
, xoffset
, width
,
420 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 */
429 texelBytes
= texImage
->TexFormat
->TexelBytes
;
431 copySize
= width
* texelBytes
;
432 src
= (char *)texImage
->Data
+ xoffset
* texelBytes
;
433 dst
= t
->image
[level
].Data
+ xoffset
* texelBytes
;
435 memcpy( dst
, src
, copySize
);
437 smesa
->clearTexCache
= GL_TRUE
;
439 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
441 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
442 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
444 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
447 static void sisTexImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
448 GLint internalFormat
,
449 GLint width
, GLint height
, GLint border
,
450 GLenum format
, GLenum type
, const GLvoid
*pixels
,
451 const struct gl_pixelstore_attrib
*packing
,
452 struct gl_texture_object
*texObj
,
453 struct gl_texture_image
*texImage
)
455 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
458 if ( texObj
->DriverData
== NULL
)
459 sisAllocTexObj( texObj
);
460 t
= texObj
->DriverData
;
462 /* Note, this will call sisChooseTextureFormat */
463 _mesa_store_teximage2d(ctx
, target
, level
, internalFormat
,
464 width
, height
, border
, format
, type
, pixels
,
465 &ctx
->Unpack
, texObj
, texImage
);
467 /* Allocate offscreen space for the texture */
468 sisFreeTexImage(smesa
, t
, level
);
469 sisAllocTexImage(smesa
, t
, level
, texImage
);
471 /* Upload the texture */
473 memcpy(t
->image
[level
].Data
, texImage
->Data
, t
->image
[level
].size
);
475 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
477 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
478 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
480 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
483 static void sisTexSubImage2D( GLcontext
*ctx
,
486 GLint xoffset
, GLint yoffset
,
487 GLsizei width
, GLsizei height
,
488 GLenum format
, GLenum type
,
489 const GLvoid
*pixels
,
490 const struct gl_pixelstore_attrib
*packing
,
491 struct gl_texture_object
*texObj
,
492 struct gl_texture_image
*texImage
)
494 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
503 if ( texObj
->DriverData
== NULL
)
504 sisAllocTexObj( texObj
);
505 t
= texObj
->DriverData
;
507 _mesa_store_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
508 height
, format
, type
, pixels
, packing
, texObj
,
511 /* Allocate offscreen space for the texture */
512 sisFreeTexImage(smesa
, t
, level
);
513 sisAllocTexImage(smesa
, t
, level
, texImage
);
515 /* Upload the texture */
517 texelBytes
= texImage
->TexFormat
->TexelBytes
;
519 copySize
= width
* texelBytes
;
520 src
= (char *)texImage
->Data
+ (xoffset
+ yoffset
* texImage
->Width
) *
522 dst
= t
->image
[level
].Data
+ (xoffset
+ yoffset
* texImage
->Width
) *
524 soffset
= texImage
->Width
* texelBytes
;
526 for (j
= yoffset
; j
< yoffset
+ height
; j
++) {
527 memcpy( dst
, src
, copySize
);
532 smesa
->clearTexCache
= GL_TRUE
;
534 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
536 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
537 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
539 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
544 * Allocate a new texture object.
545 * Called via ctx->Driver.NewTextureObject.
546 * Note: this function will be called during context creation to
547 * allocate the default texture objects.
548 * Note: we could use containment here to 'derive' the driver-specific
549 * texture object from the core mesa gl_texture_object. Not done at this time.
551 static struct gl_texture_object
*
552 sisNewTextureObject( GLcontext
*ctx
, GLuint name
, GLenum target
)
554 struct gl_texture_object
*obj
;
555 obj
= _mesa_new_texture_object(ctx
, name
, target
);
560 void sisInitTextureFuncs( struct dd_function_table
*functions
)
562 functions
->TexEnv
= sisTexEnv
;
563 functions
->ChooseTextureFormat
= sisChooseTextureFormat
;
564 functions
->TexImage1D
= sisTexImage1D
;
565 functions
->TexSubImage1D
= sisTexSubImage1D
;
566 functions
->TexImage2D
= sisTexImage2D
;
567 functions
->TexSubImage2D
= sisTexSubImage2D
;
568 functions
->TexParameter
= sisTexParameter
;
569 functions
->BindTexture
= sisBindTexture
;
570 functions
->NewTextureObject
= sisNewTextureObject
;
571 functions
->DeleteTexture
= sisDeleteTexture
;
572 functions
->IsTextureResident
= sisIsTextureResident
;