From: Dave Airlie Date: Wed, 21 Jan 2009 15:05:43 +0000 (+1000) Subject: r200/r300: port r200 texture handling to common code X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=61bb82636f7b1681b5509e1a9038bbcc1feea35c;p=mesa.git r200/r300: port r200 texture handling to common code we now get texrect + trivial textures working --- diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c index 741d051818d..d8e28cd7531 100644 --- a/src/mesa/drivers/dri/r200/r200_context.c +++ b/src/mesa/drivers/dri/r200/r200_context.c @@ -266,6 +266,11 @@ static void r200_vtbl_flush(GLcontext *ctx) 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); @@ -281,11 +286,13 @@ static void r200_vtbl_emit_state(radeonContextPtr rmesa) 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; @@ -365,6 +372,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, 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], @@ -376,6 +384,7 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual, 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) diff --git a/src/mesa/drivers/dri/r200/r200_reg.h b/src/mesa/drivers/dri/r200/r200_reg.h index 5ce287f7a5f..a8b0ae7e29d 100644 --- a/src/mesa/drivers/dri/r200/r200_reg.h +++ b/src/mesa/drivers/dri/r200/r200_reg.h @@ -949,6 +949,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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 diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c index 3b56fec78ac..249f4eb4ce6 100644 --- a/src/mesa/drivers/dri/r200/r200_state_init.c +++ b/src/mesa/drivers/dri/r200/r200_state_init.c @@ -44,6 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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" @@ -353,9 +354,32 @@ static void ctx_emit(GLcontext *ctx, struct radeon_state_atom *atom) } -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(); } @@ -499,6 +523,9 @@ void r200InitState( r200ContextPtr rmesa ) 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 ); diff --git a/src/mesa/drivers/dri/r200/r200_tex.c b/src/mesa/drivers/dri/r200/r200_tex.c index 525a9de4a0f..7c433cc6b71 100644 --- a/src/mesa/drivers/dri/r200/r200_tex.c +++ b/src/mesa/drivers/dri/r200/r200_tex.c @@ -45,6 +45,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "texmem.h" +#include "radeon_mipmap_tree.h" #include "r200_context.h" #include "r200_state.h" #include "r200_ioctl.h" @@ -67,6 +68,7 @@ static void r200SetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap, GLenu { 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); @@ -103,7 +105,7 @@ static void r200SetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap, GLenu _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; @@ -273,687 +275,6 @@ static void r200SetTexBorderColor( radeonTexObjPtr t, GLubyte c[4] ) } -/** - * 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 @@ -1034,7 +355,7 @@ static void r200TexParameter( GLcontext *ctx, GLenum target, 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__, @@ -1081,46 +402,33 @@ static void r200TexParameter( GLcontext *ctx, GLenum target, } - -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); } @@ -1150,46 +458,57 @@ static void r200TexGen( GLcontext *ctx, * 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; @@ -1197,22 +516,16 @@ void r200InitTextureFuncs( struct dd_function_table *functions ) 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 } diff --git a/src/mesa/drivers/dri/r200/r200_texmem.c b/src/mesa/drivers/dri/r200/r200_texmem.c index 5a0922de215..a50786e2e78 100644 --- a/src/mesa/drivers/dri/r200/r200_texmem.c +++ b/src/mesa/drivers/dri/r200/r200_texmem.c @@ -49,7 +49,7 @@ SOFTWARE. #include /* 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. @@ -528,3 +528,4 @@ int r200UploadTexImages( r200ContextPtr rmesa, radeonTexObjPtr t, GLuint face ) return 0; } +#endif diff --git a/src/mesa/drivers/dri/r200/r200_texstate.c b/src/mesa/drivers/dri/r200/r200_texstate.c index 02f79bf3f80..2a402e99c6f 100644 --- a/src/mesa/drivers/dri/r200/r200_texstate.c +++ b/src/mesa/drivers/dri/r200/r200_texstate.c @@ -40,6 +40,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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" @@ -139,6 +141,8 @@ static const struct tx_table tx_table_le[] = #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). @@ -180,7 +184,7 @@ static void r200SetTexImages( r200ContextPtr rmesa, } } - texelBytes = baseImage->TexFormat->TexelBytes; + /* Compute which mipmap levels we really want to send to the hardware. */ @@ -217,7 +221,7 @@ static void r200SetTexImages( r200ContextPtr rmesa, } } 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; } } @@ -387,7 +391,7 @@ static void r200SetTexImages( r200ContextPtr rmesa, /* FYI: r200UploadTexImages( rmesa, t ) used to be called here */ } - +#endif /* ================================================================ @@ -1232,10 +1236,11 @@ static void import_tex_obj_state( r200ContextPtr rmesa, 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; @@ -1254,7 +1259,6 @@ static void import_tex_obj_state( r200ContextPtr rmesa, texobj->dirty_state &= ~(1<TexGenEnabled & R_BIT) { if (texUnit->GenModeR != mode) mixed_fallback = GL_TRUE; @@ -1513,52 +1516,6 @@ static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit ) 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<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<2 texunits. - */ - - { - GLuint tmp = rmesa->TexGenEnabled; - - rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<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); @@ -1575,237 +1532,164 @@ void set_re_cntl_d3d( GLcontext *ctx, int unit, GLboolean use_d3d ) } } -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<hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE<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<recheck_texgen[unit]) { - GLboolean fallback = !r200_validate_texgen( ctx, unit ); - TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<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; } @@ -1863,7 +1747,7 @@ void r200UpdateTextureState( GLcontext *ctx ) 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) { diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index e84d0acd6d8..eb8e481a18e 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -245,6 +245,11 @@ static void r300_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmes 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; @@ -289,7 +294,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, */ 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 @@ -309,10 +314,10 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, } /* 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 diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 54844370ea1..8f67460e420 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -717,11 +717,6 @@ struct r300_context { /* Vertex buffers */ - GLuint NewGLState; - - int texture_depth; - float initialMaxAnisotropy; - GLvector4f dummy_attrib[_TNL_ATTRIB_MAX]; GLvector4f *temp_attrib[_TNL_ATTRIB_MAX]; diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index ea5d65542b2..5fbd5b93ff8 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -2416,8 +2416,8 @@ void r300UpdateShaders(r300ContextPtr rmesa) 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] = @@ -2677,7 +2677,7 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state) r300UpdateStateParameters(ctx, new_state); - r300->NewGLState |= new_state; + r300->radeon.NewGLState |= new_state; } /** diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c index 7363c045716..11e89ffd0f0 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.c +++ b/src/mesa/drivers/dri/r300/r300_tex.c @@ -181,492 +181,6 @@ static void r300SetTexBorderColor(radeonTexObjPtr t, GLubyte c[4]) 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 @@ -784,7 +298,7 @@ static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx, } _mesa_initialize_texture_object(&t->base, name, target); - t->base.MaxAnisotropy = rmesa->initialMaxAnisotropy; + t->base.MaxAnisotropy = rmesa->radeon.initialMaxAnisotropy; /* Initialize hardware state */ r300UpdateTexWrap(t); @@ -804,21 +318,21 @@ void r300InitTextureFuncs(struct dd_function_table *functions) 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; diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index 77d9a9b3bfb..68c7ca3d29f 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -242,81 +242,6 @@ static void setup_hardware_state(r300ContextPtr rmesa, radeonTexObj *t) } } - -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. * @@ -326,67 +251,10 @@ static GLboolean r300_validate_texture(GLcontext * ctx, struct gl_texture_object { 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); @@ -431,7 +299,8 @@ void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname, if (!offset) return; - t->bo = NULL; + + t->bo = NULL; t->override_offset = offset; t->pp_txpitch &= (1 << 13) -1; pitch_val = pitch; @@ -463,7 +332,7 @@ void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) { 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; @@ -488,43 +357,43 @@ void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) 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; @@ -553,6 +422,6 @@ void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) 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; } diff --git a/src/mesa/drivers/dri/radeon/common_context.h b/src/mesa/drivers/dri/radeon/common_context.h index 6cbcffd2830..09a53b00eae 100644 --- a/src/mesa/drivers/dri/radeon/common_context.h +++ b/src/mesa/drivers/dri/radeon/common_context.h @@ -404,6 +404,7 @@ struct radeon_context { 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; }; diff --git a/src/mesa/drivers/dri/radeon/common_misc.c b/src/mesa/drivers/dri/radeon/common_misc.c index 2d0fc3a0dd3..94d2e6c8764 100644 --- a/src/mesa/drivers/dri/radeon/common_misc.c +++ b/src/mesa/drivers/dri/radeon/common_misc.c @@ -36,6 +36,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #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" @@ -47,6 +48,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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" @@ -1477,3 +1483,630 @@ void radeon_generate_mipmap(GLcontext* ctx, GLenum target, struct gl_texture_obj _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; +} diff --git a/src/mesa/drivers/dri/radeon/common_misc.h b/src/mesa/drivers/dri/radeon/common_misc.h index 828fb85b38b..470a3fd5a72 100644 --- a/src/mesa/drivers/dri/radeon/common_misc.h +++ b/src/mesa/drivers/dri/radeon/common_misc.h @@ -42,5 +42,73 @@ void radeon_teximage_unmap(radeon_texture_image *image); 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