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/teximage.h"
35 #include "main/texobj.h"
37 #include "sis_context.h"
38 #include "sis_alloc.h"
42 #define ALIGN(value, align) (GLubyte *)((long)(value + align - 1) & ~(align - 1))
44 #define TEXTURE_HW_ALIGNMENT 4
45 #define TEXTURE_HW_PLUS (4 + 4)
48 sisAllocTexObj( struct gl_texture_object
*texObj
)
52 t
= (sisTexObjPtr
) CALLOC_STRUCT( sis_tex_obj
);
53 texObj
->DriverData
= t
;
58 sisAllocTexImage( sisContextPtr smesa
, sisTexObjPtr t
, int level
,
59 const struct gl_texture_image
*image
)
65 t
->format
= image
->_BaseFormat
;
66 switch (image
->TexFormat
)
68 case MESA_FORMAT_ARGB8888
:
69 t
->hwformat
= TEXEL_ARGB_8888_32
;
71 case MESA_FORMAT_ARGB4444
:
72 t
->hwformat
= TEXEL_ARGB_4444_16
;
74 case MESA_FORMAT_ARGB1555
:
75 t
->hwformat
= TEXEL_ARGB_1555_16
;
77 case MESA_FORMAT_RGB565
:
78 t
->hwformat
= TEXEL_RGB_565_16
;
80 case MESA_FORMAT_RGB332
:
81 t
->hwformat
= TEXEL_RGB_332_8
;
84 t
->hwformat
= TEXEL_I8
;
87 t
->hwformat
= TEXEL_A8
;
90 t
->hwformat
= TEXEL_L8
;
92 case MESA_FORMAT_AL88
:
93 t
->hwformat
= TEXEL_AL88
;
95 case MESA_FORMAT_YCBCR
:
96 t
->hwformat
= TEXEL_YUV422
;
98 case MESA_FORMAT_YCBCR_REV
:
99 t
->hwformat
= TEXEL_VUY422
;
102 sis_fatal_error("Bad texture format 0x%x.\n", image
->TexFormat
);
105 assert(t
->format
== image
->_BaseFormat
);
107 texel_size
= _mesa_get_format_bytes(image
->TexFormat
);
108 size
= image
->Width
* image
->Height
* texel_size
+ TEXTURE_HW_PLUS
;
110 addr
= sisAllocFB( smesa
, size
, &t
->image
[level
].handle
);
112 addr
= sisAllocAGP( smesa
, size
, &t
->image
[level
].handle
);
114 sis_fatal_error("Failure to allocate texture memory.\n");
115 t
->image
[level
].memType
= AGP_TYPE
;
118 t
->image
[level
].memType
= VIDEO_TYPE
;
120 t
->image
[level
].Data
= ALIGN(addr
, TEXTURE_HW_ALIGNMENT
);
121 t
->image
[level
].pitch
= image
->Width
* texel_size
;
122 t
->image
[level
].size
= image
->Width
* image
->Height
* texel_size
;
127 sisFreeTexImage( sisContextPtr smesa
, sisTexObjPtr t
, int level
)
130 assert(level
< SIS_MAX_TEXTURE_LEVELS
);
131 if (t
->image
[level
].Data
== NULL
)
134 switch (t
->image
[level
].memType
)
137 sisFreeFB( smesa
, t
->image
[level
].handle
);
140 sisFreeAGP( smesa
, t
->image
[level
].handle
);
143 t
->image
[level
].Data
= NULL
;
144 t
->image
[level
].handle
= NULL
;
145 /* If there are no textures loaded any more, reset the hw format so the
146 * object can be reused for new formats
149 if (t
->numImages
== 0) {
156 sisTexEnv( GLcontext
*ctx
, GLenum target
, GLenum pname
, const GLfloat
*param
)
158 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
160 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
164 sisTexParameter( GLcontext
*ctx
, GLenum target
,
165 struct gl_texture_object
*texObj
, GLenum pname
,
166 const GLfloat
*params
)
168 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
170 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
174 sisBindTexture( GLcontext
*ctx
, GLenum target
,
175 struct gl_texture_object
*texObj
)
177 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
180 if ( target
== GL_TEXTURE_2D
|| target
== GL_TEXTURE_1D
) {
181 if ( texObj
->DriverData
== NULL
) {
182 sisAllocTexObj( texObj
);
186 t
= texObj
->DriverData
;
190 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
) {
191 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
192 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
194 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
198 sisDeleteTexture( GLcontext
* ctx
, struct gl_texture_object
*texObj
)
200 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
204 smesa
->clearTexCache
= GL_TRUE
;
206 t
= texObj
->DriverData
;
209 * this shows the texture is default object and never be a
210 * argument of sisTexImage*
214 for (i
= 0; i
< SIS_MAX_TEXTURE_LEVELS
; i
++) {
215 sisFreeTexImage( smesa
, t
, i
);
219 texObj
->DriverData
= NULL
;
220 /* Free mipmap images and the texture object itself */
221 _mesa_delete_texture_object(ctx
, texObj
);
224 static GLboolean
sisIsTextureResident( GLcontext
* ctx
,
225 struct gl_texture_object
*texObj
)
227 return (texObj
->DriverData
!= NULL
);
231 sisChooseTextureFormat( GLcontext
*ctx
, GLint internalFormat
,
232 GLenum format
, GLenum type
)
234 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
236 const GLboolean do32bpt
=
237 (smesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_32
);
238 const GLboolean force16bpt
=
239 (smesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FORCE_16
);
241 switch ( internalFormat
) {
244 case GL_COMPRESSED_RGBA
:
246 case GL_UNSIGNED_INT_10_10_10_2
:
247 case GL_UNSIGNED_INT_2_10_10_10_REV
:
248 return do32bpt
? MESA_FORMAT_ARGB8888
: MESA_FORMAT_ARGB1555
;
249 case GL_UNSIGNED_SHORT_4_4_4_4
:
250 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
251 return MESA_FORMAT_ARGB4444
;
252 case GL_UNSIGNED_SHORT_5_5_5_1
:
253 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
254 return MESA_FORMAT_ARGB1555
;
256 return do32bpt
? MESA_FORMAT_ARGB8888
: MESA_FORMAT_ARGB4444
;
261 case GL_COMPRESSED_RGB
:
263 case GL_UNSIGNED_SHORT_4_4_4_4
:
264 case GL_UNSIGNED_SHORT_4_4_4_4_REV
:
265 return MESA_FORMAT_ARGB4444
;
266 case GL_UNSIGNED_SHORT_5_5_5_1
:
267 case GL_UNSIGNED_SHORT_1_5_5_5_REV
:
268 return MESA_FORMAT_ARGB1555
;
269 case GL_UNSIGNED_SHORT_5_6_5
:
270 case GL_UNSIGNED_SHORT_5_6_5_REV
:
271 return MESA_FORMAT_RGB565
;
273 return do32bpt
? MESA_FORMAT_ARGB8888
: MESA_FORMAT_RGB565
;
280 MESA_FORMAT_ARGB8888
: MESA_FORMAT_ARGB4444
;
284 MESA_FORMAT_ARGB8888
: MESA_FORMAT_ARGB1555
;
288 return MESA_FORMAT_ARGB4444
;
291 return MESA_FORMAT_ARGB1555
;
297 return !force16bpt
? MESA_FORMAT_ARGB8888
: MESA_FORMAT_RGB565
;
301 return MESA_FORMAT_RGB565
;
304 return MESA_FORMAT_RGB332
;
307 case GL_ALPHA4
: /* FIXME: This could use its own texstore */
311 case GL_COMPRESSED_ALPHA
:
312 return MESA_FORMAT_A8
;
316 case GL_LUMINANCE4
: /* FIXME: This could use its own texstore */
320 case GL_COMPRESSED_LUMINANCE
:
321 return MESA_FORMAT_L8
;
324 case GL_LUMINANCE_ALPHA
:
325 case GL_LUMINANCE4_ALPHA4
: /* FIXME: This could use its own texstore */
326 case GL_LUMINANCE6_ALPHA2
: /* FIXME: This could use its own texstore */
327 case GL_LUMINANCE8_ALPHA8
:
328 case GL_LUMINANCE12_ALPHA4
: /* FIXME: This could use its own texstore */
329 case GL_LUMINANCE12_ALPHA12
:
330 case GL_LUMINANCE16_ALPHA16
:
331 case GL_COMPRESSED_LUMINANCE_ALPHA
:
332 return MESA_FORMAT_AL88
;
339 case GL_COMPRESSED_INTENSITY
:
340 return MESA_FORMAT_I8
;
343 if (type
== GL_UNSIGNED_SHORT_8_8_APPLE
||
344 type
== GL_UNSIGNED_BYTE
)
345 return MESA_FORMAT_YCBCR
;
347 return MESA_FORMAT_YCBCR_REV
;
350 _mesa_problem(ctx
, "unexpected format in sisDDChooseTextureFormat: %d",
352 return MESA_FORMAT_NONE
;
356 static void sisTexImage1D( GLcontext
*ctx
, GLenum target
, GLint level
,
357 GLint internalFormat
,
358 GLint width
, GLint border
,
359 GLenum format
, GLenum type
, const GLvoid
*pixels
,
360 const struct gl_pixelstore_attrib
*packing
,
361 struct gl_texture_object
*texObj
,
362 struct gl_texture_image
*texImage
)
364 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
367 if ( texObj
->DriverData
== NULL
)
368 sisAllocTexObj( texObj
);
369 t
= texObj
->DriverData
;
371 /* Note, this will call sisChooseTextureFormat */
372 _mesa_store_teximage1d( ctx
, target
, level
, internalFormat
,
373 width
, border
, format
, type
,
374 pixels
, packing
, texObj
, texImage
);
376 /* Allocate offscreen space for the texture */
377 sisFreeTexImage(smesa
, t
, level
);
378 sisAllocTexImage(smesa
, t
, level
, texImage
);
380 /* Upload the texture */
382 memcpy(t
->image
[level
].Data
, texImage
->Data
, t
->image
[level
].size
);
384 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
386 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
387 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
389 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
393 static void sisTexSubImage1D( GLcontext
*ctx
,
398 GLenum format
, GLenum type
,
399 const GLvoid
*pixels
,
400 const struct gl_pixelstore_attrib
*packing
,
401 struct gl_texture_object
*texObj
,
402 struct gl_texture_image
*texImage
)
404 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
411 if ( texObj
->DriverData
== NULL
)
412 sisAllocTexObj( texObj
);
413 t
= texObj
->DriverData
;
415 _mesa_store_texsubimage1d(ctx
, target
, level
, xoffset
, width
,
416 format
, type
, pixels
, packing
, texObj
,
419 /* Allocate offscreen space for the texture */
420 sisFreeTexImage(smesa
, t
, level
);
421 sisAllocTexImage(smesa
, t
, level
, texImage
);
423 /* Upload the texture */
425 texelBytes
= _mesa_get_format_bytes(texImage
->TexFormat
);
427 copySize
= width
* texelBytes
;
428 src
= (char *)texImage
->Data
+ xoffset
* texelBytes
;
429 dst
= t
->image
[level
].Data
+ xoffset
* texelBytes
;
431 memcpy( dst
, src
, copySize
);
433 smesa
->clearTexCache
= GL_TRUE
;
435 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
437 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
438 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
440 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
443 static void sisTexImage2D( GLcontext
*ctx
, GLenum target
, GLint level
,
444 GLint internalFormat
,
445 GLint width
, GLint height
, GLint border
,
446 GLenum format
, GLenum type
, const GLvoid
*pixels
,
447 const struct gl_pixelstore_attrib
*packing
,
448 struct gl_texture_object
*texObj
,
449 struct gl_texture_image
*texImage
)
451 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
454 if ( texObj
->DriverData
== NULL
)
455 sisAllocTexObj( texObj
);
456 t
= texObj
->DriverData
;
458 /* Note, this will call sisChooseTextureFormat */
459 _mesa_store_teximage2d(ctx
, target
, level
, internalFormat
,
460 width
, height
, border
, format
, type
, pixels
,
461 &ctx
->Unpack
, texObj
, texImage
);
463 /* Allocate offscreen space for the texture */
464 sisFreeTexImage(smesa
, t
, level
);
465 sisAllocTexImage(smesa
, t
, level
, texImage
);
467 /* Upload the texture */
469 memcpy(t
->image
[level
].Data
, texImage
->Data
, t
->image
[level
].size
);
471 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
473 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
474 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
476 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
479 static void sisTexSubImage2D( GLcontext
*ctx
,
482 GLint xoffset
, GLint yoffset
,
483 GLsizei width
, GLsizei height
,
484 GLenum format
, GLenum type
,
485 const GLvoid
*pixels
,
486 const struct gl_pixelstore_attrib
*packing
,
487 struct gl_texture_object
*texObj
,
488 struct gl_texture_image
*texImage
)
490 sisContextPtr smesa
= SIS_CONTEXT(ctx
);
499 if ( texObj
->DriverData
== NULL
)
500 sisAllocTexObj( texObj
);
501 t
= texObj
->DriverData
;
503 _mesa_store_texsubimage2d(ctx
, target
, level
, xoffset
, yoffset
, width
,
504 height
, format
, type
, pixels
, packing
, texObj
,
507 /* Allocate offscreen space for the texture */
508 sisFreeTexImage(smesa
, t
, level
);
509 sisAllocTexImage(smesa
, t
, level
, texImage
);
511 /* Upload the texture */
513 texelBytes
= _mesa_get_format_bytes(texImage
->TexFormat
);
515 copySize
= width
* texelBytes
;
516 src
= (char *)texImage
->Data
+ (xoffset
+ yoffset
* texImage
->Width
) *
518 dst
= t
->image
[level
].Data
+ (xoffset
+ yoffset
* texImage
->Width
) *
520 soffset
= texImage
->Width
* texelBytes
;
522 for (j
= yoffset
; j
< yoffset
+ height
; j
++) {
523 memcpy( dst
, src
, copySize
);
528 smesa
->clearTexCache
= GL_TRUE
;
530 if (smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] != t
->format
)
532 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURE_ENV
;
533 smesa
->PrevTexFormat
[ctx
->Texture
.CurrentUnit
] = t
->format
;
535 smesa
->TexStates
[ctx
->Texture
.CurrentUnit
] |= NEW_TEXTURING
;
540 * Allocate a new texture object.
541 * Called via ctx->Driver.NewTextureObject.
542 * Note: this function will be called during context creation to
543 * allocate the default texture objects.
544 * Note: we could use containment here to 'derive' the driver-specific
545 * texture object from the core mesa gl_texture_object. Not done at this time.
547 static struct gl_texture_object
*
548 sisNewTextureObject( GLcontext
*ctx
, GLuint name
, GLenum target
)
550 struct gl_texture_object
*obj
;
551 obj
= _mesa_new_texture_object(ctx
, name
, target
);
556 void sisInitTextureFuncs( struct dd_function_table
*functions
)
558 functions
->TexEnv
= sisTexEnv
;
559 functions
->ChooseTextureFormat
= sisChooseTextureFormat
;
560 functions
->TexImage1D
= sisTexImage1D
;
561 functions
->TexSubImage1D
= sisTexSubImage1D
;
562 functions
->TexImage2D
= sisTexImage2D
;
563 functions
->TexSubImage2D
= sisTexSubImage2D
;
564 functions
->TexParameter
= sisTexParameter
;
565 functions
->BindTexture
= sisBindTexture
;
566 functions
->NewTextureObject
= sisNewTextureObject
;
567 functions
->DeleteTexture
= sisDeleteTexture
;
568 functions
->IsTextureResident
= sisIsTextureResident
;