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( struct gl_context *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( struct gl_context *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( struct gl_context *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( struct gl_context * 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( struct gl_context * ctx,
224
struct gl_texture_object *texObj )
226
return (texObj->DriverData != NULL);
230
sisChooseTextureFormat( struct gl_context *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( struct gl_context *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( struct gl_context *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( struct gl_context *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( struct gl_context *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( struct gl_context *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;