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 **************************************************************************/
28 * Eric Anholt <anholt@FreeBSD.org>
31 #include "sis_context.h"
32 #include "sis_alloc.h"
35 #include "swrast/swrast.h"
36 #include "main/imports.h"
37 #include "main/texformat.h"
38 #include "main/texstore.h"
39 #include "main/teximage.h"
40 #include "main/texobj.h"
44 #define ALIGN(value, align) (GLubyte *)((long)(value + align - 1) & ~(align - 1))
46 #define TEXTURE_HW_ALIGNMENT 4
47 #define TEXTURE_HW_PLUS (4 + 4)
50 sisAllocTexObj( struct gl_texture_object
*texObj
)
54 t
= (sisTexObjPtr
) CALLOC_STRUCT( sis_tex_obj
);
55 texObj
->DriverData
= t
;
60 sisAllocTexImage( sisContextPtr smesa
, sisTexObjPtr t
, int level
,
61 const struct gl_texture_image
*image
)
67 t
->format
= image
->_BaseFormat
;
68 switch (image
->TexFormat
->MesaFormat
)
70 case MESA_FORMAT_ARGB8888
:
71 t
->hwformat
= TEXEL_ARGB_8888_32
;
73 case MESA_FORMAT_ARGB4444
:
74 t
->hwformat
= TEXEL_ARGB_4444_16
;
76 case MESA_FORMAT_ARGB1555
:
77 t
->hwformat
= TEXEL_ARGB_1555_16
;
79 case MESA_FORMAT_RGB565
:
80 t
->hwformat
= TEXEL_RGB_565_16
;
82 case MESA_FORMAT_RGB332
:
83 t
->hwformat
= TEXEL_RGB_332_8
;
86 t
->hwformat
= TEXEL_I8
;
89 t
->hwformat
= TEXEL_A8
;
92 t
->hwformat
= TEXEL_L8
;
94 case MESA_FORMAT_AL88
:
95 t
->hwformat
= TEXEL_AL88
;
97 case MESA_FORMAT_YCBCR
:
98 t
->hwformat
= TEXEL_YUV422
;
100 case MESA_FORMAT_YCBCR_REV
:
101 t
->hwformat
= TEXEL_VUY422
;
104 sis_fatal_error("Bad texture format 0x%x.\n",
105 image
->TexFormat
->MesaFormat
);
108 assert(t
->format
== image
->_BaseFormat
);
110 texel_size
= image
->TexFormat
->TexelBytes
;
111 size
= image
->Width
* image
->Height
* texel_size
+ TEXTURE_HW_PLUS
;
113 addr
= sisAllocFB( smesa
, size
, &t
->image
[level
].handle
);
115 addr
= sisAllocAGP( smesa
, size
, &t
->image
[level
].handle
);
117 sis_fatal_error("Failure to allocate texture memory.\n");
118 t
->image
[level
].memType
= AGP_TYPE
;
121 t
->image
[level
].memType
= VIDEO_TYPE
;
123 t
->image
[level
].Data
= ALIGN(addr
, TEXTURE_HW_ALIGNMENT
);
124 t
->image
[level
].pitch
= image
->Width
* texel_size
;
125 t
->image
[level
].size
= image
->Width
* image
->Height
* texel_size
;
130 sisFreeTexImage( sisContextPtr smesa
, sisTexObjPtr t
, int level
)
133 assert(level
< SIS_MAX_TEXTURE_LEVELS
);
134 if (t
->image
[level
].Data
== NULL
)
137 switch (t
->image
[level
].memType
)
140 sisFreeFB( smesa
, t
->image
[level
].handle
);
143 sisFreeAGP( smesa
, t
->image
[level
].handle
);
146 t
->image
[level
].Data
= NULL
;
147 t
->image
[level
].handle
= NULL
;
148 /* If there are no textures loaded any more, reset the hw format so the
149 * object can be reused for new formats
152 if (t
->numImages
== 0) {
159 sisTexEnv( GLcontext
*ctx
, GLenum target
, GLenum pname
, const GLfloat
*param
)
161 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
163 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
167 sisTexParameter( GLcontext
*ctx
, GLenum target
,
168 struct gl_texture_object
*texObj
, GLenum pname
,
169 const GLfloat
*params
)
171 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
173 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
177 sisBindTexture( GLcontext
*ctx
, GLenum target
,
178 struct gl_texture_object
*texObj
)
180 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
183 if ( target
== GL_TEXTURE_2D
|| target
== GL_TEXTURE_1D
) {
184 if ( texObj
->DriverData
== NULL
) {
185 sisAllocTexObj( texObj
);
189 t
= texObj
->DriverData
;
193 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
) {
194 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
195 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
197 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
201 sisDeleteTexture( GLcontext
* ctx
, struct gl_texture_object
*texObj
)
203 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
207 smesa
->clearTexCache
= GL_TRUE
;
209 t
= texObj
->DriverData
;
212 * this shows the texture is default object and never be a
213 * argument of sisTexImage*
217 for (i
= 0; i
< SIS_MAX_TEXTURE_LEVELS
; i
++) {
218 sisFreeTexImage( smesa
, t
, i
);
222 texObj
->DriverData
= NULL
;
223 /* Free mipmap images and the texture object itself */
224 _mesa_delete_texture_object(ctx
, texObj
);
227 static GLboolean
sisIsTextureResident( GLcontext
* ctx
,
228 struct gl_texture_object
*texObj
)
230 return (texObj
->DriverData
!= NULL
);
233 static const struct gl_texture_format
*
234 sisChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
235 GLenum format
, GLenum type
)
237 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
239 const GLboolean do32bpt
=
240 (smesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
241 const GLboolean force16bpt
=
242 (smesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
244 switch ( internalFormat
) {
247 case GL_COMPRESSED_RGBA
:
249 case GL_UNSIGNED_INT_10_10_10_2
:
250 case GL_UNSIGNED_INT_2_10_10_10_REV
:
251 return do32bpt
? &_mesa_texformat_argb8888
: &_mesa_texformat_argb1555
;
252 case GL_UNSIGNED_SHORT_4_4_4_4
:
253 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
254 return &_mesa_texformat_argb4444
;
255 case GL_UNSIGNED_SHORT_5_5_5_1
:
256 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
257 return &_mesa_texformat_argb1555
;
259 return do32bpt
? &_mesa_texformat_argb8888
: &_mesa_texformat_argb4444
;
264 case GL_COMPRESSED_RGB
:
266 case GL_UNSIGNED_SHORT_4_4_4_4
:
267 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
268 return &_mesa_texformat_argb4444
;
269 case GL_UNSIGNED_SHORT_5_5_5_1
:
270 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
271 return &_mesa_texformat_argb1555
;
272 case GL_UNSIGNED_SHORT_5_6_5
:
273 case GL_UNSIGNED_SHORT_5_6_5_REV
:
274 return &_mesa_texformat_rgb565
;
276 return do32bpt
? &_mesa_texformat_argb8888
: &_mesa_texformat_rgb565
;
283 &_mesa_texformat_argb8888
: &_mesa_texformat_argb4444
;
287 &_mesa_texformat_argb8888
: &_mesa_texformat_argb1555
;
291 return &_mesa_texformat_argb4444
;
294 return &_mesa_texformat_argb1555
;
300 return !force16bpt
? &_mesa_texformat_argb8888
: &_mesa_texformat_rgb565
;
304 return &_mesa_texformat_rgb565
;
307 return &_mesa_texformat_rgb332
;
310 case GL_ALPHA4
: /* FIXME: This could use its own texstore */
314 case GL_COMPRESSED_ALPHA
:
315 return &_mesa_texformat_a8
;
319 case GL_LUMINANCE4
: /* FIXME: This could use its own texstore */
323 case GL_COMPRESSED_LUMINANCE
:
324 return &_mesa_texformat_l8
;
327 case GL_LUMINANCE_ALPHA
:
328 case GL_LUMINANCE4_ALPHA4
: /* FIXME: This could use its own texstore */
329 case GL_LUMINANCE6_ALPHA2
: /* FIXME: This could use its own texstore */
330 case GL_LUMINANCE8_ALPHA8
:
331 case GL_LUMINANCE12_ALPHA4
: /* FIXME: This could use its own texstore */
332 case GL_LUMINANCE12_ALPHA12
:
333 case GL_LUMINANCE16_ALPHA16
:
334 case GL_COMPRESSED_LUMINANCE_ALPHA
:
335 return &_mesa_texformat_al88
;
342 case GL_COMPRESSED_INTENSITY
:
343 return &_mesa_texformat_i8
;
346 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
347 type
== GL_UNSIGNED_BYTE
)
348 return &_mesa_texformat_ycbcr
;
350 return &_mesa_texformat_ycbcr_rev
;
353 _mesa_problem(ctx
, "unexpected format in sisDDChooseTextureFormat: %d",
359 static void sisTexImage1D( GLcontext
*ctx
, GLenum target
, GLint level
,
360 GLint internalFormat
,
361 GLint width
, 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 sisChooseTextureFormat */
375 _mesa_store_teximage1d( ctx
, target
, level
, internalFormat
,
376 width
, border
, format
, type
,
377 pixels
, packing
, texObj
, texImage
);
379 /* Allocate offscreen space for the texture */
380 sisFreeTexImage(smesa
, t
, level
);
381 sisAllocTexImage(smesa
, t
, level
, texImage
);
383 /* 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
;
396 static void sisTexSubImage1D( GLcontext
*ctx
,
401 GLenum format
, GLenum type
,
402 const GLvoid
*pixels
,
403 const struct gl_pixelstore_attrib
*packing
,
404 struct gl_texture_object
*texObj
,
405 struct gl_texture_image
*texImage
)
407 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
414 if ( texObj
->DriverData
== NULL
)
415 sisAllocTexObj( texObj
);
416 t
= texObj
->DriverData
;
418 _mesa_store_texsubimage1d(ctx
, target
, level
, xoffset
, width
,
419 format
, type
, pixels
, packing
, texObj
,
422 /* Allocate offscreen space for the texture */
423 sisFreeTexImage(smesa
, t
, level
);
424 sisAllocTexImage(smesa
, t
, level
, texImage
);
426 /* Upload the texture */
428 texelBytes
= texImage
->TexFormat
->TexelBytes
;
430 copySize
= width
* texelBytes
;
431 src
= (char *)texImage
->Data
+ xoffset
* texelBytes
;
432 dst
= t
->image
[level
].Data
+ xoffset
* texelBytes
;
434 memcpy( dst
, src
, copySize
);
436 smesa
->clearTexCache
= GL_TRUE
;
438 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
440 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
441 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
443 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
446 static void sisTexImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
447 GLint internalFormat
,
448 GLint width
, GLint height
, GLint border
,
449 GLenum format
, GLenum type
, const GLvoid
*pixels
,
450 const struct gl_pixelstore_attrib
*packing
,
451 struct gl_texture_object
*texObj
,
452 struct gl_texture_image
*texImage
)
454 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
457 if ( texObj
->DriverData
== NULL
)
458 sisAllocTexObj( texObj
);
459 t
= texObj
->DriverData
;
461 /* Note, this will call sisChooseTextureFormat */
462 _mesa_store_teximage2d(ctx
, target
, level
, internalFormat
,
463 width
, height
, border
, format
, type
, pixels
,
464 &ctx
->Unpack
, texObj
, texImage
);
466 /* Allocate offscreen space for the texture */
467 sisFreeTexImage(smesa
, t
, level
);
468 sisAllocTexImage(smesa
, t
, level
, texImage
);
470 /* Upload the texture */
472 memcpy(t
->image
[level
].Data
, texImage
->Data
, t
->image
[level
].size
);
474 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
476 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
477 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
479 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
482 static void sisTexSubImage2D( GLcontext
*ctx
,
485 GLint xoffset
, GLint yoffset
,
486 GLsizei width
, GLsizei height
,
487 GLenum format
, GLenum type
,
488 const GLvoid
*pixels
,
489 const struct gl_pixelstore_attrib
*packing
,
490 struct gl_texture_object
*texObj
,
491 struct gl_texture_image
*texImage
)
493 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
502 if ( texObj
->DriverData
== NULL
)
503 sisAllocTexObj( texObj
);
504 t
= texObj
->DriverData
;
506 _mesa_store_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
507 height
, format
, type
, pixels
, packing
, texObj
,
510 /* Allocate offscreen space for the texture */
511 sisFreeTexImage(smesa
, t
, level
);
512 sisAllocTexImage(smesa
, t
, level
, texImage
);
514 /* Upload the texture */
516 texelBytes
= texImage
->TexFormat
->TexelBytes
;
518 copySize
= width
* texelBytes
;
519 src
= (char *)texImage
->Data
+ (xoffset
+ yoffset
* texImage
->Width
) *
521 dst
= t
->image
[level
].Data
+ (xoffset
+ yoffset
* texImage
->Width
) *
523 soffset
= texImage
->Width
* texelBytes
;
525 for (j
= yoffset
; j
< yoffset
+ height
; j
++) {
526 memcpy( dst
, src
, copySize
);
531 smesa
->clearTexCache
= GL_TRUE
;
533 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
535 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
536 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
538 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
543 * Allocate a new texture object.
544 * Called via ctx->Driver.NewTextureObject.
545 * Note: this function will be called during context creation to
546 * allocate the default texture objects.
547 * Note: we could use containment here to 'derive' the driver-specific
548 * texture object from the core mesa gl_texture_object. Not done at this time.
550 static struct gl_texture_object
*
551 sisNewTextureObject( GLcontext
*ctx
, GLuint name
, GLenum target
)
553 struct gl_texture_object
*obj
;
554 obj
= _mesa_new_texture_object(ctx
, name
, target
);
559 void sisInitTextureFuncs( struct dd_function_table
*functions
)
561 functions
->TexEnv
= sisTexEnv
;
562 functions
->ChooseTextureFormat
= sisChooseTextureFormat
;
563 functions
->TexImage1D
= sisTexImage1D
;
564 functions
->TexSubImage1D
= sisTexSubImage1D
;
565 functions
->TexImage2D
= sisTexImage2D
;
566 functions
->TexSubImage2D
= sisTexSubImage2D
;
567 functions
->TexParameter
= sisTexParameter
;
568 functions
->BindTexture
= sisBindTexture
;
569 functions
->NewTextureObject
= sisNewTextureObject
;
570 functions
->DeleteTexture
= sisDeleteTexture
;
571 functions
->IsTextureResident
= sisIsTextureResident
;