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 "swrast/swrast.h"
32 #include "main/imports.h"
33 #include "main/texstore.h"
34 #include "main/texobj.h"
36 #include "sis_context.h"
37 #include "sis_alloc.h"
41 #define ALIGN(value, align) (GLubyte *)((long)(value + align - 1) & ~(align - 1))
43 #define TEXTURE_HW_ALIGNMENT 4
44 #define TEXTURE_HW_PLUS (4 + 4)
47 sisAllocTexObj( struct gl_texture_object
*texObj
)
51 t
= (sisTexObjPtr
) CALLOC_STRUCT( sis_tex_obj
);
52 texObj
->DriverData
= t
;
57 sisAllocTexImage( sisContextPtr smesa
, sisTexObjPtr t
, int level
,
58 const struct gl_texture_image
*image
)
64 t
->format
= image
->_BaseFormat
;
65 switch (image
->TexFormat
)
67 case MESA_FORMAT_ARGB8888
:
68 t
->hwformat
= TEXEL_ARGB_8888_32
;
70 case MESA_FORMAT_ARGB4444
:
71 t
->hwformat
= TEXEL_ARGB_4444_16
;
73 case MESA_FORMAT_ARGB1555
:
74 t
->hwformat
= TEXEL_ARGB_1555_16
;
76 case MESA_FORMAT_RGB565
:
77 t
->hwformat
= TEXEL_RGB_565_16
;
79 case MESA_FORMAT_RGB332
:
80 t
->hwformat
= TEXEL_RGB_332_8
;
83 t
->hwformat
= TEXEL_I8
;
86 t
->hwformat
= TEXEL_A8
;
89 t
->hwformat
= TEXEL_L8
;
91 case MESA_FORMAT_AL88
:
92 t
->hwformat
= TEXEL_AL88
;
94 case MESA_FORMAT_YCBCR
:
95 t
->hwformat
= TEXEL_YUV422
;
97 case MESA_FORMAT_YCBCR_REV
:
98 t
->hwformat
= TEXEL_VUY422
;
101 sis_fatal_error("Bad texture format 0x%x.\n", image
->TexFormat
);
104 assert(t
->format
== image
->_BaseFormat
);
106 texel_size
= _mesa_get_format_bytes(image
->TexFormat
);
107 size
= image
->Width
* image
->Height
* texel_size
+ TEXTURE_HW_PLUS
;
109 addr
= sisAllocFB( smesa
, size
, &t
->image
[level
].handle
);
111 addr
= sisAllocAGP( smesa
, size
, &t
->image
[level
].handle
);
113 sis_fatal_error("Failure to allocate texture memory.\n");
114 t
->image
[level
].memType
= AGP_TYPE
;
117 t
->image
[level
].memType
= VIDEO_TYPE
;
119 t
->image
[level
].Data
= ALIGN(addr
, TEXTURE_HW_ALIGNMENT
);
120 t
->image
[level
].pitch
= image
->Width
* texel_size
;
121 t
->image
[level
].size
= image
->Width
* image
->Height
* texel_size
;
126 sisFreeTexImage( sisContextPtr smesa
, sisTexObjPtr t
, int level
)
129 assert(level
< SIS_MAX_TEXTURE_LEVELS
);
130 if (t
->image
[level
].Data
== NULL
)
133 switch (t
->image
[level
].memType
)
136 sisFreeFB( smesa
, t
->image
[level
].handle
);
139 sisFreeAGP( smesa
, t
->image
[level
].handle
);
142 t
->image
[level
].Data
= NULL
;
143 t
->image
[level
].handle
= NULL
;
144 /* If there are no textures loaded any more, reset the hw format so the
145 * object can be reused for new formats
148 if (t
->numImages
== 0) {
155 sisTexEnv( GLcontext
*ctx
, GLenum target
, GLenum pname
, const GLfloat
*param
)
157 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
159 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
163 sisTexParameter( GLcontext
*ctx
, GLenum target
,
164 struct gl_texture_object
*texObj
, GLenum pname
,
165 const GLfloat
*params
)
167 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
169 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
173 sisBindTexture( GLcontext
*ctx
, GLenum target
,
174 struct gl_texture_object
*texObj
)
176 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
179 if ( target
== GL_TEXTURE_2D
|| target
== GL_TEXTURE_1D
) {
180 if ( texObj
->DriverData
== NULL
) {
181 sisAllocTexObj( texObj
);
185 t
= texObj
->DriverData
;
189 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
) {
190 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
191 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
193 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
197 sisDeleteTexture( GLcontext
* ctx
, struct gl_texture_object
*texObj
)
199 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
203 smesa
->clearTexCache
= GL_TRUE
;
205 t
= texObj
->DriverData
;
208 * this shows the texture is default object and never be a
209 * argument of sisTexImage*
213 for (i
= 0; i
< SIS_MAX_TEXTURE_LEVELS
; i
++) {
214 sisFreeTexImage( smesa
, t
, i
);
218 texObj
->DriverData
= NULL
;
219 /* Free mipmap images and the texture object itself */
220 _mesa_delete_texture_object(ctx
, texObj
);
223 static GLboolean
sisIsTextureResident( GLcontext
* ctx
,
224 struct gl_texture_object
*texObj
)
226 return (texObj
->DriverData
!= NULL
);
230 sisChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
231 GLenum format
, GLenum type
)
233 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
235 const GLboolean do32bpt
=
236 (smesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
237 const GLboolean force16bpt
=
238 (smesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
240 switch ( internalFormat
) {
243 case GL_COMPRESSED_RGBA
:
245 case GL_UNSIGNED_INT_10_10_10_2
:
246 case GL_UNSIGNED_INT_2_10_10_10_REV
:
247 return do32bpt
? MESA_FORMAT_ARGB8888
: MESA_FORMAT_ARGB1555
;
248 case GL_UNSIGNED_SHORT_4_4_4_4
:
249 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
250 return MESA_FORMAT_ARGB4444
;
251 case GL_UNSIGNED_SHORT_5_5_5_1
:
252 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
253 return MESA_FORMAT_ARGB1555
;
255 return do32bpt
? MESA_FORMAT_ARGB8888
: MESA_FORMAT_ARGB4444
;
260 case GL_COMPRESSED_RGB
:
262 case GL_UNSIGNED_SHORT_4_4_4_4
:
263 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
264 return MESA_FORMAT_ARGB4444
;
265 case GL_UNSIGNED_SHORT_5_5_5_1
:
266 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
267 return MESA_FORMAT_ARGB1555
;
268 case GL_UNSIGNED_SHORT_5_6_5
:
269 case GL_UNSIGNED_SHORT_5_6_5_REV
:
270 return MESA_FORMAT_RGB565
;
272 return do32bpt
? MESA_FORMAT_ARGB8888
: MESA_FORMAT_RGB565
;
279 MESA_FORMAT_ARGB8888
: MESA_FORMAT_ARGB4444
;
283 MESA_FORMAT_ARGB8888
: MESA_FORMAT_ARGB1555
;
287 return MESA_FORMAT_ARGB4444
;
290 return MESA_FORMAT_ARGB1555
;
296 return !force16bpt
? MESA_FORMAT_ARGB8888
: MESA_FORMAT_RGB565
;
300 return MESA_FORMAT_RGB565
;
303 return MESA_FORMAT_RGB332
;
306 case GL_ALPHA4
: /* FIXME: This could use its own texstore */
310 case GL_COMPRESSED_ALPHA
:
311 return MESA_FORMAT_A8
;
315 case GL_LUMINANCE4
: /* FIXME: This could use its own texstore */
319 case GL_COMPRESSED_LUMINANCE
:
320 return MESA_FORMAT_L8
;
323 case GL_LUMINANCE_ALPHA
:
324 case GL_LUMINANCE4_ALPHA4
: /* FIXME: This could use its own texstore */
325 case GL_LUMINANCE6_ALPHA2
: /* FIXME: This could use its own texstore */
326 case GL_LUMINANCE8_ALPHA8
:
327 case GL_LUMINANCE12_ALPHA4
: /* FIXME: This could use its own texstore */
328 case GL_LUMINANCE12_ALPHA12
:
329 case GL_LUMINANCE16_ALPHA16
:
330 case GL_COMPRESSED_LUMINANCE_ALPHA
:
331 return MESA_FORMAT_AL88
;
338 case GL_COMPRESSED_INTENSITY
:
339 return MESA_FORMAT_I8
;
342 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
343 type
== GL_UNSIGNED_BYTE
)
344 return MESA_FORMAT_YCBCR
;
346 return MESA_FORMAT_YCBCR_REV
;
349 _mesa_problem(ctx
, "unexpected format in sisDDChooseTextureFormat: %d",
351 return MESA_FORMAT_NONE
;
355 static void sisTexImage1D( GLcontext
*ctx
, GLenum target
, GLint level
,
356 GLint internalFormat
,
357 GLint width
, GLint border
,
358 GLenum format
, GLenum type
, const GLvoid
*pixels
,
359 const struct gl_pixelstore_attrib
*packing
,
360 struct gl_texture_object
*texObj
,
361 struct gl_texture_image
*texImage
)
363 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
366 if ( texObj
->DriverData
== NULL
)
367 sisAllocTexObj( texObj
);
368 t
= texObj
->DriverData
;
370 /* Note, this will call sisChooseTextureFormat */
371 _mesa_store_teximage1d( ctx
, target
, level
, internalFormat
,
372 width
, border
, format
, type
,
373 pixels
, packing
, texObj
, texImage
);
375 /* Allocate offscreen space for the texture */
376 sisFreeTexImage(smesa
, t
, level
);
377 sisAllocTexImage(smesa
, t
, level
, texImage
);
379 /* Upload the texture */
381 memcpy(t
->image
[level
].Data
, texImage
->Data
, t
->image
[level
].size
);
383 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
385 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
386 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
388 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
392 static void sisTexSubImage1D( GLcontext
*ctx
,
397 GLenum format
, GLenum type
,
398 const GLvoid
*pixels
,
399 const struct gl_pixelstore_attrib
*packing
,
400 struct gl_texture_object
*texObj
,
401 struct gl_texture_image
*texImage
)
403 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
410 if ( texObj
->DriverData
== NULL
)
411 sisAllocTexObj( texObj
);
412 t
= texObj
->DriverData
;
414 _mesa_store_texsubimage1d(ctx
, target
, level
, xoffset
, width
,
415 format
, type
, pixels
, packing
, texObj
,
418 /* Allocate offscreen space for the texture */
419 sisFreeTexImage(smesa
, t
, level
);
420 sisAllocTexImage(smesa
, t
, level
, texImage
);
422 /* Upload the texture */
424 texelBytes
= _mesa_get_format_bytes(texImage
->TexFormat
);
426 copySize
= width
* texelBytes
;
427 src
= (char *)texImage
->Data
+ xoffset
* texelBytes
;
428 dst
= t
->image
[level
].Data
+ xoffset
* texelBytes
;
430 memcpy( dst
, src
, copySize
);
432 smesa
->clearTexCache
= GL_TRUE
;
434 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
436 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
437 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
439 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
442 static void sisTexImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
443 GLint internalFormat
,
444 GLint width
, GLint height
, GLint border
,
445 GLenum format
, GLenum type
, const GLvoid
*pixels
,
446 const struct gl_pixelstore_attrib
*packing
,
447 struct gl_texture_object
*texObj
,
448 struct gl_texture_image
*texImage
)
450 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
453 if ( texObj
->DriverData
== NULL
)
454 sisAllocTexObj( texObj
);
455 t
= texObj
->DriverData
;
457 /* Note, this will call sisChooseTextureFormat */
458 _mesa_store_teximage2d(ctx
, target
, level
, internalFormat
,
459 width
, height
, border
, format
, type
, pixels
,
460 &ctx
->Unpack
, texObj
, texImage
);
462 /* Allocate offscreen space for the texture */
463 sisFreeTexImage(smesa
, t
, level
);
464 sisAllocTexImage(smesa
, t
, level
, texImage
);
466 /* Upload the texture */
468 memcpy(t
->image
[level
].Data
, texImage
->Data
, t
->image
[level
].size
);
470 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
472 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
473 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
475 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
478 static void sisTexSubImage2D( GLcontext
*ctx
,
481 GLint xoffset
, GLint yoffset
,
482 GLsizei width
, GLsizei height
,
483 GLenum format
, GLenum type
,
484 const GLvoid
*pixels
,
485 const struct gl_pixelstore_attrib
*packing
,
486 struct gl_texture_object
*texObj
,
487 struct gl_texture_image
*texImage
)
489 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
498 if ( texObj
->DriverData
== NULL
)
499 sisAllocTexObj( texObj
);
500 t
= texObj
->DriverData
;
502 _mesa_store_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
503 height
, format
, type
, pixels
, packing
, texObj
,
506 /* Allocate offscreen space for the texture */
507 sisFreeTexImage(smesa
, t
, level
);
508 sisAllocTexImage(smesa
, t
, level
, texImage
);
510 /* Upload the texture */
512 texelBytes
= _mesa_get_format_bytes(texImage
->TexFormat
);
514 copySize
= width
* texelBytes
;
515 src
= (char *)texImage
->Data
+ (xoffset
+ yoffset
* texImage
->Width
) *
517 dst
= t
->image
[level
].Data
+ (xoffset
+ yoffset
* texImage
->Width
) *
519 soffset
= texImage
->Width
* texelBytes
;
521 for (j
= yoffset
; j
< yoffset
+ height
; j
++) {
522 memcpy( dst
, src
, copySize
);
527 smesa
->clearTexCache
= GL_TRUE
;
529 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
531 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
532 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
534 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
539 * Allocate a new texture object.
540 * Called via ctx->Driver.NewTextureObject.
541 * Note: this function will be called during context creation to
542 * allocate the default texture objects.
543 * Note: we could use containment here to 'derive' the driver-specific
544 * texture object from the core mesa gl_texture_object. Not done at this time.
546 static struct gl_texture_object
*
547 sisNewTextureObject( GLcontext
*ctx
, GLuint name
, GLenum target
)
549 struct gl_texture_object
*obj
;
550 obj
= _mesa_new_texture_object(ctx
, name
, target
);
555 void sisInitTextureFuncs( struct dd_function_table
*functions
)
557 functions
->TexEnv
= sisTexEnv
;
558 functions
->ChooseTextureFormat
= sisChooseTextureFormat
;
559 functions
->TexImage1D
= sisTexImage1D
;
560 functions
->TexSubImage1D
= sisTexSubImage1D
;
561 functions
->TexImage2D
= sisTexImage2D
;
562 functions
->TexSubImage2D
= sisTexSubImage2D
;
563 functions
->TexParameter
= sisTexParameter
;
564 functions
->BindTexture
= sisBindTexture
;
565 functions
->NewTextureObject
= sisNewTextureObject
;
566 functions
->DeleteTexture
= sisDeleteTexture
;
567 functions
->IsTextureResident
= sisIsTextureResident
;