R200_FIREVERTICES(R200_CONTEXT(ctx));
}
+static void r200_vtbl_flush_vertices(radeonContextPtr rmesa)
+{
+ R200_FIREVERTICES(((r200ContextPtr)rmesa));
+}
+
static void r200_vtbl_set_all_dirty(GLcontext *ctx)
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
r200EmitState((r200ContextPtr)rmesa);
}
+
static void r200_init_vtbl(radeonContextPtr radeon)
{
radeon->vtbl.get_lock = r200_get_lock;
radeon->vtbl.update_viewport_offset = r200UpdateViewportOffset;
radeon->vtbl.flush = r200_vtbl_flush;
+ radeon->vtbl.flush_vertices = r200_vtbl_flush_vertices;
radeon->vtbl.set_all_dirty = r200_vtbl_set_all_dirty;
radeon->vtbl.update_draw_buffer = r200UpdateDrawBuffer;
radeon->vtbl.emit_cs_header = r200_vtbl_emit_cs_header;
rmesa->radeon.nr_heaps = 1 /* screen->numTexHeaps */ ;
assert(rmesa->radeon.nr_heaps < RADEON_NR_TEX_HEAPS);
+#if 0
for ( i = 0 ; i < rmesa->radeon.nr_heaps ; i++ ) {
rmesa->radeon.texture_heaps[i] = driCreateTextureHeap( i, rmesa,
screen->texSize[i],
sizeof( radeonTexObj ),
(destroy_texture_object_t *) r200DestroyTexObj );
}
+#endif
rmesa->radeon.texture_depth = driQueryOptioni (&rmesa->radeon.optionCache,
"texture_depth");
if (rmesa->radeon.texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
#define R200_LOD_BIAS_MASK (0xfff80000)
#define R200_LOD_BIAS_SHIFT 19
#define R200_PP_TXSIZE_0 0x2c0c /* NPOT only */
+#define R200_PP_TX_WIDTHMASK_SHIFT 0
+#define R200_PP_TX_HEIGHTMASK_SHIFT 16
+
#define R200_PP_TXPITCH_0 0x2c10 /* NPOT only */
#define R200_PP_BORDER_COLOR_0 0x2c14
#define R200_PP_CUBIC_FACES_0 0x2c18
#include "swrast_setup/swrast_setup.h"
#include "radeon_buffer.h"
+#include "radeon_mipmap_tree.h"
#include "radeon_cs.h"
#include "common_context.h"
#include "common_cmdbuf.h"
}
-static int tex_emit(GLcontext *ctx, struct radeon_state_atom *atom)
+static void tex_emit(GLcontext *ctx, struct radeon_state_atom *atom)
{
+ r200ContextPtr r200 = R200_CONTEXT(ctx);
+ BATCH_LOCALS(&r200->radeon);
+ uint32_t dwords = atom->cmd_size;
+ int i = atom->idx;
+ radeonTexObj *t = r200->state.texture.unit[i].texobj;
+
+ BEGIN_BATCH_NO_AUTOSTATE(dwords);
+ fprintf(stderr,"atom state is %x, %x %x %x %x %x\n", atom->cmd[0],
+ atom->cmd[1],
+ atom->cmd[2],
+ atom->cmd[3],
+ atom->cmd[4],
+ atom->cmd[5]);
+ OUT_BATCH_TABLE(atom->cmd, 10);
+ if (t && !t->image_override) {
+ fprintf(stderr,"emitting reloc for %d\n", i);
+ OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0,
+ RADEON_GEM_DOMAIN_VRAM, 0, 0);
+ } else if (!t) {
+
+ OUT_BATCH(atom->cmd[10]);
+ }
+ END_BATCH();
}
ALLOC_STATE( afs[0], never, AFS_STATE_SIZE, "AFS/afsinst-0", 0 );
ALLOC_STATE( afs[1], never, AFS_STATE_SIZE, "AFS/afsinst-1", 1 );
}
+
+ for (i = 0; i < 5; i++)
+ rmesa->hw.tex[i].emit = tex_emit;
if (rmesa->radeon.radeonScreen->drmSupportsCubeMapsR200) {
ALLOC_STATE( cube[0], tex_cube, CUBE_STATE_SIZE, "CUBE/tex-0", 0 );
ALLOC_STATE( cube[1], tex_cube, CUBE_STATE_SIZE, "CUBE/tex-1", 1 );
#include "texmem.h"
+#include "radeon_mipmap_tree.h"
#include "r200_context.h"
#include "r200_state.h"
#include "r200_ioctl.h"
{
GLboolean is_clamp = GL_FALSE;
GLboolean is_clamp_to_border = GL_FALSE;
+ struct gl_texture_object *tObj = &t->base;
t->pp_txfilter &= ~(R200_CLAMP_S_MASK | R200_CLAMP_T_MASK | R200_BORDER_MODE_D3D);
_mesa_problem(NULL, "bad S wrap mode in %s", __FUNCTION__);
}
- if (t->base.tObj->Target != GL_TEXTURE_1D) {
+ if (tObj->Target != GL_TEXTURE_1D) {
switch ( twrap ) {
case GL_REPEAT:
t->pp_txfilter |= R200_CLAMP_T_WRAP;
}
-/**
- * Allocate space for and load the mesa images into the texture memory block.
- * This will happen before drawing with a new texture, or drawing with a
- * texture after it was swapped out or teximaged again.
- */
-
-static radeonTexObjPtr r200AllocTexObj( struct gl_texture_object *texObj )
-{
- radeonTexObjPtr t;
-
- t = CALLOC_STRUCT( radeon_tex_obj );
- texObj->DriverData = t;
- if ( t != NULL ) {
- if ( R200_DEBUG & DEBUG_TEXTURE ) {
- fprintf( stderr, "%s( %p, %p )\n", __FUNCTION__, (void *)texObj,
- (void *)t );
- }
-
- /* Initialize non-image-dependent parts of the state:
- */
- t->base.tObj = texObj;
- t->border_fallback = GL_FALSE;
-
- make_empty_list( & t->base );
-
- r200SetTexWrap( t, texObj->WrapS, texObj->WrapT, texObj->WrapR );
- r200SetTexMaxAnisotropy( t, texObj->MaxAnisotropy );
- r200SetTexFilter( t, texObj->MinFilter, texObj->MagFilter );
- r200SetTexBorderColor( t, texObj->_BorderChan );
- }
-
- return t;
-}
-
-/* try to find a format which will only need a memcopy */
-static const struct gl_texture_format *
-r200Choose8888TexFormat( GLenum srcFormat, GLenum srcType )
-{
- const GLuint ui = 1;
- const GLubyte littleEndian = *((const GLubyte *) &ui);
-
- if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
- (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
- (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
- (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
- return &_mesa_texformat_rgba8888;
- }
- else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
- (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
- (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
- (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
- return &_mesa_texformat_rgba8888_rev;
- }
- else return _dri_texformat_argb8888;
-}
-
-static const struct gl_texture_format *
-r200ChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
- GLenum format, GLenum type )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- const GLboolean do32bpt =
- ( rmesa->radeon.texture_depth == DRI_CONF_TEXTURE_DEPTH_32 );
- const GLboolean force16bpt =
- ( rmesa->radeon.texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16 );
- (void) format;
-
- switch ( internalFormat ) {
- case 4:
- case GL_RGBA:
- case GL_COMPRESSED_RGBA:
- switch ( type ) {
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- return do32bpt ? _dri_texformat_argb8888 : _dri_texformat_argb1555;
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- return _dri_texformat_argb4444;
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- return _dri_texformat_argb1555;
- default:
- return do32bpt ?
- r200Choose8888TexFormat(format, type) : _dri_texformat_argb4444;
- }
-
- case 3:
- case GL_RGB:
- case GL_COMPRESSED_RGB:
- switch ( type ) {
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- return _dri_texformat_argb4444;
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- return _dri_texformat_argb1555;
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- return _dri_texformat_rgb565;
- default:
- return do32bpt ? _dri_texformat_argb8888 : _dri_texformat_rgb565;
- }
-
- case GL_RGBA8:
- case GL_RGB10_A2:
- case GL_RGBA12:
- case GL_RGBA16:
- return !force16bpt ?
- r200Choose8888TexFormat(format, type) : _dri_texformat_argb4444;
-
- case GL_RGBA4:
- case GL_RGBA2:
- return _dri_texformat_argb4444;
-
- case GL_RGB5_A1:
- return _dri_texformat_argb1555;
-
- case GL_RGB8:
- case GL_RGB10:
- case GL_RGB12:
- case GL_RGB16:
- return !force16bpt ? _dri_texformat_argb8888 : _dri_texformat_rgb565;
-
- case GL_RGB5:
- case GL_RGB4:
- case GL_R3_G3_B2:
- return _dri_texformat_rgb565;
-
- case GL_ALPHA:
- case GL_ALPHA4:
- case GL_ALPHA8:
- case GL_ALPHA12:
- case GL_ALPHA16:
- case GL_COMPRESSED_ALPHA:
- /* can't use a8 format since interpreting hw I8 as a8 would result
- in wrong rgb values (same as alpha value instead of 0). */
- return _dri_texformat_al88;
-
- case 1:
- case GL_LUMINANCE:
- case GL_LUMINANCE4:
- case GL_LUMINANCE8:
- case GL_LUMINANCE12:
- case GL_LUMINANCE16:
- case GL_COMPRESSED_LUMINANCE:
- return _dri_texformat_l8;
-
- case 2:
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE4_ALPHA4:
- case GL_LUMINANCE6_ALPHA2:
- case GL_LUMINANCE8_ALPHA8:
- case GL_LUMINANCE12_ALPHA4:
- case GL_LUMINANCE12_ALPHA12:
- case GL_LUMINANCE16_ALPHA16:
- case GL_COMPRESSED_LUMINANCE_ALPHA:
- return _dri_texformat_al88;
-
- case GL_INTENSITY:
- case GL_INTENSITY4:
- case GL_INTENSITY8:
- case GL_INTENSITY12:
- case GL_INTENSITY16:
- case GL_COMPRESSED_INTENSITY:
- return _dri_texformat_i8;
-
- case GL_YCBCR_MESA:
- if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
- type == GL_UNSIGNED_BYTE)
- return &_mesa_texformat_ycbcr;
- else
- return &_mesa_texformat_ycbcr_rev;
-
- case GL_RGB_S3TC:
- case GL_RGB4_S3TC:
- case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
- return &_mesa_texformat_rgb_dxt1;
-
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- return &_mesa_texformat_rgba_dxt1;
-
- case GL_RGBA_S3TC:
- case GL_RGBA4_S3TC:
- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
- return &_mesa_texformat_rgba_dxt3;
-
- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- return &_mesa_texformat_rgba_dxt5;
-
- default:
- _mesa_problem(ctx,
- "unexpected internalFormat 0x%x in r200ChooseTextureFormat",
- (int) internalFormat);
- return NULL;
- }
-
- return NULL; /* never get here */
-}
-
-
-static GLboolean
-r200ValidateClientStorage( GLcontext *ctx, GLenum target,
- GLint internalFormat,
- GLint srcWidth, GLint srcHeight,
- GLenum format, GLenum type, const void *pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- if ( R200_DEBUG & DEBUG_TEXTURE )
- fprintf(stderr, "intformat %s format %s type %s\n",
- _mesa_lookup_enum_by_nr( internalFormat ),
- _mesa_lookup_enum_by_nr( format ),
- _mesa_lookup_enum_by_nr( type ));
-
- if (!ctx->Unpack.ClientStorage)
- return 0;
-
- if (ctx->_ImageTransferState ||
- texImage->IsCompressed ||
- texObj->GenerateMipmap)
- return 0;
-
-
- /* This list is incomplete, may be different on ppc???
- */
- switch ( internalFormat ) {
- case GL_RGBA:
- if ( format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
- texImage->TexFormat = _dri_texformat_argb8888;
- }
- else
- return 0;
- break;
-
- case GL_RGB:
- if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
- texImage->TexFormat = _dri_texformat_rgb565;
- }
- else
- return 0;
- break;
-
- case GL_YCBCR_MESA:
- if ( format == GL_YCBCR_MESA &&
- type == GL_UNSIGNED_SHORT_8_8_REV_APPLE ) {
- texImage->TexFormat = &_mesa_texformat_ycbcr_rev;
- }
- else if ( format == GL_YCBCR_MESA &&
- (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
- type == GL_UNSIGNED_BYTE)) {
- texImage->TexFormat = &_mesa_texformat_ycbcr;
- }
- else
- return 0;
- break;
-
- default:
- return 0;
- }
-
- /* Could deal with these packing issues, but currently don't:
- */
- if (packing->SkipPixels ||
- packing->SkipRows ||
- packing->SwapBytes ||
- packing->LsbFirst) {
- return 0;
- }
-
- {
- GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth,
- format, type);
-
-
- if ( R200_DEBUG & DEBUG_TEXTURE )
- fprintf(stderr, "%s: srcRowStride %d/%x\n",
- __FUNCTION__, srcRowStride, srcRowStride);
-
- /* Could check this later in upload, pitch restrictions could be
- * relaxed, but would need to store the image pitch somewhere,
- * as packing details might change before image is uploaded:
- */
- if (!r200IsGartMemory( rmesa, pixels, srcHeight * srcRowStride ) ||
- (srcRowStride & 63))
- return 0;
-
-
- /* Have validated that _mesa_transfer_teximage would be a straight
- * memcpy at this point. NOTE: future calls to TexSubImage will
- * overwrite the client data. This is explicitly mentioned in the
- * extension spec.
- */
- texImage->Data = (void *)pixels;
- texImage->IsClientData = GL_TRUE;
- texImage->RowStride = srcRowStride / texImage->TexFormat->TexelBytes;
-
- return 1;
- }
-}
-
-
-static void r200TexImage1D( GLcontext *ctx, GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint border,
- GLenum format, GLenum type, const GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage )
-{
- driTextureObject * t = (driTextureObject *) texObj->DriverData;
-
- if ( t ) {
- driSwapOutTextureObject( t );
- }
- else {
- t = (driTextureObject *) r200AllocTexObj( texObj );
- if (!t) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
- return;
- }
- }
-
- /* Note, this will call ChooseTextureFormat */
- _mesa_store_teximage1d(ctx, target, level, internalFormat,
- width, border, format, type, pixels,
- &ctx->Unpack, texObj, texImage);
-
- t->dirty_images[0] |= (1 << level);
-}
-
-
-static void r200TexSubImage1D( GLcontext *ctx, GLenum target, GLint level,
- GLint xoffset,
- GLsizei width,
- GLenum format, GLenum type,
- const GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage )
-{
- driTextureObject * t = (driTextureObject *) texObj->DriverData;
-
- assert( t ); /* this _should_ be true */
- if ( t ) {
- driSwapOutTextureObject( t );
- }
- else {
- t = (driTextureObject *) r200AllocTexObj( texObj );
- if (!t) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
- return;
- }
- }
-
- _mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
- format, type, pixels, packing, texObj,
- texImage);
-
- t->dirty_images[0] |= (1 << level);
-}
-
-
-static void r200TexImage2D( GLcontext *ctx, GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint height, GLint border,
- GLenum format, GLenum type, const GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage )
-{
- driTextureObject * t = (driTextureObject *) texObj->DriverData;
- GLuint face;
-
- /* which cube face or ordinary 2D image */
- switch (target) {
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
- ASSERT(face < 6);
- break;
- default:
- face = 0;
- }
-
- if ( t != NULL ) {
- driSwapOutTextureObject( t );
- }
- else {
- t = (driTextureObject *) r200AllocTexObj( texObj );
- if (!t) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
- return;
- }
- }
-
- texImage->IsClientData = GL_FALSE;
-
- if (r200ValidateClientStorage( ctx, target,
- internalFormat,
- width, height,
- format, type, pixels,
- packing, texObj, texImage)) {
- if (R200_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "%s: Using client storage\n", __FUNCTION__);
- }
- else {
- if (R200_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__);
-
- /* Normal path: copy (to cached memory) and eventually upload
- * via another copy to GART memory and then a blit... Could
- * eliminate one copy by going straight to (permanent) GART.
- *
- * Note, this will call r200ChooseTextureFormat.
- */
- _mesa_store_teximage2d(ctx, target, level, internalFormat,
- width, height, border, format, type, pixels,
- &ctx->Unpack, texObj, texImage);
-
- t->dirty_images[face] |= (1 << level);
- }
-}
-
-
-static void r200TexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage )
-{
- driTextureObject * t = (driTextureObject *) texObj->DriverData;
- GLuint face;
-
- /* which cube face or ordinary 2D image */
- switch (target) {
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
- ASSERT(face < 6);
- break;
- default:
- face = 0;
- }
-
- assert( t ); /* this _should_ be true */
- if ( t ) {
- driSwapOutTextureObject( t );
- }
- else {
- t = (driTextureObject *) r200AllocTexObj( texObj );
- if (!t) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
- return;
- }
- }
-
- _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
- height, format, type, pixels, packing, texObj,
- texImage);
-
- t->dirty_images[face] |= (1 << level);
-}
-
-
-static void r200CompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint height, GLint border,
- GLsizei imageSize, const GLvoid *data,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage )
-{
- driTextureObject * t = (driTextureObject *) texObj->DriverData;
- GLuint face;
-
- /* which cube face or ordinary 2D image */
- switch (target) {
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
- ASSERT(face < 6);
- break;
- default:
- face = 0;
- }
-
- if ( t != NULL ) {
- driSwapOutTextureObject( t );
- }
- else {
- t = (driTextureObject *) r200AllocTexObj( texObj );
- if (!t) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
- return;
- }
- }
-
- texImage->IsClientData = GL_FALSE;
-/* can't call this, different parameters. Would never evaluate to true anyway currently
- if (r200ValidateClientStorage( ctx, target,
- internalFormat,
- width, height,
- format, type, pixels,
- packing, texObj, texImage)) {
- if (R200_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "%s: Using client storage\n", __FUNCTION__);
- }
- else */{
- if (R200_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__);
-
- /* Normal path: copy (to cached memory) and eventually upload
- * via another copy to GART memory and then a blit... Could
- * eliminate one copy by going straight to (permanent) GART.
- *
- * Note, this will call r200ChooseTextureFormat.
- */
- _mesa_store_compressed_teximage2d(ctx, target, level, internalFormat, width,
- height, border, imageSize, data, texObj, texImage);
-
- t->dirty_images[face] |= (1 << level);
- }
-}
-
-
-static void r200CompressedTexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format,
- GLsizei imageSize, const GLvoid *data,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage )
-{
- driTextureObject * t = (driTextureObject *) texObj->DriverData;
- GLuint face;
-
-
- /* which cube face or ordinary 2D image */
- switch (target) {
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
- ASSERT(face < 6);
- break;
- default:
- face = 0;
- }
-
- assert( t ); /* this _should_ be true */
- if ( t ) {
- driSwapOutTextureObject( t );
- }
- else {
- t = (driTextureObject *) r200AllocTexObj( texObj );
- if (!t) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2D");
- return;
- }
- }
-
- _mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
- height, format, imageSize, data, texObj, texImage);
-
- t->dirty_images[face] |= (1 << level);
-}
-
-
-#if ENABLE_HW_3D_TEXTURE
-static void r200TexImage3D( GLcontext *ctx, GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint height, GLint depth,
- GLint border,
- GLenum format, GLenum type, const GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage )
-{
- driTextureObject * t = (driTextureObject *) texObj->DriverData;
-
- if ( t ) {
- driSwapOutTextureObject( t );
- }
- else {
- t = (driTextureObject *) r200AllocTexObj( texObj );
- if (!t) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
- return;
- }
- }
-
- texImage->IsClientData = GL_FALSE;
-
-#if 0
- if (r200ValidateClientStorage( ctx, target,
- internalFormat,
- width, height,
- format, type, pixels,
- packing, texObj, texImage)) {
- if (R200_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "%s: Using client storage\n", __FUNCTION__);
- }
- else
-#endif
- {
- if (R200_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__);
-
- /* Normal path: copy (to cached memory) and eventually upload
- * via another copy to GART memory and then a blit... Could
- * eliminate one copy by going straight to (permanent) GART.
- *
- * Note, this will call r200ChooseTextureFormat.
- */
- _mesa_store_teximage3d(ctx, target, level, internalFormat,
- width, height, depth, border,
- format, type, pixels,
- &ctx->Unpack, texObj, texImage);
-
- t->dirty_images[0] |= (1 << level);
- }
-}
-#endif
-
-
-#if ENABLE_HW_3D_TEXTURE
-static void
-r200TexSubImage3D( GLcontext *ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type,
- const GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage )
-{
- driTextureObject * t = (driTextureObject *) texObj->DriverData;
-
-/* fprintf(stderr, "%s\n", __FUNCTION__); */
-
- assert( t ); /* this _should_ be true */
- if ( t ) {
- driSwapOutTextureObject( t );
- }
- else {
- t = (driTextureObject *) r200AllocTexObj( texObj );
- if (!t) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
- return;
- }
- texObj->DriverData = t;
- }
-
- _mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset,
- width, height, depth,
- format, type, pixels, packing, texObj, texImage);
-
- t->dirty_images[0] |= (1 << level);
-}
-#endif
struct gl_texture_object *texObj,
GLenum pname, const GLfloat *params )
{
- radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData;
+ radeonTexObj* t = radeon_tex_obj(texObj);
if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) {
fprintf( stderr, "%s( %s )\n", __FUNCTION__,
}
-
-static void r200BindTexture( GLcontext *ctx, GLenum target,
- struct gl_texture_object *texObj )
-{
- if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) {
- fprintf( stderr, "%s( %p ) unit=%d\n", __FUNCTION__, (void *)texObj,
- ctx->Texture.CurrentUnit );
- }
-
- if ( (target == GL_TEXTURE_1D)
- || (target == GL_TEXTURE_2D)
-#if ENABLE_HW_3D_TEXTURE
- || (target == GL_TEXTURE_3D)
-#endif
- || (target == GL_TEXTURE_CUBE_MAP)
- || (target == GL_TEXTURE_RECTANGLE_NV) ) {
- assert( texObj->DriverData != NULL );
- }
-}
-
-
-static void r200DeleteTexture( GLcontext *ctx,
- struct gl_texture_object *texObj )
+static void r200DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj)
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
- driTextureObject * t = (driTextureObject *) texObj->DriverData;
-
- if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) {
- fprintf( stderr, "%s( %p (target = %s) )\n", __FUNCTION__, (void *)texObj,
- _mesa_lookup_enum_by_nr( texObj->Target ) );
+ radeonTexObj* t = radeon_tex_obj(texObj);
+
+ if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
+ fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__,
+ (void *)texObj,
+ _mesa_lookup_enum_by_nr(texObj->Target));
+ }
+
+ if (rmesa) {
+ int i;
+ R200_FIREVERTICES(rmesa);
+ for ( i = 0 ; i < rmesa->radeon.glCtx->Const.MaxTextureUnits ; i++ ) {
+ if ( t == rmesa->state.texture.unit[i].texobj ) {
+ rmesa->state.texture.unit[i].texobj = NULL;
+ rmesa->hw.tex[i].dirty = GL_FALSE;
+ rmesa->hw.cube[i].dirty = GL_FALSE;
+ }
+ }
}
-
- if ( t != NULL ) {
- if ( rmesa ) {
- R200_FIREVERTICES( rmesa );
- }
-
- driDestroyTextureObject( t );
+
+ if (t->mt) {
+ radeon_miptree_unreference(t->mt);
+ t->mt = 0;
}
- /* Free mipmap images and the texture object itself */
_mesa_delete_texture_object(ctx, texObj);
}
* Called via ctx->Driver.NewTextureObject.
* Note: this function will be called during context creation to
* allocate the default texture objects.
- * Note: we could use containment here to 'derive' the driver-specific
- * texture object from the core mesa gl_texture_object. Not done at this time.
* Fixup MaxAnisotropy according to user preference.
*/
-static struct gl_texture_object *
-r200NewTextureObject( GLcontext *ctx, GLuint name, GLenum target )
+static struct gl_texture_object *r200NewTextureObject(GLcontext * ctx,
+ GLuint name,
+ GLenum target)
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
- struct gl_texture_object *obj;
- obj = _mesa_new_texture_object(ctx, name, target);
- if (!obj)
- return NULL;
- obj->MaxAnisotropy = rmesa->radeon.initialMaxAnisotropy;
- r200AllocTexObj( obj );
- return obj;
+ radeonTexObj* t = CALLOC_STRUCT(radeon_tex_obj);
+
+
+ if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
+ fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__,
+ t, _mesa_lookup_enum_by_nr(target));
+ }
+
+ _mesa_initialize_texture_object(&t->base, name, target);
+ t->base.MaxAnisotropy = rmesa->radeon.initialMaxAnisotropy;
+
+ /* Initialize hardware state */
+ r200SetTexWrap( t, t->base.WrapS, t->base.WrapT, t->base.WrapR );
+ r200SetTexMaxAnisotropy( t, t->base.MaxAnisotropy );
+ r200SetTexFilter(t, t->base.MinFilter, t->base.MagFilter);
+ r200SetTexBorderColor(t, t->base._BorderChan);
+
+ return &t->base;
}
+
void r200InitTextureFuncs( struct dd_function_table *functions )
{
/* Note: we only plug in the functions we implement in the driver
* since _mesa_init_driver_functions() was already called.
*/
- functions->ChooseTextureFormat = r200ChooseTextureFormat;
- functions->TexImage1D = r200TexImage1D;
- functions->TexImage2D = r200TexImage2D;
+ functions->ChooseTextureFormat = radeonChooseTextureFormat;
+ functions->TexImage1D = radeonTexImage1D;
+ functions->TexImage2D = radeonTexImage2D;
#if ENABLE_HW_3D_TEXTURE
- functions->TexImage3D = r200TexImage3D;
+ functions->TexImage3D = radeonTexImage3D;
#else
functions->TexImage3D = _mesa_store_teximage3d;
#endif
- functions->TexSubImage1D = r200TexSubImage1D;
- functions->TexSubImage2D = r200TexSubImage2D;
+ functions->TexSubImage1D = radeonTexSubImage1D;
+ functions->TexSubImage2D = radeonTexSubImage2D;
#if ENABLE_HW_3D_TEXTURE
- functions->TexSubImage3D = r200TexSubImage3D;
+ functions->TexSubImage3D = radeonTexSubImage3D;
#else
functions->TexSubImage3D = _mesa_store_texsubimage3d;
#endif
functions->NewTextureObject = r200NewTextureObject;
- functions->BindTexture = r200BindTexture;
+ // functions->BindTexture = r200BindTexture;
functions->DeleteTexture = r200DeleteTexture;
functions->IsTextureResident = driIsTextureResident;
functions->TexParameter = r200TexParameter;
functions->TexGen = r200TexGen;
- functions->CompressedTexImage2D = r200CompressedTexImage2D;
- functions->CompressedTexSubImage2D = r200CompressedTexSubImage2D;
+ functions->CompressedTexImage2D = radeonCompressedTexImage2D;
+ functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D;
+
+ functions->GenerateMipmap = radeon_generate_mipmap;
+
+ functions->NewTextureImage = radeonNewTextureImage;
+ functions->FreeTexImageData = radeonFreeTexImageData;
+ functions->MapTexture = radeonMapTexture;
+ functions->UnmapTexture = radeonUnmapTexture;
driInitTextureFormats();
-#if 000
- /* moved or obsolete code */
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- driInitTextureObjects( ctx, & rmesa->swapped,
- DRI_TEXMGR_DO_TEXTURE_1D
- | DRI_TEXMGR_DO_TEXTURE_2D );
-
- /* Hack: r200NewTextureObject is not yet installed when the
- * default textures are created. Therefore set MaxAnisotropy of the
- * default 2D texture now. */
- ctx->Shared->Default2D->MaxAnisotropy = driQueryOptionf (&rmesa->optionCache,
- "def_max_anisotropy");
-#endif
}
#include <unistd.h> /* for usleep() */
-
+#if 0
/**
* Destroy any device-dependent state associated with the texture. This may
* include NULLing out hardware state that points to the texture.
return 0;
}
+#endif
#include "main/texobj.h"
#include "main/enums.h"
+#include "common_context.h"
+#include "radeon_mipmap_tree.h"
#include "r200_context.h"
#include "r200_state.h"
#include "r200_ioctl.h"
#undef _ALPHA
#undef _INVALID
+#if 0
+
/**
* This function computes the number of bytes of storage needed for
* the given texture object (all mipmap levels, all cube faces).
}
}
- texelBytes = baseImage->TexFormat->TexelBytes;
+
/* Compute which mipmap levels we really want to send to the hardware.
*/
}
}
if (tObj->Target != GL_TEXTURE_RECTANGLE_NV) {
- /* we can set macro tiling even for small textures, they will be untiled anyway */
+ /* we can set macro tiling even for small textures, they will be untiled anyway */
t->tile_bits |= R200_TXO_MACRO_TILE;
}
}
/* FYI: r200UploadTexImages( rmesa, t ) used to be called here */
}
-
+#endif
/* ================================================================
cmd[TEX_PP_TXOFFSET_OLDDRM] = texobj->pp_txoffset;
}
- if (texobj->base.tObj->Target == GL_TEXTURE_CUBE_MAP) {
+ if (texobj->base.Target == GL_TEXTURE_CUBE_MAP) {
GLuint *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
- GLuint bytesPerFace = texobj->base.totalSize / 6;
- ASSERT(texobj->base.totalSize % 6 == 0);
+ // GLuint bytesPerFace = texobj->base.totalSize / 6;
+ // ASSERT(texobj->base.totalSize % 6 == 0);
+ GLuint bytesPerFace = 1; // TODO
R200_STATECHANGE( rmesa, cube[unit] );
cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
texobj->dirty_state &= ~(1<<unit);
}
-
static void set_texgen_matrix( r200ContextPtr rmesa,
GLuint unit,
const GLfloat *s_plane,
} else {
tgcm |= R200_TEXGEN_COMP_T << (unit * 4);
}
-
if (texUnit->TexGenEnabled & R_BIT) {
if (texUnit->GenModeR != mode)
mixed_fallback = GL_TRUE;
return GL_TRUE;
}
-
-static void disable_tex( GLcontext *ctx, int unit )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
-
- if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE<<unit)) {
- /* Texture unit disabled */
- if ( rmesa->state.texture.unit[unit].texobj != NULL ) {
- /* The old texture is no longer bound to this texture unit.
- * Mark it as such.
- */
-
- rmesa->state.texture.unit[unit].texobj->base.bound &= ~(1UL << unit);
- rmesa->state.texture.unit[unit].texobj = NULL;
- }
-
- R200_STATECHANGE( rmesa, ctx );
- rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_TEX_0_ENABLE << unit);
-
- R200_STATECHANGE( rmesa, vtx );
- rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
-
- if (rmesa->radeon.TclFallback & (R200_TCL_FALLBACK_TEXGEN_0<<unit)) {
- TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
- }
-
- /* Actually want to keep all units less than max active texture
- * enabled, right? Fix this for >2 texunits.
- */
-
- {
- GLuint tmp = rmesa->TexGenEnabled;
-
- rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit);
- rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit);
- rmesa->TexGenNeedNormals[unit] = GL_FALSE;
- rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
-
- if (tmp != rmesa->TexGenEnabled) {
- rmesa->recheck_texgen[unit] = GL_TRUE;
- rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
- }
- }
- }
-}
-
void set_re_cntl_d3d( GLcontext *ctx, int unit, GLboolean use_d3d )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
}
}
-static GLboolean enable_tex_2d( GLcontext *ctx, int unit )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- struct gl_texture_object *tObj = texUnit->_Current;
- radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
-
- /* Need to load the 2d images associated with this unit.
- */
- if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) {
- t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2;
- t->base.dirty_images[0] = ~0;
- }
-
- ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D);
-
- if ( t->base.dirty_images[0] ) {
- R200_FIREVERTICES( rmesa );
- r200SetTexImages( rmesa, tObj );
- r200UploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 );
- if ( !t->base.memBlock && !t->image_override )
- return GL_FALSE;
- }
-
- set_re_cntl_d3d( ctx, unit, GL_FALSE );
-
- return GL_TRUE;
-}
-
-#if ENABLE_HW_3D_TEXTURE
-static GLboolean enable_tex_3d( GLcontext *ctx, int unit )
+/**
+ * Compute the cached hardware register values for the given texture object.
+ *
+ * \param rmesa Context pointer
+ * \param t the r300 texture object
+ */
+static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t)
{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- struct gl_texture_object *tObj = texUnit->_Current;
- radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
-
- /* Need to load the 3d images associated with this unit.
- */
- if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) {
- t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2;
- t->base.dirty_images[0] = ~0;
+ const struct gl_texture_image *firstImage =
+ t->base.Image[0][t->mt->firstLevel];
+ GLint log2Width, log2Height, log2Depth, texelBytes;
+
+ log2Width = firstImage->WidthLog2;
+ log2Height = firstImage->HeightLog2;
+ log2Depth = firstImage->DepthLog2;
+ texelBytes = firstImage->TexFormat->TexelBytes;
+
+
+ if (!t->image_override) {
+ if (VALID_FORMAT(firstImage->TexFormat->MesaFormat)) {
+ const struct tx_table *table = _mesa_little_endian() ? tx_table_le :
+ tx_table_be;
+
+ t->pp_txformat &= ~(R200_TXFORMAT_FORMAT_MASK |
+ R200_TXFORMAT_ALPHA_IN_MAP);
+ t->pp_txfilter &= ~R200_YUV_TO_RGB;
+
+ t->pp_txformat |= table[ firstImage->TexFormat->MesaFormat ].format;
+ t->pp_txfilter |= table[ firstImage->TexFormat->MesaFormat ].filter;
+ } else {
+ _mesa_problem(NULL, "unexpected texture format in %s",
+ __FUNCTION__);
+ return;
+ }
}
+
+ t->pp_txfilter &= ~R200_MAX_MIP_LEVEL_MASK;
+ t->pp_txfilter |= (t->mt->lastLevel - t->mt->firstLevel) << R200_MAX_MIP_LEVEL_SHIFT;
+
+ t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK |
+ R200_TXFORMAT_HEIGHT_MASK |
+ R200_TXFORMAT_CUBIC_MAP_ENABLE |
+ R200_TXFORMAT_F5_WIDTH_MASK |
+ R200_TXFORMAT_F5_HEIGHT_MASK);
+ t->pp_txformat |= ((log2Width << R200_TXFORMAT_WIDTH_SHIFT) |
+ (log2Height << R200_TXFORMAT_HEIGHT_SHIFT));
+
+ t->tile_bits = 0;
+
+ // if (t->base.Target == GL_TEXTURE_CUBE_MAP)
+ // t->pp_txformat |= R300_TX_FORMAT_CUBIC_MAP;
+ // if (t->base.Target == GL_TEXTURE_3D)
+ // t->pp_txformat |= R300_TX_FORMAT_3D;
+
+ t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK);
+ if (t->base.Target == GL_TEXTURE_3D) {
+ t->pp_txformat_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT);
+ t->pp_txformat_x |= R200_TEXCOORD_VOLUME;
- ASSERT(tObj->Target == GL_TEXTURE_3D);
-
- /* R100 & R200 do not support mipmaps for 3D textures.
- */
- if ( (tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR) ) {
- return GL_FALSE;
}
-
- if ( t->base.dirty_images[0] ) {
- R200_FIREVERTICES( rmesa );
- r200SetTexImages( rmesa, tObj );
- r200UploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 );
- if ( !t->base.memBlock )
- return GL_FALSE;
+ else if (t->base.Target == GL_TEXTURE_CUBE_MAP) {
+ ASSERT(log2Width == log2Height);
+ t->pp_txformat |= ((log2Width << R200_TXFORMAT_F5_WIDTH_SHIFT) |
+ (log2Height << R200_TXFORMAT_F5_HEIGHT_SHIFT) |
+ /* don't think we need this bit, if it exists at all - fglrx does not set it */
+ (R200_TXFORMAT_CUBIC_MAP_ENABLE));
+ t->pp_txformat_x |= R200_TEXCOORD_CUBIC_ENV;
+ t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) |
+ (log2Height << R200_FACE_HEIGHT_1_SHIFT) |
+ (log2Width << R200_FACE_WIDTH_2_SHIFT) |
+ (log2Height << R200_FACE_HEIGHT_2_SHIFT) |
+ (log2Width << R200_FACE_WIDTH_3_SHIFT) |
+ (log2Height << R200_FACE_HEIGHT_3_SHIFT) |
+ (log2Width << R200_FACE_WIDTH_4_SHIFT) |
+ (log2Height << R200_FACE_HEIGHT_4_SHIFT));
}
-
- set_re_cntl_d3d( ctx, unit, GL_TRUE );
-
- return GL_TRUE;
-}
-#endif
-
-static GLboolean enable_tex_cube( GLcontext *ctx, int unit )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- struct gl_texture_object *tObj = texUnit->_Current;
- radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
- GLuint face;
-
- /* Need to load the 2d images associated with this unit.
- */
- if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) {
- t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2;
- for (face = 0; face < 6; face++)
- t->base.dirty_images[face] = ~0;
+ else {
+ /* If we don't in fact send enough texture coordinates, q will be 1,
+ * making TEXCOORD_PROJ act like TEXCOORD_NONPROJ (Right?)
+ */
+ t->pp_txformat_x |= R200_TEXCOORD_PROJ;
}
- ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP);
-
- if ( t->base.dirty_images[0] || t->base.dirty_images[1] ||
- t->base.dirty_images[2] || t->base.dirty_images[3] ||
- t->base.dirty_images[4] || t->base.dirty_images[5] ) {
- /* flush */
- R200_FIREVERTICES( rmesa );
- /* layout memory space, once for all faces */
- r200SetTexImages( rmesa, tObj );
- }
+ t->pp_txsize = (((firstImage->Width - 1) << R200_PP_TX_WIDTHMASK_SHIFT)
+ | ((firstImage->Height - 1) << R200_PP_TX_HEIGHTMASK_SHIFT));
- /* upload (per face) */
- for (face = 0; face < 6; face++) {
- if (t->base.dirty_images[face]) {
- r200UploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, face );
- }
- }
-
- if ( !t->base.memBlock ) {
- /* texmem alloc failed, use s/w fallback */
- return GL_FALSE;
+ if ( !t->image_override ) {
+ if (firstImage->IsCompressed)
+ t->pp_txpitch = (firstImage->Width + 63) & ~(63);
+ else
+ t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63);
+ t->pp_txpitch -= 32;
}
- set_re_cntl_d3d( ctx, unit, GL_TRUE );
-
- return GL_TRUE;
-}
-
-static GLboolean enable_tex_rect( GLcontext *ctx, int unit )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- struct gl_texture_object *tObj = texUnit->_Current;
- radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
-
- if (!(t->pp_txformat & R200_TXFORMAT_NON_POWER2)) {
+ if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
- t->base.dirty_images[0] = ~0;
- }
-
- ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV);
+ // t->pp_txsize |= R300_TX_SIZE_TXPITCH_EN;
- if ( t->base.dirty_images[0] ) {
- R200_FIREVERTICES( rmesa );
- r200SetTexImages( rmesa, tObj );
- r200UploadTexImages( rmesa, (radeonTexObjPtr) tObj->DriverData, 0 );
- if ( !t->base.memBlock &&
- !t->image_override &&
- !rmesa->prefer_gart_client_texturing )
- return GL_FALSE;
}
-
- set_re_cntl_d3d( ctx, unit, GL_FALSE );
-
- return GL_TRUE;
+
}
-
-static GLboolean update_tex_common( GLcontext *ctx, int unit )
+static GLboolean r200_validate_texture(GLcontext *ctx, struct gl_texture_object *texObj, int unit)
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- struct gl_texture_object *tObj = texUnit->_Current;
- radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData;
-
- /* Fallback if there's a texture border */
- if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 )
- return GL_FALSE;
-
- /* Update state if this is a different texture object to last
- * time.
- */
- if ( rmesa->state.texture.unit[unit].texobj != t ) {
- if ( rmesa->state.texture.unit[unit].texobj != NULL ) {
- /* The old texture is no longer bound to this texture unit.
- * Mark it as such.
- */
+ radeonTexObj *t = radeon_tex_obj(texObj);
- rmesa->state.texture.unit[unit].texobj->base.bound &=
- ~(1UL << unit);
- }
-
- rmesa->state.texture.unit[unit].texobj = t;
- t->base.bound |= (1UL << unit);
- t->dirty_state |= 1<<unit;
- driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */
- }
+ if (!radeon_validate_texture_miptree(ctx, texObj))
+ return GL_FALSE;
+ r200_validate_texgen(ctx, unit);
+ /* Configure the hardware registers (more precisely, the cached version
+ * of the hardware registers). */
+ setup_hardware_state(rmesa, t);
- /* Newly enabled?
- */
- if ( 1|| !(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE<<unit))) {
- R200_STATECHANGE( rmesa, ctx );
- rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << unit;
- R200_STATECHANGE( rmesa, vtx );
- rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
- rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3);
- rmesa->recheck_texgen[unit] = GL_TRUE;
- }
+ if (texObj->Target == GL_TEXTURE_RECTANGLE_NV ||
+ texObj->Target == GL_TEXTURE_2D)
+ set_re_cntl_d3d( ctx, unit, GL_FALSE );
+ else
+ set_re_cntl_d3d( ctx, unit, GL_TRUE );
+ R200_STATECHANGE( rmesa, ctx );
+ rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << unit;
+
+ R200_STATECHANGE( rmesa, vtx );
+ rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
+ rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3);
+ rmesa->recheck_texgen[unit] = GL_TRUE;
if (t->dirty_state & (1<<unit)) {
import_tex_obj_state( rmesa, unit, t );
}
- if (rmesa->recheck_texgen[unit]) {
- GLboolean fallback = !r200_validate_texgen( ctx, unit );
- TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), fallback);
- rmesa->recheck_texgen[unit] = 0;
- rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
- }
-
- FALLBACK( rmesa, R200_FALLBACK_BORDER_MODE, t->border_fallback );
- return !t->border_fallback;
+ t->dirty_state = R200_TEX_ALL;
+
+ t->validated = GL_TRUE;
+ return GL_TRUE;
}
-
-
-static GLboolean r200UpdateTextureUnit( GLcontext *ctx, int unit )
+GLboolean r200UpdateTextureUnit(GLcontext *ctx, int unit)
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLuint unitneeded = rmesa->state.texture.unit[unit].unitneeded;
- if ( unitneeded & (TEXTURE_RECT_BIT) ) {
- return (enable_tex_rect( ctx, unit ) &&
- update_tex_common( ctx, unit ));
- }
- else if ( unitneeded & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) {
- return (enable_tex_2d( ctx, unit ) &&
- update_tex_common( ctx, unit ));
- }
-#if ENABLE_HW_3D_TEXTURE
- else if ( unitneeded & (TEXTURE_3D_BIT) ) {
- return (enable_tex_3d( ctx, unit ) &&
- update_tex_common( ctx, unit ));
- }
-#endif
- else if ( unitneeded & (TEXTURE_CUBE_BIT) ) {
- return (enable_tex_cube( ctx, unit ) &&
- update_tex_common( ctx, unit ));
- }
- else if ( unitneeded ) {
- return GL_FALSE;
- }
- else {
- disable_tex( ctx, unit );
- return GL_TRUE;
- }
+ if (!unitneeded)
+ return GL_TRUE;
+
+ if (!r200_validate_texture(ctx, ctx->Texture.Unit[unit]._Current, unit)) {
+ _mesa_warning(ctx,
+ "failed to validate texture for unit %d.\n",
+ unit);
+ rmesa->state.texture.unit[unit].texobj = NULL;
+ return GL_FALSE;
+ }
+
+ rmesa->state.texture.unit[unit].texobj = radeon_tex_obj(ctx->Texture.Unit[unit]._Current);
+ return GL_TRUE;
}
R200_STATECHANGE(rmesa, tex[1]);
rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_1_ENABLE;
if (!(rmesa->hw.cst.cmd[CST_PP_CNTL_X] & R200_PPX_TEX_1_ENABLE))
- rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
+ rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] |= R200_TXFORMAT_LOOKUP_DISABLE;
}
else if (!ctx->ATIFragmentShader._Enabled) {
R300_WAIT_3D | R300_WAIT_3D_CLEAN));
}
+static void r300_vtbl_flush_vertices(radeonContextPtr rmesa)
+{
+ R300_FIREVERTICES(((r300ContextPtr)rmesa));
+}
+
static void r300_init_vtbl(radeonContextPtr radeon)
{
radeon->vtbl.get_lock = r300_get_lock;
*/
driParseConfigFiles(&r300->radeon.optionCache, &screen->optionCache,
screen->driScreen->myNum, "r300");
- r300->initialMaxAnisotropy = driQueryOptionf(&r300->radeon.optionCache,
+ r300->radeon.initialMaxAnisotropy = driQueryOptionf(&r300->radeon.optionCache,
"def_max_anisotropy");
/* Init default driver functions then plug in our R300-specific functions
}
/* Init r300 context data */
- r300->texture_depth = driQueryOptioni(&r300->radeon.optionCache,
+ r300->radeon.texture_depth = driQueryOptioni(&r300->radeon.optionCache,
"texture_depth");
- if (r300->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
- r300->texture_depth = (screen->cpp == 4) ?
+ if (r300->radeon.texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
+ r300->radeon.texture_depth = (screen->cpp == 4) ?
DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
/* Set the maximum texture size small enough that we can guarentee that
/* Vertex buffers
*/
- GLuint NewGLState;
-
- int texture_depth;
- float initialMaxAnisotropy;
-
GLvector4f dummy_attrib[_TNL_ATTRIB_MAX];
GLvector4f *temp_attrib[_TNL_ATTRIB_MAX];
ctx = rmesa->radeon.glCtx;
- if (rmesa->NewGLState && hw_tcl_on) {
- rmesa->NewGLState = 0;
+ if (rmesa->radeon.NewGLState && hw_tcl_on) {
+ rmesa->radeon.NewGLState = 0;
for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
rmesa->temp_attrib[i] =
r300UpdateStateParameters(ctx, new_state);
- r300->NewGLState |= new_state;
+ r300->radeon.NewGLState |= new_state;
}
/**
t->pp_border_color = PACK_COLOR_8888(c[3], c[0], c[1], c[2]);
}
-/* try to find a format which will only need a memcopy */
-static const struct gl_texture_format *r300Choose8888TexFormat(GLenum srcFormat,
- GLenum srcType)
-{
- const GLuint ui = 1;
- const GLubyte littleEndian = *((const GLubyte *)&ui);
-
- if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
- (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
- (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
- (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
- return &_mesa_texformat_rgba8888;
- } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
- (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
- (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
- (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
- return &_mesa_texformat_rgba8888_rev;
- } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
- srcType == GL_UNSIGNED_INT_8_8_8_8)) {
- return &_mesa_texformat_argb8888_rev;
- } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
- srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
- return &_mesa_texformat_argb8888;
- } else
- return _dri_texformat_argb8888;
-}
-
-static const struct gl_texture_format *r300ChooseTextureFormat(GLcontext * ctx,
- GLint
- internalFormat,
- GLenum format,
- GLenum type)
-{
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
- const GLboolean do32bpt =
- (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32);
- const GLboolean force16bpt =
- (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16);
- (void)format;
-
-#if 0
- fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n",
- _mesa_lookup_enum_by_nr(internalFormat), internalFormat,
- _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format));
- fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt);
-#endif
-
- switch (internalFormat) {
- case 4:
- case GL_RGBA:
- case GL_COMPRESSED_RGBA:
- switch (type) {
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- return do32bpt ? _dri_texformat_argb8888 :
- _dri_texformat_argb1555;
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- return _dri_texformat_argb4444;
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- return _dri_texformat_argb1555;
- default:
- return do32bpt ? r300Choose8888TexFormat(format, type) :
- _dri_texformat_argb4444;
- }
-
- case 3:
- case GL_RGB:
- case GL_COMPRESSED_RGB:
- switch (type) {
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- return _dri_texformat_argb4444;
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- return _dri_texformat_argb1555;
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- return _dri_texformat_rgb565;
- default:
- return do32bpt ? _dri_texformat_argb8888 :
- _dri_texformat_rgb565;
- }
-
- case GL_RGBA8:
- case GL_RGB10_A2:
- case GL_RGBA12:
- case GL_RGBA16:
- return !force16bpt ?
- r300Choose8888TexFormat(format,
- type) : _dri_texformat_argb4444;
-
- case GL_RGBA4:
- case GL_RGBA2:
- return _dri_texformat_argb4444;
-
- case GL_RGB5_A1:
- return _dri_texformat_argb1555;
-
- case GL_RGB8:
- case GL_RGB10:
- case GL_RGB12:
- case GL_RGB16:
- return !force16bpt ? _dri_texformat_argb8888 :
- _dri_texformat_rgb565;
-
- case GL_RGB5:
- case GL_RGB4:
- case GL_R3_G3_B2:
- return _dri_texformat_rgb565;
-
- case GL_ALPHA:
- case GL_ALPHA4:
- case GL_ALPHA8:
- case GL_ALPHA12:
- case GL_ALPHA16:
- case GL_COMPRESSED_ALPHA:
- return _dri_texformat_a8;
-
- case 1:
- case GL_LUMINANCE:
- case GL_LUMINANCE4:
- case GL_LUMINANCE8:
- case GL_LUMINANCE12:
- case GL_LUMINANCE16:
- case GL_COMPRESSED_LUMINANCE:
- return _dri_texformat_l8;
-
- case 2:
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE4_ALPHA4:
- case GL_LUMINANCE6_ALPHA2:
- case GL_LUMINANCE8_ALPHA8:
- case GL_LUMINANCE12_ALPHA4:
- case GL_LUMINANCE12_ALPHA12:
- case GL_LUMINANCE16_ALPHA16:
- case GL_COMPRESSED_LUMINANCE_ALPHA:
- return _dri_texformat_al88;
-
- case GL_INTENSITY:
- case GL_INTENSITY4:
- case GL_INTENSITY8:
- case GL_INTENSITY12:
- case GL_INTENSITY16:
- case GL_COMPRESSED_INTENSITY:
- return _dri_texformat_i8;
-
- case GL_YCBCR_MESA:
- if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
- type == GL_UNSIGNED_BYTE)
- return &_mesa_texformat_ycbcr;
- else
- return &_mesa_texformat_ycbcr_rev;
-
- case GL_RGB_S3TC:
- case GL_RGB4_S3TC:
- case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
- return &_mesa_texformat_rgb_dxt1;
-
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- return &_mesa_texformat_rgba_dxt1;
-
- case GL_RGBA_S3TC:
- case GL_RGBA4_S3TC:
- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
- return &_mesa_texformat_rgba_dxt3;
-
- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- return &_mesa_texformat_rgba_dxt5;
-
- case GL_ALPHA16F_ARB:
- return &_mesa_texformat_alpha_float16;
- case GL_ALPHA32F_ARB:
- return &_mesa_texformat_alpha_float32;
- case GL_LUMINANCE16F_ARB:
- return &_mesa_texformat_luminance_float16;
- case GL_LUMINANCE32F_ARB:
- return &_mesa_texformat_luminance_float32;
- case GL_LUMINANCE_ALPHA16F_ARB:
- return &_mesa_texformat_luminance_alpha_float16;
- case GL_LUMINANCE_ALPHA32F_ARB:
- return &_mesa_texformat_luminance_alpha_float32;
- case GL_INTENSITY16F_ARB:
- return &_mesa_texformat_intensity_float16;
- case GL_INTENSITY32F_ARB:
- return &_mesa_texformat_intensity_float32;
- case GL_RGB16F_ARB:
- return &_mesa_texformat_rgba_float16;
- case GL_RGB32F_ARB:
- return &_mesa_texformat_rgba_float32;
- case GL_RGBA16F_ARB:
- return &_mesa_texformat_rgba_float16;
- case GL_RGBA32F_ARB:
- return &_mesa_texformat_rgba_float32;
-
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_COMPONENT16:
- case GL_DEPTH_COMPONENT24:
- case GL_DEPTH_COMPONENT32:
-#if 0
- switch (type) {
- case GL_UNSIGNED_BYTE:
- case GL_UNSIGNED_SHORT:
- return &_mesa_texformat_z16;
- case GL_UNSIGNED_INT:
- return &_mesa_texformat_z32;
- case GL_UNSIGNED_INT_24_8_EXT:
- default:
- return &_mesa_texformat_z24_s8;
- }
-#else
- return &_mesa_texformat_z16;
-#endif
-
- default:
- _mesa_problem(ctx,
- "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
- (int)internalFormat);
- return NULL;
- }
-
- return NULL; /* never get here */
-}
-
-/**
- * All glTexImage calls go through this function.
- */
-static void r300_teximage(
- GLcontext *ctx, int dims,
- GLint face, GLint level,
- GLint internalFormat,
- GLint width, GLint height, GLint depth,
- GLsizei imageSize,
- GLenum format, GLenum type, const GLvoid * pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage,
- int compressed)
-{
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
- radeonTexObj* t = radeon_tex_obj(texObj);
- radeon_texture_image* image = get_radeon_texture_image(texImage);
-
- R300_FIREVERTICES(rmesa);
-
- t->validated = GL_FALSE;
-
- /* Choose and fill in the texture format for this image */
- texImage->TexFormat = r300ChooseTextureFormat(ctx, internalFormat, format, type);
- _mesa_set_fetch_functions(texImage, dims);
-
- if (texImage->TexFormat->TexelBytes == 0) {
- texImage->IsCompressed = GL_TRUE;
- texImage->CompressedSize =
- ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
- texImage->Height, texImage->Depth,
- texImage->TexFormat->MesaFormat);
- } else {
- texImage->IsCompressed = GL_FALSE;
- texImage->CompressedSize = 0;
- }
-
- /* Allocate memory for image */
- radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */
-
- if (!t->mt)
- radeon_try_alloc_miptree(&rmesa->radeon, t, texImage, face, level);
- if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) {
- image->mt = t->mt;
- image->mtlevel = level - t->mt->firstLevel;
- image->mtface = face;
- radeon_miptree_reference(t->mt);
- } else {
- int size;
- if (texImage->IsCompressed) {
- size = texImage->CompressedSize;
- } else {
- size = texImage->Width * texImage->Height * texImage->Depth * texImage->TexFormat->TexelBytes;
- }
- texImage->Data = _mesa_alloc_texmemory(size);
- }
-
- /* Upload texture image; note that the spec allows pixels to be NULL */
- if (compressed) {
- pixels = _mesa_validate_pbo_compressed_teximage(
- ctx, imageSize, pixels, packing, "glCompressedTexImage");
- } else {
- pixels = _mesa_validate_pbo_teximage(
- ctx, dims, width, height, depth,
- format, type, pixels, packing, "glTexImage");
- }
-
- if (pixels) {
- radeon_teximage_map(image, GL_TRUE);
-
- if (compressed) {
- memcpy(texImage->Data, pixels, imageSize);
- } else {
- GLuint dstRowStride;
- if (image->mt) {
- radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
- dstRowStride = lvl->rowstride;
- } else {
- dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
- }
- if (!texImage->TexFormat->StoreImage(ctx, dims,
- texImage->_BaseFormat,
- texImage->TexFormat,
- texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
- dstRowStride,
- texImage->ImageOffsets,
- width, height, depth,
- format, type, pixels, packing))
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
- }
-
- radeon_teximage_unmap(image);
- }
-
- _mesa_unmap_teximage_pbo(ctx, packing);
-
- /* SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- ctx->Driver.GenerateMipmap(ctx, texObj->Target, texObj);
- }
-}
-
-static void r300TexImage1D(GLcontext * ctx, GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint border,
- GLenum format, GLenum type, const GLvoid * pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- r300_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1,
- 0, format, type, pixels, packing, texObj, texImage, 0);
-}
-
-static void r300TexImage2D(GLcontext * ctx, GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint height, GLint border,
- GLenum format, GLenum type, const GLvoid * pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- GLuint face = radeon_face_for_target(target);
-
- r300_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
- 0, format, type, pixels, packing, texObj, texImage, 0);
-}
-
-static void r300CompressedTexImage2D(GLcontext * ctx, GLenum target,
- GLint level, GLint internalFormat,
- GLint width, GLint height, GLint border,
- GLsizei imageSize, const GLvoid * data,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- GLuint face = radeon_face_for_target(target);
-
- r300_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
- imageSize, 0, 0, data, 0, texObj, texImage, 1);
-}
-
-static void r300TexImage3D(GLcontext * ctx, GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint height, GLint depth,
- GLint border,
- GLenum format, GLenum type, const GLvoid * pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- r300_teximage(ctx, 3, 0, level, internalFormat, width, height, depth,
- 0, format, type, pixels, packing, texObj, texImage, 0);
-}
-
-/**
- * Update a subregion of the given texture image.
- */
-static void r300_texsubimage(GLcontext* ctx, int dims, int level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type,
- const GLvoid * pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage,
- int compressed)
-{
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
- radeon_texture_image* image = get_radeon_texture_image(texImage);
-
- R300_FIREVERTICES(rmesa);
-
- pixels = _mesa_validate_pbo_teximage(ctx, dims,
- width, height, depth, format, type, pixels, packing, "glTexSubImage1D");
-
- if (pixels) {
- GLint dstRowStride;
- radeon_teximage_map(image, GL_TRUE);
-
- if (image->mt) {
- radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
- dstRowStride = lvl->rowstride;
- } else {
- dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
- }
-
- if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
- texImage->TexFormat, texImage->Data,
- xoffset, yoffset, zoffset,
- dstRowStride,
- texImage->ImageOffsets,
- width, height, depth,
- format, type, pixels, packing))
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
-
- radeon_teximage_unmap(image);
- }
-
- _mesa_unmap_teximage_pbo(ctx, packing);
-
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- ctx->Driver.GenerateMipmap(ctx, texObj->Target, texObj);
- }
-}
-
-static void r300TexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
- GLint xoffset,
- GLsizei width,
- GLenum format, GLenum type,
- const GLvoid * pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- r300_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1,
- format, type, pixels, packing, texObj, texImage, 0);
-}
-
-static void r300TexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const GLvoid * pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- r300_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
- format, type, pixels, packing, texObj, texImage, 0);
-}
-
-static void r300CompressedTexSubImage2D(GLcontext * ctx, GLenum target,
- GLint level, GLint xoffset,
- GLint yoffset, GLsizei width,
- GLsizei height, GLenum format,
- GLsizei imageSize, const GLvoid * data,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- r300_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
- format, 0, data, 0, texObj, texImage, 1);
-}
-
-static void
-r300TexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type,
- const GLvoid * pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-{
- r300_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth,
- format, type, pixels, packing, texObj, texImage, 0);
-}
-
-
-
/**
* Changes variables and flags for a state update, which will happen at the
* next UpdateTextureState
}
_mesa_initialize_texture_object(&t->base, name, target);
- t->base.MaxAnisotropy = rmesa->initialMaxAnisotropy;
+ t->base.MaxAnisotropy = rmesa->radeon.initialMaxAnisotropy;
/* Initialize hardware state */
r300UpdateTexWrap(t);
functions->MapTexture = radeonMapTexture;
functions->UnmapTexture = radeonUnmapTexture;
- functions->ChooseTextureFormat = r300ChooseTextureFormat;
- functions->TexImage1D = r300TexImage1D;
- functions->TexImage2D = r300TexImage2D;
- functions->TexImage3D = r300TexImage3D;
- functions->TexSubImage1D = r300TexSubImage1D;
- functions->TexSubImage2D = r300TexSubImage2D;
- functions->TexSubImage3D = r300TexSubImage3D;
+ functions->ChooseTextureFormat = radeonChooseTextureFormat;
+ functions->TexImage1D = radeonTexImage1D;
+ functions->TexImage2D = radeonTexImage2D;
+ functions->TexImage3D = radeonTexImage3D;
+ functions->TexSubImage1D = radeonTexSubImage1D;
+ functions->TexSubImage2D = radeonTexSubImage2D;
+ functions->TexSubImage3D = radeonTexSubImage3D;
functions->NewTextureObject = r300NewTextureObject;
functions->DeleteTexture = r300DeleteTexture;
functions->IsTextureResident = driIsTextureResident;
functions->TexParameter = r300TexParameter;
- functions->CompressedTexImage2D = r300CompressedTexImage2D;
- functions->CompressedTexSubImage2D = r300CompressedTexSubImage2D;
+ functions->CompressedTexImage2D = radeonCompressedTexImage2D;
+ functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D;
functions->GenerateMipmap = radeon_generate_mipmap;
}
}
-
-static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
- GLuint numrows, GLuint rowsize)
-{
- assert(rowsize <= dststride);
- assert(rowsize <= srcstride);
-
- if (rowsize == srcstride && rowsize == dststride) {
- memcpy(dst, src, numrows*rowsize);
- } else {
- GLuint i;
- for(i = 0; i < numrows; ++i) {
- memcpy(dst, src, rowsize);
- dst += dststride;
- src += srcstride;
- }
- }
-}
-
-
-/**
- * Ensure that the given image is stored in the given miptree from now on.
- */
-static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, int face, int level)
-{
- radeon_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel];
- unsigned char *dest;
-
- assert(image->mt != mt);
- assert(dstlvl->width == image->base.Width);
- assert(dstlvl->height == image->base.Height);
- assert(dstlvl->depth == image->base.Depth);
-
- radeon_bo_map(mt->bo, GL_TRUE);
- dest = mt->bo->ptr + dstlvl->faces[face].offset;
-
- if (image->mt) {
- /* Format etc. should match, so we really just need a memcpy().
- * In fact, that memcpy() could be done by the hardware in many
- * cases, provided that we have a proper memory manager.
- */
- radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel];
-
- assert(srclvl->size == dstlvl->size);
- assert(srclvl->rowstride == dstlvl->rowstride);
-
- radeon_bo_map(image->mt->bo, GL_FALSE);
- memcpy(dest,
- image->mt->bo->ptr + srclvl->faces[face].offset,
- dstlvl->size);
- radeon_bo_unmap(image->mt->bo);
-
- radeon_miptree_unreference(image->mt);
- } else {
- uint srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
-
- if (mt->tilebits)
- WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
-
- copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride,
- image->base.Height * image->base.Depth, srcrowstride);
-
- _mesa_free_texmemory(image->base.Data);
- image->base.Data = 0;
- }
-
- radeon_bo_unmap(mt->bo);
-
- image->mt = mt;
- image->mtface = face;
- image->mtlevel = level;
- radeon_miptree_reference(image->mt);
-}
-
-
/**
* Ensure the given texture is ready for rendering.
*
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
radeonTexObj *t = radeon_tex_obj(texObj);
- radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[0][texObj->BaseLevel]);
- int face, level;
-
- if (t->validated || t->image_override)
- return GL_TRUE;
- if (RADEON_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj);
-
- if (baseimage->base.Border > 0)
+ if (!radeon_validate_texture_miptree(ctx, texObj))
return GL_FALSE;
- /* Ensure a matching miptree exists.
- *
- * Differing mipmap trees can result when the app uses TexImage to
- * change texture dimensions.
- *
- * Prefer to use base image's miptree if it
- * exists, since that most likely contains more valid data (remember
- * that the base level is usually significantly larger than the rest
- * of the miptree, so cubemaps are the only possible exception).
- */
- if (baseimage->mt &&
- baseimage->mt != t->mt &&
- radeon_miptree_matches_texture(baseimage->mt, &t->base)) {
- radeon_miptree_unreference(t->mt);
- t->mt = baseimage->mt;
- radeon_miptree_reference(t->mt);
- } else if (t->mt && !radeon_miptree_matches_texture(t->mt, &t->base)) {
- radeon_miptree_unreference(t->mt);
- t->mt = 0;
- }
-
- if (!t->mt) {
- if (RADEON_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, " Allocate new miptree\n");
- radeon_try_alloc_miptree(&rmesa->radeon, t, &baseimage->base, 0, texObj->BaseLevel);
- if (!t->mt) {
- _mesa_problem(ctx, "r300_validate_texture failed to alloc miptree");
- return GL_FALSE;
- }
- }
-
- /* Ensure all images are stored in the single main miptree */
- for(face = 0; face < t->mt->faces; ++face) {
- for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) {
- radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]);
- if (RADEON_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, " face %i, level %i... ", face, level);
- if (t->mt == image->mt) {
- if (RADEON_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "OK\n");
- continue;
- }
-
- if (RADEON_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "migrating\n");
- migrate_image_to_miptree(t->mt, image, face, level);
- }
- }
-
/* Configure the hardware registers (more precisely, the cached version
* of the hardware registers). */
setup_hardware_state(rmesa, t);
if (!offset)
return;
- t->bo = NULL;
+
+ t->bo = NULL;
t->override_offset = offset;
t->pp_txpitch &= (1 << 13) -1;
pitch_val = pitch;
{
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
+ struct gl_texture_image *texImage;
struct radeon_renderbuffer *rb;
radeon_texture_image *rImage;
radeonContextPtr radeon;
return;
}
- radeon_update_renderbuffers(pDRICtx, dPriv);
- /* back & depth buffer are useless free them right away */
- rb = (void*)fb->Attachment[BUFFER_DEPTH].Renderbuffer;
- if (rb && rb->bo) {
- radeon_bo_unref(rb->bo);
- rb->bo = NULL;
- }
- rb = (void*)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
- if (rb && rb->bo) {
- radeon_bo_unref(rb->bo);
+ radeon_update_renderbuffers(pDRICtx, dPriv);
+ /* back & depth buffer are useless free them right away */
+ rb = (void*)fb->Attachment[BUFFER_DEPTH].Renderbuffer;
+ if (rb && rb->bo) {
+ radeon_bo_unref(rb->bo);
rb->bo = NULL;
- }
- rb = (void*)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
- if (rb->bo == NULL) {
- /* Failed to BO for the buffer */
- return;
- }
-
- _mesa_lock_texture(radeon->glCtx, texObj);
- if (t->bo) {
- t->bo = NULL;
- }
- if (t->mt) {
- t->mt = NULL;
- }
- if (rImage->mt) {
- radeon_miptree_unreference(rImage->mt);
- rImage->mt = NULL;
- }
+ }
+ rb = (void*)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+ if (rb && rb->bo) {
+ radeon_bo_unref(rb->bo);
+ rb->bo = NULL;
+ }
+ rb = (void*)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+ if (rb->bo == NULL) {
+ /* Failed to BO for the buffer */
+ return;
+ }
+
+ _mesa_lock_texture(radeon->glCtx, texObj);
+ if (t->bo) {
+ t->bo = NULL;
+ }
+ if (t->mt) {
+ t->mt = NULL;
+ }
+ if (rImage->mt) {
+ radeon_miptree_unreference(rImage->mt);
+ rImage->mt = NULL;
+ }
fprintf(stderr,"settexbuf %dx%d@%d\n", rb->width, rb->height, rb->cpp);
- _mesa_init_teximage_fields(radeon->glCtx, target, texImage,
- rb->width, rb->height, 1, 0, rb->cpp);
+ _mesa_init_teximage_fields(radeon->glCtx, target, texImage,
+ rb->width, rb->height, 1, 0, rb->cpp);
texImage->TexFormat = &_mesa_texformat_rgba8888_rev;
- rImage->bo = rb->bo;
-
- t->bo = rb->bo;
- t->tile_bits = 0;
+ rImage->bo = rb->bo;
+
+ t->bo = rb->bo;
+ t->tile_bits = 0;
t->image_override = GL_TRUE;
t->override_offset = 0;
t->pp_txpitch &= (1 << 13) -1;
t->pp_txsize |= R300_TX_SIZE_TXPITCH_EN;
t->pp_txpitch |= pitch_val;
t->validated = GL_TRUE;
- _mesa_unlock_texture(radeon->glCtx, texObj);
- return;
+ _mesa_unlock_texture(radeon->glCtx, texObj);
+ return;
}
void (*update_draw_buffer)(GLcontext *ctx);
void (*emit_cs_header)(struct radeon_cs *cs, radeonContextPtr rmesa);
void (*emit_state)(radeonContextPtr rmesa);
+ void (*flush_vertices)(radeonContextPtr rmesa);
} vtbl;
};
#include <errno.h>
#include "main/glheader.h"
#include "main/imports.h"
+#include "main/context.h"
#include "main/api_arrayelt.h"
#include "main/enums.h"
#include "main/colormac.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
#include "swrast_setup/swrast_setup.h"
+#include "main/mipmap.h"
+#include "main/texformat.h"
+#include "main/texstore.h"
+#include "main/teximage.h"
+#include "main/texobj.h"
#include "drirenderbuffer.h"
#include "vblank.h"
_mesa_generate_mipmap(ctx, target, texObj);
radeon_teximage_unmap(baseimage);
}
+
+
+/* try to find a format which will only need a memcopy */
+static const struct gl_texture_format *radeonChoose8888TexFormat(GLenum srcFormat,
+ GLenum srcType)
+{
+ const GLuint ui = 1;
+ const GLubyte littleEndian = *((const GLubyte *)&ui);
+
+ if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
+ (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
+ (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
+ (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian)) {
+ return &_mesa_texformat_rgba8888;
+ } else if ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
+ (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
+ (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
+ (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian)) {
+ return &_mesa_texformat_rgba8888_rev;
+ } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
+ srcType == GL_UNSIGNED_INT_8_8_8_8)) {
+ return &_mesa_texformat_argb8888_rev;
+ } else if (srcFormat == GL_BGRA && ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
+ srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
+ return &_mesa_texformat_argb8888;
+ } else
+ return _dri_texformat_argb8888;
+}
+
+const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
+ GLint internalFormat,
+ GLenum format,
+ GLenum type)
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ const GLboolean do32bpt =
+ (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32);
+ const GLboolean force16bpt =
+ (rmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16);
+ (void)format;
+
+#if 0
+ fprintf(stderr, "InternalFormat=%s(%d) type=%s format=%s\n",
+ _mesa_lookup_enum_by_nr(internalFormat), internalFormat,
+ _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(format));
+ fprintf(stderr, "do32bpt=%d force16bpt=%d\n", do32bpt, force16bpt);
+#endif
+
+ switch (internalFormat) {
+ case 4:
+ case GL_RGBA:
+ case GL_COMPRESSED_RGBA:
+ switch (type) {
+ case GL_UNSIGNED_INT_10_10_10_2:
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ return do32bpt ? _dri_texformat_argb8888 :
+ _dri_texformat_argb1555;
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+ return _dri_texformat_argb4444;
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ return _dri_texformat_argb1555;
+ default:
+ return do32bpt ? radeonChoose8888TexFormat(format, type) :
+ _dri_texformat_argb4444;
+ }
+
+ case 3:
+ case GL_RGB:
+ case GL_COMPRESSED_RGB:
+ switch (type) {
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+ return _dri_texformat_argb4444;
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ return _dri_texformat_argb1555;
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ return _dri_texformat_rgb565;
+ default:
+ return do32bpt ? _dri_texformat_argb8888 :
+ _dri_texformat_rgb565;
+ }
+
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ return !force16bpt ?
+ radeonChoose8888TexFormat(format,
+ type) : _dri_texformat_argb4444;
+
+ case GL_RGBA4:
+ case GL_RGBA2:
+ return _dri_texformat_argb4444;
+
+ case GL_RGB5_A1:
+ return _dri_texformat_argb1555;
+
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ return !force16bpt ? _dri_texformat_argb8888 :
+ _dri_texformat_rgb565;
+
+ case GL_RGB5:
+ case GL_RGB4:
+ case GL_R3_G3_B2:
+ return _dri_texformat_rgb565;
+
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ case GL_COMPRESSED_ALPHA:
+ return _dri_texformat_a8;
+
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ case GL_COMPRESSED_LUMINANCE:
+ return _dri_texformat_l8;
+
+ case 2:
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE4_ALPHA4:
+ case GL_LUMINANCE6_ALPHA2:
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_LUMINANCE12_ALPHA4:
+ case GL_LUMINANCE12_ALPHA12:
+ case GL_LUMINANCE16_ALPHA16:
+ case GL_COMPRESSED_LUMINANCE_ALPHA:
+ return _dri_texformat_al88;
+
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ case GL_COMPRESSED_INTENSITY:
+ return _dri_texformat_i8;
+
+ case GL_YCBCR_MESA:
+ if (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
+ type == GL_UNSIGNED_BYTE)
+ return &_mesa_texformat_ycbcr;
+ else
+ return &_mesa_texformat_ycbcr_rev;
+
+ case GL_RGB_S3TC:
+ case GL_RGB4_S3TC:
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ return &_mesa_texformat_rgb_dxt1;
+
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ return &_mesa_texformat_rgba_dxt1;
+
+ case GL_RGBA_S3TC:
+ case GL_RGBA4_S3TC:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ return &_mesa_texformat_rgba_dxt3;
+
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ return &_mesa_texformat_rgba_dxt5;
+
+ case GL_ALPHA16F_ARB:
+ return &_mesa_texformat_alpha_float16;
+ case GL_ALPHA32F_ARB:
+ return &_mesa_texformat_alpha_float32;
+ case GL_LUMINANCE16F_ARB:
+ return &_mesa_texformat_luminance_float16;
+ case GL_LUMINANCE32F_ARB:
+ return &_mesa_texformat_luminance_float32;
+ case GL_LUMINANCE_ALPHA16F_ARB:
+ return &_mesa_texformat_luminance_alpha_float16;
+ case GL_LUMINANCE_ALPHA32F_ARB:
+ return &_mesa_texformat_luminance_alpha_float32;
+ case GL_INTENSITY16F_ARB:
+ return &_mesa_texformat_intensity_float16;
+ case GL_INTENSITY32F_ARB:
+ return &_mesa_texformat_intensity_float32;
+ case GL_RGB16F_ARB:
+ return &_mesa_texformat_rgba_float16;
+ case GL_RGB32F_ARB:
+ return &_mesa_texformat_rgba_float32;
+ case GL_RGBA16F_ARB:
+ return &_mesa_texformat_rgba_float16;
+ case GL_RGBA32F_ARB:
+ return &_mesa_texformat_rgba_float32;
+
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH_COMPONENT32:
+#if 0
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT:
+ return &_mesa_texformat_z16;
+ case GL_UNSIGNED_INT:
+ return &_mesa_texformat_z32;
+ case GL_UNSIGNED_INT_24_8_EXT:
+ default:
+ return &_mesa_texformat_z24_s8;
+ }
+#else
+ return &_mesa_texformat_z16;
+#endif
+
+ default:
+ _mesa_problem(ctx,
+ "unexpected internalFormat 0x%x in r300ChooseTextureFormat",
+ (int)internalFormat);
+ return NULL;
+ }
+
+ return NULL; /* never get here */
+}
+
+/**
+ * All glTexImage calls go through this function.
+ */
+static void radeon_teximage(
+ GLcontext *ctx, int dims,
+ GLint face, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint depth,
+ GLsizei imageSize,
+ GLenum format, GLenum type, const GLvoid * pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage,
+ int compressed)
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ radeonTexObj* t = radeon_tex_obj(texObj);
+ radeon_texture_image* image = get_radeon_texture_image(texImage);
+
+ rmesa->vtbl.flush_vertices(rmesa);
+
+ t->validated = GL_FALSE;
+
+ /* Choose and fill in the texture format for this image */
+ texImage->TexFormat = radeonChooseTextureFormat(ctx, internalFormat, format, type);
+ _mesa_set_fetch_functions(texImage, dims);
+
+ if (texImage->TexFormat->TexelBytes == 0) {
+ texImage->IsCompressed = GL_TRUE;
+ texImage->CompressedSize =
+ ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
+ texImage->Height, texImage->Depth,
+ texImage->TexFormat->MesaFormat);
+ } else {
+ texImage->IsCompressed = GL_FALSE;
+ texImage->CompressedSize = 0;
+ }
+
+ /* Allocate memory for image */
+ radeonFreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */
+
+ if (!t->mt)
+ radeon_try_alloc_miptree(rmesa, t, texImage, face, level);
+ if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) {
+ image->mt = t->mt;
+ image->mtlevel = level - t->mt->firstLevel;
+ image->mtface = face;
+ radeon_miptree_reference(t->mt);
+ } else {
+ int size;
+ if (texImage->IsCompressed) {
+ size = texImage->CompressedSize;
+ } else {
+ size = texImage->Width * texImage->Height * texImage->Depth * texImage->TexFormat->TexelBytes;
+ }
+ texImage->Data = _mesa_alloc_texmemory(size);
+ }
+
+ /* Upload texture image; note that the spec allows pixels to be NULL */
+ if (compressed) {
+ pixels = _mesa_validate_pbo_compressed_teximage(
+ ctx, imageSize, pixels, packing, "glCompressedTexImage");
+ } else {
+ pixels = _mesa_validate_pbo_teximage(
+ ctx, dims, width, height, depth,
+ format, type, pixels, packing, "glTexImage");
+ }
+
+ if (pixels) {
+ radeon_teximage_map(image, GL_TRUE);
+
+ if (compressed) {
+ memcpy(texImage->Data, pixels, imageSize);
+ } else {
+ GLuint dstRowStride;
+ if (image->mt) {
+ radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
+ dstRowStride = lvl->rowstride;
+ } else {
+ dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
+ }
+ if (!texImage->TexFormat->StoreImage(ctx, dims,
+ texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, height, depth,
+ format, type, pixels, packing))
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+ }
+
+ radeon_teximage_unmap(image);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+
+ /* SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ ctx->Driver.GenerateMipmap(ctx, texObj->Target, texObj);
+ }
+}
+
+void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint border,
+ GLenum format, GLenum type, const GLvoid * pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ radeon_teximage(ctx, 1, 0, level, internalFormat, width, 1, 1,
+ 0, format, type, pixels, packing, texObj, texImage, 0);
+}
+
+void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLenum format, GLenum type, const GLvoid * pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+
+{
+ GLuint face = radeon_face_for_target(target);
+
+ radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
+ 0, format, type, pixels, packing, texObj, texImage, 0);
+}
+
+void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target,
+ GLint level, GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLsizei imageSize, const GLvoid * data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ GLuint face = radeon_face_for_target(target);
+
+ radeon_teximage(ctx, 2, face, level, internalFormat, width, height, 1,
+ imageSize, 0, 0, data, 0, texObj, texImage, 1);
+}
+
+void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint depth,
+ GLint border,
+ GLenum format, GLenum type, const GLvoid * pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ radeon_teximage(ctx, 3, 0, level, internalFormat, width, height, depth,
+ 0, format, type, pixels, packing, texObj, texImage, 0);
+}
+
+/**
+ * Update a subregion of the given texture image.
+ */
+static void radeon_texsubimage(GLcontext* ctx, int dims, int level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type,
+ const GLvoid * pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage,
+ int compressed)
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ radeon_texture_image* image = get_radeon_texture_image(texImage);
+
+ rmesa->vtbl.flush_vertices(rmesa);
+
+ pixels = _mesa_validate_pbo_teximage(ctx, dims,
+ width, height, depth, format, type, pixels, packing, "glTexSubImage1D");
+
+ if (pixels) {
+ GLint dstRowStride;
+ radeon_teximage_map(image, GL_TRUE);
+
+ if (image->mt) {
+ radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel];
+ dstRowStride = lvl->rowstride;
+ } else {
+ dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes;
+ }
+
+ if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
+ texImage->TexFormat, texImage->Data,
+ xoffset, yoffset, zoffset,
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, height, depth,
+ format, type, pixels, packing))
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
+
+ radeon_teximage_unmap(image);
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ ctx->Driver.GenerateMipmap(ctx, texObj->Target, texObj);
+ }
+}
+
+void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format, GLenum type,
+ const GLvoid * pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ radeon_texsubimage(ctx, 1, level, xoffset, 0, 0, width, 1, 1,
+ format, type, pixels, packing, texObj, texImage, 0);
+}
+
+void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid * pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height,
+ 1, format, type, pixels, packing, texObj, texImage,
+ 0);
+}
+
+void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target,
+ GLint level, GLint xoffset,
+ GLint yoffset, GLsizei width,
+ GLsizei height, GLenum format,
+ GLsizei imageSize, const GLvoid * data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ radeon_texsubimage(ctx, 2, level, xoffset, yoffset, 0, width, height, 1,
+ format, 0, data, 0, texObj, texImage, 1);
+}
+
+
+void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type,
+ const GLvoid * pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ radeon_texsubimage(ctx, 3, level, xoffset, yoffset, zoffset, width, height, depth,
+ format, type, pixels, packing, texObj, texImage, 0);
+}
+
+static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride,
+ GLuint numrows, GLuint rowsize)
+{
+ assert(rowsize <= dststride);
+ assert(rowsize <= srcstride);
+
+ if (rowsize == srcstride && rowsize == dststride) {
+ memcpy(dst, src, numrows*rowsize);
+ } else {
+ GLuint i;
+ for(i = 0; i < numrows; ++i) {
+ memcpy(dst, src, rowsize);
+ dst += dststride;
+ src += srcstride;
+ }
+ }
+}
+
+
+/**
+ * Ensure that the given image is stored in the given miptree from now on.
+ */
+static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_image *image, int face, int level)
+{
+ radeon_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel];
+ unsigned char *dest;
+
+ assert(image->mt != mt);
+ assert(dstlvl->width == image->base.Width);
+ assert(dstlvl->height == image->base.Height);
+ assert(dstlvl->depth == image->base.Depth);
+
+ radeon_bo_map(mt->bo, GL_TRUE);
+ dest = mt->bo->ptr + dstlvl->faces[face].offset;
+
+ if (image->mt) {
+ /* Format etc. should match, so we really just need a memcpy().
+ * In fact, that memcpy() could be done by the hardware in many
+ * cases, provided that we have a proper memory manager.
+ */
+ radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel];
+
+ assert(srclvl->size == dstlvl->size);
+ assert(srclvl->rowstride == dstlvl->rowstride);
+
+ radeon_bo_map(image->mt->bo, GL_FALSE);
+ memcpy(dest,
+ image->mt->bo->ptr + srclvl->faces[face].offset,
+ dstlvl->size);
+ radeon_bo_unmap(image->mt->bo);
+
+ radeon_miptree_unreference(image->mt);
+ } else {
+ uint srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
+
+// if (mt->tilebits)
+// WARN_ONCE("%s: tiling not supported yet", __FUNCTION__);
+
+ copy_rows(dest, dstlvl->rowstride, image->base.Data, srcrowstride,
+ image->base.Height * image->base.Depth, srcrowstride);
+
+ _mesa_free_texmemory(image->base.Data);
+ image->base.Data = 0;
+ }
+
+ radeon_bo_unmap(mt->bo);
+
+ image->mt = mt;
+ image->mtface = face;
+ image->mtlevel = level;
+ radeon_miptree_reference(image->mt);
+}
+
+int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj)
+{
+ radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ radeonTexObj *t = radeon_tex_obj(texObj);
+ radeon_texture_image *baseimage = get_radeon_texture_image(texObj->Image[0][texObj->BaseLevel]);
+ int face, level;
+
+ if (t->validated || t->image_override)
+ return GL_TRUE;
+
+ if (RADEON_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj);
+
+ if (baseimage->base.Border > 0)
+ return GL_FALSE;
+
+ /* Ensure a matching miptree exists.
+ *
+ * Differing mipmap trees can result when the app uses TexImage to
+ * change texture dimensions.
+ *
+ * Prefer to use base image's miptree if it
+ * exists, since that most likely contains more valid data (remember
+ * that the base level is usually significantly larger than the rest
+ * of the miptree, so cubemaps are the only possible exception).
+ */
+ if (baseimage->mt &&
+ baseimage->mt != t->mt &&
+ radeon_miptree_matches_texture(baseimage->mt, &t->base)) {
+ radeon_miptree_unreference(t->mt);
+ t->mt = baseimage->mt;
+ radeon_miptree_reference(t->mt);
+ } else if (t->mt && !radeon_miptree_matches_texture(t->mt, &t->base)) {
+ radeon_miptree_unreference(t->mt);
+ t->mt = 0;
+ }
+
+ if (!t->mt) {
+ if (RADEON_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, " Allocate new miptree\n");
+ radeon_try_alloc_miptree(rmesa, t, &baseimage->base, 0, texObj->BaseLevel);
+ if (!t->mt) {
+ _mesa_problem(ctx, "r300_validate_texture failed to alloc miptree");
+ return GL_FALSE;
+ }
+ }
+
+ /* Ensure all images are stored in the single main miptree */
+ for(face = 0; face < t->mt->faces; ++face) {
+ for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) {
+ radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]);
+ if (RADEON_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, " face %i, level %i... ", face, level);
+ if (t->mt == image->mt) {
+ if (RADEON_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "OK\n");
+ continue;
+ }
+
+ if (RADEON_DEBUG & DEBUG_TEXTURE)
+ fprintf(stderr, "migrating\n");
+ migrate_image_to_miptree(t->mt, image, face, level);
+ }
+ }
+
+ return GL_TRUE;
+}
void radeonMapTexture(GLcontext *ctx, struct gl_texture_object *texObj);
void radeonUnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj);
void radeon_generate_mipmap(GLcontext* ctx, GLenum target, struct gl_texture_object *texObj);
+int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *texObj);
GLuint radeon_face_for_target(GLenum target);
+const struct gl_texture_format *radeonChooseTextureFormat(GLcontext * ctx,
+ GLint internalFormat,
+ GLenum format,
+ GLenum type);
+
+void radeonTexImage1D(GLcontext * ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint border,
+ GLenum format, GLenum type, const GLvoid * pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+void radeonTexImage2D(GLcontext * ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLenum format, GLenum type, const GLvoid * pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+void radeonCompressedTexImage2D(GLcontext * ctx, GLenum target,
+ GLint level, GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLsizei imageSize, const GLvoid * data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+void radeonTexImage3D(GLcontext * ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint depth,
+ GLint border,
+ GLenum format, GLenum type, const GLvoid * pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+void radeonTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format, GLenum type,
+ const GLvoid * pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+void radeonTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid * pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+void radeonCompressedTexSubImage2D(GLcontext * ctx, GLenum target,
+ GLint level, GLint xoffset,
+ GLint yoffset, GLsizei width,
+ GLsizei height, GLenum format,
+ GLsizei imageSize, const GLvoid * data,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type,
+ const GLvoid * pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+
#endif