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
)
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", image
->TexFormat
);
107 assert(t
->format
== image
->_BaseFormat
);
109 texel_size
= _mesa_get_format_bytes(image
->TexFormat
);
110 size
= image
->Width
* image
->Height
* texel_size
+ TEXTURE_HW_PLUS
;
112 addr
= sisAllocFB( smesa
, size
, &t
->image
[level
].handle
);
114 addr
= sisAllocAGP( smesa
, size
, &t
->image
[level
].handle
);
116 sis_fatal_error("Failure to allocate texture memory.\n");
117 t
->image
[level
].memType
= AGP_TYPE
;
120 t
->image
[level
].memType
= VIDEO_TYPE
;
122 t
->image
[level
].Data
= ALIGN(addr
, TEXTURE_HW_ALIGNMENT
);
123 t
->image
[level
].pitch
= image
->Width
* texel_size
;
124 t
->image
[level
].size
= image
->Width
* image
->Height
* texel_size
;
129 sisFreeTexImage( sisContextPtr smesa
, sisTexObjPtr t
, int level
)
132 assert(level
< SIS_MAX_TEXTURE_LEVELS
);
133 if (t
->image
[level
].Data
== NULL
)
136 switch (t
->image
[level
].memType
)
139 sisFreeFB( smesa
, t
->image
[level
].handle
);
142 sisFreeAGP( smesa
, t
->image
[level
].handle
);
145 t
->image
[level
].Data
= NULL
;
146 t
->image
[level
].handle
= NULL
;
147 /* If there are no textures loaded any more, reset the hw format so the
148 * object can be reused for new formats
151 if (t
->numImages
== 0) {
158 sisTexEnv( GLcontext
*ctx
, GLenum target
, GLenum pname
, const GLfloat
*param
)
160 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
162 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
166 sisTexParameter( GLcontext
*ctx
, GLenum target
,
167 struct gl_texture_object
*texObj
, GLenum pname
,
168 const GLfloat
*params
)
170 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
172 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
176 sisBindTexture( GLcontext
*ctx
, GLenum target
,
177 struct gl_texture_object
*texObj
)
179 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
182 if ( target
== GL_TEXTURE_2D
|| target
== GL_TEXTURE_1D
) {
183 if ( texObj
->DriverData
== NULL
) {
184 sisAllocTexObj( texObj
);
188 t
= texObj
->DriverData
;
192 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
) {
193 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
194 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
196 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
200 sisDeleteTexture( GLcontext
* ctx
, struct gl_texture_object
*texObj
)
202 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
206 smesa
->clearTexCache
= GL_TRUE
;
208 t
= texObj
->DriverData
;
211 * this shows the texture is default object and never be a
212 * argument of sisTexImage*
216 for (i
= 0; i
< SIS_MAX_TEXTURE_LEVELS
; i
++) {
217 sisFreeTexImage( smesa
, t
, i
);
221 texObj
->DriverData
= NULL
;
222 /* Free mipmap images and the texture object itself */
223 _mesa_delete_texture_object(ctx
, texObj
);
226 static GLboolean
sisIsTextureResident( GLcontext
* ctx
,
227 struct gl_texture_object
*texObj
)
229 return (texObj
->DriverData
!= NULL
);
233 sisChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
234 GLenum format
, GLenum type
)
236 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
238 const GLboolean do32bpt
=
239 (smesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
240 const GLboolean force16bpt
=
241 (smesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
243 switch ( internalFormat
) {
246 case GL_COMPRESSED_RGBA
:
248 case GL_UNSIGNED_INT_10_10_10_2
:
249 case GL_UNSIGNED_INT_2_10_10_10_REV
:
250 return do32bpt
? MESA_FORMAT_ARGB8888
: MESA_FORMAT_ARGB1555
;
251 case GL_UNSIGNED_SHORT_4_4_4_4
:
252 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
253 return MESA_FORMAT_ARGB4444
;
254 case GL_UNSIGNED_SHORT_5_5_5_1
:
255 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
256 return MESA_FORMAT_ARGB1555
;
258 return do32bpt
? MESA_FORMAT_ARGB8888
: MESA_FORMAT_ARGB4444
;
263 case GL_COMPRESSED_RGB
:
265 case GL_UNSIGNED_SHORT_4_4_4_4
:
266 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
267 return MESA_FORMAT_ARGB4444
;
268 case GL_UNSIGNED_SHORT_5_5_5_1
:
269 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
270 return MESA_FORMAT_ARGB1555
;
271 case GL_UNSIGNED_SHORT_5_6_5
:
272 case GL_UNSIGNED_SHORT_5_6_5_REV
:
273 return MESA_FORMAT_RGB565
;
275 return do32bpt
? MESA_FORMAT_ARGB8888
: MESA_FORMAT_RGB565
;
282 MESA_FORMAT_ARGB8888
: MESA_FORMAT_ARGB4444
;
286 MESA_FORMAT_ARGB8888
: MESA_FORMAT_ARGB1555
;
290 return MESA_FORMAT_ARGB4444
;
293 return MESA_FORMAT_ARGB1555
;
299 return !force16bpt
? MESA_FORMAT_ARGB8888
: MESA_FORMAT_RGB565
;
303 return MESA_FORMAT_RGB565
;
306 return MESA_FORMAT_RGB332
;
309 case GL_ALPHA4
: /* FIXME: This could use its own texstore */
313 case GL_COMPRESSED_ALPHA
:
314 return MESA_FORMAT_A8
;
318 case GL_LUMINANCE4
: /* FIXME: This could use its own texstore */
322 case GL_COMPRESSED_LUMINANCE
:
323 return MESA_FORMAT_L8
;
326 case GL_LUMINANCE_ALPHA
:
327 case GL_LUMINANCE4_ALPHA4
: /* FIXME: This could use its own texstore */
328 case GL_LUMINANCE6_ALPHA2
: /* FIXME: This could use its own texstore */
329 case GL_LUMINANCE8_ALPHA8
:
330 case GL_LUMINANCE12_ALPHA4
: /* FIXME: This could use its own texstore */
331 case GL_LUMINANCE12_ALPHA12
:
332 case GL_LUMINANCE16_ALPHA16
:
333 case GL_COMPRESSED_LUMINANCE_ALPHA
:
334 return MESA_FORMAT_AL88
;
341 case GL_COMPRESSED_INTENSITY
:
342 return MESA_FORMAT_I8
;
345 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
346 type
== GL_UNSIGNED_BYTE
)
347 return MESA_FORMAT_YCBCR
;
349 return MESA_FORMAT_YCBCR_REV
;
352 _mesa_problem(ctx
, "unexpected format in sisDDChooseTextureFormat: %d",
354 return MESA_FORMAT_NONE
;
358 static void sisTexImage1D( GLcontext
*ctx
, GLenum target
, GLint level
,
359 GLint internalFormat
,
360 GLint width
, GLint border
,
361 GLenum format
, GLenum type
, const GLvoid
*pixels
,
362 const struct gl_pixelstore_attrib
*packing
,
363 struct gl_texture_object
*texObj
,
364 struct gl_texture_image
*texImage
)
366 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
369 if ( texObj
->DriverData
== NULL
)
370 sisAllocTexObj( texObj
);
371 t
= texObj
->DriverData
;
373 /* Note, this will call sisChooseTextureFormat */
374 _mesa_store_teximage1d( ctx
, target
, level
, internalFormat
,
375 width
, border
, format
, type
,
376 pixels
, packing
, texObj
, texImage
);
378 /* Allocate offscreen space for the texture */
379 sisFreeTexImage(smesa
, t
, level
);
380 sisAllocTexImage(smesa
, t
, level
, texImage
);
382 /* 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
;
395 static void sisTexSubImage1D( GLcontext
*ctx
,
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
);
413 if ( texObj
->DriverData
== NULL
)
414 sisAllocTexObj( texObj
);
415 t
= texObj
->DriverData
;
417 _mesa_store_texsubimage1d(ctx
, target
, level
, xoffset
, width
,
418 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 */
427 texelBytes
= _mesa_get_format_bytes(texImage
->TexFormat
);
429 copySize
= width
* texelBytes
;
430 src
= (char *)texImage
->Data
+ xoffset
* texelBytes
;
431 dst
= t
->image
[level
].Data
+ xoffset
* texelBytes
;
433 memcpy( dst
, src
, copySize
);
435 smesa
->clearTexCache
= GL_TRUE
;
437 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
439 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
440 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
442 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
445 static void sisTexImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
446 GLint internalFormat
,
447 GLint width
, GLint height
, GLint border
,
448 GLenum format
, GLenum type
, const GLvoid
*pixels
,
449 const struct gl_pixelstore_attrib
*packing
,
450 struct gl_texture_object
*texObj
,
451 struct gl_texture_image
*texImage
)
453 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
456 if ( texObj
->DriverData
== NULL
)
457 sisAllocTexObj( texObj
);
458 t
= texObj
->DriverData
;
460 /* Note, this will call sisChooseTextureFormat */
461 _mesa_store_teximage2d(ctx
, target
, level
, internalFormat
,
462 width
, height
, border
, format
, type
, pixels
,
463 &ctx
->Unpack
, texObj
, texImage
);
465 /* Allocate offscreen space for the texture */
466 sisFreeTexImage(smesa
, t
, level
);
467 sisAllocTexImage(smesa
, t
, level
, texImage
);
469 /* Upload the texture */
471 memcpy(t
->image
[level
].Data
, texImage
->Data
, t
->image
[level
].size
);
473 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
475 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
476 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
478 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
481 static void sisTexSubImage2D( GLcontext
*ctx
,
484 GLint xoffset
, GLint yoffset
,
485 GLsizei width
, GLsizei height
,
486 GLenum format
, GLenum type
,
487 const GLvoid
*pixels
,
488 const struct gl_pixelstore_attrib
*packing
,
489 struct gl_texture_object
*texObj
,
490 struct gl_texture_image
*texImage
)
492 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
501 if ( texObj
->DriverData
== NULL
)
502 sisAllocTexObj( texObj
);
503 t
= texObj
->DriverData
;
505 _mesa_store_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
506 height
, format
, type
, pixels
, packing
, texObj
,
509 /* Allocate offscreen space for the texture */
510 sisFreeTexImage(smesa
, t
, level
);
511 sisAllocTexImage(smesa
, t
, level
, texImage
);
513 /* Upload the texture */
515 texelBytes
= _mesa_get_format_bytes(texImage
->TexFormat
);
517 copySize
= width
* texelBytes
;
518 src
= (char *)texImage
->Data
+ (xoffset
+ yoffset
* texImage
->Width
) *
520 dst
= t
->image
[level
].Data
+ (xoffset
+ yoffset
* texImage
->Width
) *
522 soffset
= texImage
->Width
* texelBytes
;
524 for (j
= yoffset
; j
< yoffset
+ height
; j
++) {
525 memcpy( dst
, src
, copySize
);
530 smesa
->clearTexCache
= GL_TRUE
;
532 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
534 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
535 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
537 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
542 * Allocate a new texture object.
543 * Called via ctx->Driver.NewTextureObject.
544 * Note: this function will be called during context creation to
545 * allocate the default texture objects.
546 * Note: we could use containment here to 'derive' the driver-specific
547 * texture object from the core mesa gl_texture_object. Not done at this time.
549 static struct gl_texture_object
*
550 sisNewTextureObject( GLcontext
*ctx
, GLuint name
, GLenum target
)
552 struct gl_texture_object
*obj
;
553 obj
= _mesa_new_texture_object(ctx
, name
, target
);
558 void sisInitTextureFuncs( struct dd_function_table
*functions
)
560 functions
->TexEnv
= sisTexEnv
;
561 functions
->ChooseTextureFormat
= sisChooseTextureFormat
;
562 functions
->TexImage1D
= sisTexImage1D
;
563 functions
->TexSubImage1D
= sisTexSubImage1D
;
564 functions
->TexImage2D
= sisTexImage2D
;
565 functions
->TexSubImage2D
= sisTexSubImage2D
;
566 functions
->TexParameter
= sisTexParameter
;
567 functions
->BindTexture
= sisBindTexture
;
568 functions
->NewTextureObject
= sisNewTextureObject
;
569 functions
->DeleteTexture
= sisDeleteTexture
;
570 functions
->IsTextureResident
= sisIsTextureResident
;