From: Dave Airlie Date: Tue, 20 Jan 2009 16:10:32 +0000 (+1000) Subject: radeon/r200/r300: start to move to common miptree/texobj X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=33dc14c707734df37fb02b7bcc278ddeb94036f1;p=mesa.git radeon/r200/r300: start to move to common miptree/texobj --- diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile index 6b90018a288..5f1cfc889ee 100644 --- a/src/mesa/drivers/dri/r200/Makefile +++ b/src/mesa/drivers/dri/r200/Makefile @@ -32,6 +32,7 @@ DRIVER_SOURCES = r200_context.c \ common_misc.c \ radeon_bo_legacy.c \ radeon_cs_legacy.c \ + radeon_mipmap_tree.c \ $(EGL_SOURCES) C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) @@ -62,7 +63,9 @@ COMMON_SYMLINKS = \ common_lock.h \ common_misc.h \ common_misc.c \ - common_cmdbuf.h + common_cmdbuf.h \ + radeon_mipmap_tree.c \ + radeon_mipmap_tree.h DRI_LIB_DEPS += -ldrm_radeon diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index 942d76fcc88..ce425e1d61a 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -35,10 +35,8 @@ DRIVER_SOURCES = \ r300_cmdbuf.c \ r300_state.c \ r300_render.c \ - r300_texmem.c \ r300_tex.c \ r300_texstate.c \ - r300_mipmap_tree.c \ radeon_program.c \ radeon_program_alu.c \ radeon_program_pair.c \ @@ -52,6 +50,7 @@ DRIVER_SOURCES = \ r300_shader.c \ r300_emit.c \ r300_swtcl.c \ + radeon_mipmap_tree.c \ $(EGL_SOURCES) C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES) @@ -84,7 +83,9 @@ COMMON_SYMLINKS = \ common_lock.h \ common_misc.c \ common_misc.h \ - common_cmdbuf.h + common_cmdbuf.h \ + radeon_mipmap_tree.c \ + radeon_mipmap_tree.h DRI_LIB_DEPS += -ldrm_radeon diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 30314d454ff..04bb76bb301 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -52,7 +52,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_reg.h" #include "r300_cmdbuf.h" #include "r300_emit.h" -#include "r300_mipmap_tree.h" +#include "radeon_mipmap_tree.h" #include "r300_state.h" #include "radeon_cs_legacy.h" #include "radeon_cs_gem.h" @@ -271,7 +271,7 @@ static void emit_tex_offsets(GLcontext *ctx, struct radeon_state_atom * atom) for(i = 0; i < numtmus; ++i) { BEGIN_BATCH(2); OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1); - r300TexObj *t = r300->hw.textures[i]; + radeonTexObj *t = r300->hw.textures[i]; if (t && !t->image_override) { OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0, RADEON_GEM_DOMAIN_VRAM, 0, 0); diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 798f1f58c9e..e84d0acd6d8 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -59,7 +59,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_span.h" #include "r300_context.h" #include "r300_cmdbuf.h" -#include "r300_mipmap_tree.h" #include "r300_state.h" #include "r300_ioctl.h" #include "r300_tex.h" diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 477756774d6..1c228b42efb 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -81,7 +81,6 @@ typedef struct r300_context *r300ContextPtr; /* Texture related */ -typedef struct r300_tex_obj r300TexObj, *r300TexObjPtr; typedef struct _r300_texture_image r300_texture_image; @@ -96,8 +95,8 @@ struct _r300_texture_image { * If mt == 0, the image is stored in normal memory pointed to * by base.Data. */ - struct _r300_mipmap_tree *mt; - struct radeon_bo *bo; + struct _radeon_mipmap_tree *mt; + struct radeon_bo *bo; int mtlevel; /** if mt != 0, this is the image's level in the mipmap tree */ int mtface; /** if mt != 0, this is the image's face in the mipmap tree */ @@ -108,41 +107,6 @@ static INLINE r300_texture_image *get_r300_texture_image(struct gl_texture_image return (r300_texture_image*)image; } - -/* Texture object in locally shared texture space. - */ -struct r300_tex_obj { - struct gl_texture_object base; - struct _r300_mipmap_tree *mt; - - /** - * This is true if we've verified that the mipmap tree above is complete - * and so on. - */ - GLboolean validated; - - GLboolean image_override; /* Image overridden by GLX_EXT_tfp */ - GLuint override_offset; - - /* hardware register values */ - /* Note that R200 has 8 registers per texture and R300 only 7 */ - GLuint filter; - GLuint filter_1; - GLuint pitch_reg; - GLuint size; /* npot only */ - GLuint format; - GLuint pp_border_color; - /* end hardware registers */ - - GLuint tile_bits; /* hw texture tile bits used on this texture */ - struct radeon_bo *bo; -}; - -static INLINE r300TexObj* r300_tex_obj(struct gl_texture_object *texObj) -{ - return (r300TexObj*)texObj; -} - /* The blit width for texture uploads */ #define R300_BLIT_WIDTH_BYTES 1024 @@ -459,7 +423,7 @@ struct r300_hw_state { } tex; struct radeon_state_atom txe; /* tex enable (4104) */ - r300TexObj *textures[R300_MAX_TEXTURE_UNITS]; + radeonTexObj *textures[R300_MAX_TEXTURE_UNITS]; }; /** diff --git a/src/mesa/drivers/dri/r300/r300_mipmap_tree.c b/src/mesa/drivers/dri/r300/r300_mipmap_tree.c deleted file mode 100644 index 097f9cdfece..00000000000 --- a/src/mesa/drivers/dri/r300/r300_mipmap_tree.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright (C) 2008 Nicolai Haehnle. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "r300_mipmap_tree.h" - -#include -#include - -#include "main/simple_list.h" -#include "main/texcompress.h" -#include "main/texformat.h" - -#include "radeon_buffer.h" - -static GLuint r300_compressed_texture_size(GLcontext *ctx, - GLsizei width, GLsizei height, GLsizei depth, - GLuint mesaFormat) -{ - GLuint size = _mesa_compressed_texture_size(ctx, width, height, depth, mesaFormat); - - if (mesaFormat == MESA_FORMAT_RGB_DXT1 || - mesaFormat == MESA_FORMAT_RGBA_DXT1) { - if (width + 3 < 8) /* width one block */ - size = size * 4; - else if (width + 3 < 16) - size = size * 2; - } else { - /* DXT3/5, 16 bytes per block */ - WARN_ONCE("DXT 3/5 suffers from multitexturing problems!\n"); - if (width + 3 < 8) - size = size * 2; - } - - return size; -} - -/** - * Compute sizes and fill in offset and blit information for the given - * image (determined by \p face and \p level). - * - * \param curOffset points to the offset at which the image is to be stored - * and is updated by this function according to the size of the image. - */ -static void compute_tex_image_offset(r300_mipmap_tree *mt, - GLuint face, GLuint level, GLuint* curOffset) -{ - r300_mipmap_level *lvl = &mt->levels[level]; - - /* Find image size in bytes */ - if (mt->compressed) { - /* TODO: Is this correct? Need test cases for compressed textures! */ - GLuint align; - - if (mt->target == GL_TEXTURE_RECTANGLE_NV) - align = 64 / mt->bpp; - else - align = 32 / mt->bpp; - lvl->rowstride = (lvl->width + align - 1) & ~(align - 1); - lvl->size = r300_compressed_texture_size(mt->r300->radeon.glCtx, - lvl->width, lvl->height, lvl->depth, mt->compressed); - } else if (mt->target == GL_TEXTURE_RECTANGLE_NV) { - lvl->rowstride = (lvl->width * mt->bpp + 63) & ~63; - lvl->size = lvl->rowstride * lvl->height; - } else if (mt->tilebits & R300_TXO_MICRO_TILE) { - /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned, - * though the actual offset may be different (if texture is less than - * 32 bytes width) to the untiled case */ - lvl->rowstride = (lvl->width * mt->bpp * 2 + 31) & ~31; - lvl->size = lvl->rowstride * ((lvl->height + 1) / 2) * lvl->depth; - } else { - lvl->rowstride = (lvl->width * mt->bpp + 31) & ~31; - lvl->size = lvl->rowstride * lvl->height * lvl->depth; - } - assert(lvl->size > 0); - - /* All images are aligned to a 32-byte offset */ - *curOffset = (*curOffset + 0x1f) & ~0x1f; - lvl->faces[face].offset = *curOffset; - *curOffset += lvl->size; -} - -static GLuint minify(GLuint size, GLuint levels) -{ - size = size >> levels; - if (size < 1) - size = 1; - return size; -} - -static void calculate_miptree_layout(r300_mipmap_tree *mt) -{ - GLuint curOffset; - GLuint numLevels; - GLuint i; - - numLevels = mt->lastLevel - mt->firstLevel + 1; - assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS); - - curOffset = 0; - for(i = 0; i < numLevels; i++) { - GLuint face; - - mt->levels[i].width = minify(mt->width0, i); - mt->levels[i].height = minify(mt->height0, i); - mt->levels[i].depth = minify(mt->depth0, i); - - for(face = 0; face < mt->faces; face++) - compute_tex_image_offset(mt, face, i, &curOffset); - } - - /* Note the required size in memory */ - mt->totalsize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; -} - - -/** - * Create a new mipmap tree, calculate its layout and allocate memory. - */ -r300_mipmap_tree* r300_miptree_create(r300ContextPtr rmesa, r300TexObj *t, - GLenum target, GLuint firstLevel, GLuint lastLevel, - GLuint width0, GLuint height0, GLuint depth0, - GLuint bpp, GLuint tilebits, GLuint compressed) -{ - r300_mipmap_tree *mt = CALLOC_STRUCT(_r300_mipmap_tree); - - mt->r300 = rmesa; - mt->refcount = 1; - mt->t = t; - mt->target = target; - mt->faces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; - mt->firstLevel = firstLevel; - mt->lastLevel = lastLevel; - mt->width0 = width0; - mt->height0 = height0; - mt->depth0 = depth0; - mt->bpp = bpp; - mt->tilebits = tilebits; - mt->compressed = compressed; - - calculate_miptree_layout(mt); - - mt->bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom, - 0, mt->totalsize, 1024, - RADEON_GEM_DOMAIN_VRAM, - 0); - - return mt; -} - -void r300_miptree_reference(r300_mipmap_tree *mt) -{ - mt->refcount++; - assert(mt->refcount > 0); -} - -void r300_miptree_unreference(r300_mipmap_tree *mt) -{ - if (!mt) - return; - - assert(mt->refcount > 0); - mt->refcount--; - if (!mt->refcount) { - radeon_bo_unref(mt->bo); - free(mt); - } -} - - -static void calculate_first_last_level(struct gl_texture_object *tObj, - GLuint *pfirstLevel, GLuint *plastLevel) -{ - const struct gl_texture_image * const baseImage = - tObj->Image[0][tObj->BaseLevel]; - - /* These must be signed values. MinLod and MaxLod can be negative numbers, - * and having firstLevel and lastLevel as signed prevents the need for - * extra sign checks. - */ - int firstLevel; - int lastLevel; - - /* Yes, this looks overly complicated, but it's all needed. - */ - switch (tObj->Target) { - case GL_TEXTURE_1D: - case GL_TEXTURE_2D: - case GL_TEXTURE_3D: - case GL_TEXTURE_CUBE_MAP: - if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) { - /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL. - */ - firstLevel = lastLevel = tObj->BaseLevel; - } else { - firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5); - firstLevel = MAX2(firstLevel, tObj->BaseLevel); - firstLevel = MIN2(firstLevel, tObj->BaseLevel + baseImage->MaxLog2); - lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5); - lastLevel = MAX2(lastLevel, tObj->BaseLevel); - lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); - lastLevel = MIN2(lastLevel, tObj->MaxLevel); - lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ - } - break; - case GL_TEXTURE_RECTANGLE_NV: - case GL_TEXTURE_4D_SGIS: - firstLevel = lastLevel = 0; - break; - default: - return; - } - - /* save these values */ - *pfirstLevel = firstLevel; - *plastLevel = lastLevel; -} - - -/** - * Checks whether the given miptree can hold the given texture image at the - * given face and level. - */ -GLboolean r300_miptree_matches_image(r300_mipmap_tree *mt, - struct gl_texture_image *texImage, GLuint face, GLuint level) -{ - r300_mipmap_level *lvl; - - if (face >= mt->faces || level < mt->firstLevel || level > mt->lastLevel) - return GL_FALSE; - - if (texImage->TexFormat->TexelBytes != mt->bpp) - return GL_FALSE; - - lvl = &mt->levels[level - mt->firstLevel]; - if (lvl->width != texImage->Width || - lvl->height != texImage->Height || - lvl->depth != texImage->Depth) - return GL_FALSE; - - return GL_TRUE; -} - - -/** - * Checks whether the given miptree has the right format to store the given texture object. - */ -GLboolean r300_miptree_matches_texture(r300_mipmap_tree *mt, struct gl_texture_object *texObj) -{ - struct gl_texture_image *firstImage; - GLuint compressed; - GLuint numfaces = 1; - GLuint firstLevel, lastLevel; - - calculate_first_last_level(texObj, &firstLevel, &lastLevel); - if (texObj->Target == GL_TEXTURE_CUBE_MAP) - numfaces = 6; - - firstImage = texObj->Image[0][firstLevel]; - compressed = firstImage->IsCompressed ? firstImage->TexFormat->MesaFormat : 0; - - return (mt->firstLevel == firstLevel && - mt->lastLevel == lastLevel && - mt->width0 == firstImage->Width && - mt->height0 == firstImage->Height && - mt->depth0 == firstImage->Depth && - mt->bpp == firstImage->TexFormat->TexelBytes && - mt->compressed == compressed); -} - - -/** - * Try to allocate a mipmap tree for the given texture that will fit the - * given image in the given position. - */ -void r300_try_alloc_miptree(r300ContextPtr rmesa, r300TexObj *t, - struct gl_texture_image *texImage, GLuint face, GLuint level) -{ - GLuint compressed = texImage->IsCompressed ? texImage->TexFormat->MesaFormat : 0; - GLuint numfaces = 1; - GLuint firstLevel, lastLevel; - - assert(!t->mt); - - calculate_first_last_level(&t->base, &firstLevel, &lastLevel); - if (t->base.Target == GL_TEXTURE_CUBE_MAP) - numfaces = 6; - - if (level != firstLevel || face >= numfaces) - return; - - t->mt = r300_miptree_create(rmesa, t, t->base.Target, - firstLevel, lastLevel, - texImage->Width, texImage->Height, texImage->Depth, - texImage->TexFormat->TexelBytes, t->tile_bits, compressed); -} diff --git a/src/mesa/drivers/dri/r300/r300_mipmap_tree.h b/src/mesa/drivers/dri/r300/r300_mipmap_tree.h deleted file mode 100644 index aeb52dc1353..00000000000 --- a/src/mesa/drivers/dri/r300/r300_mipmap_tree.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2008 Nicolai Haehnle. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef __R300_MIPMAP_TREE_H_ -#define __R300_MIPMAP_TREE_H_ - -#include "r300_context.h" - -typedef struct _r300_mipmap_tree r300_mipmap_tree; -typedef struct _r300_mipmap_level r300_mipmap_level; -typedef struct _r300_mipmap_image r300_mipmap_image; - -struct _r300_mipmap_image { - GLuint offset; /** Offset of this image from the start of mipmap tree buffer, in bytes */ -}; - -struct _r300_mipmap_level { - GLuint width; - GLuint height; - GLuint depth; - GLuint size; /** Size of each image, in bytes */ - GLuint rowstride; /** in bytes */ - r300_mipmap_image faces[6]; -}; - - -/** - * A mipmap tree contains texture images in the layout that the hardware - * expects. - * - * The meta-data of mipmap trees is immutable, i.e. you cannot change the - * layout on-the-fly; however, the texture contents (i.e. texels) can be - * changed. - */ -struct _r300_mipmap_tree { - r300ContextPtr r300; - r300TexObj *t; - struct radeon_bo *bo; - GLuint refcount; - - GLuint totalsize; /** total size of the miptree, in bytes */ - - GLenum target; /** GL_TEXTURE_xxx */ - GLuint faces; /** # of faces: 6 for cubemaps, 1 otherwise */ - GLuint firstLevel; /** First mip level stored in this mipmap tree */ - GLuint lastLevel; /** Last mip level stored in this mipmap tree */ - - GLuint width0; /** Width of firstLevel image */ - GLuint height0; /** Height of firstLevel image */ - GLuint depth0; /** Depth of firstLevel image */ - - GLuint bpp; /** Bytes per texel */ - GLuint tilebits; /** R300_TXO_xxx_TILE */ - GLuint compressed; /** MESA_FORMAT_xxx indicating a compressed format, or 0 if uncompressed */ - - r300_mipmap_level levels[RADEON_MAX_TEXTURE_LEVELS]; -}; - -r300_mipmap_tree* r300_miptree_create(r300ContextPtr rmesa, r300TexObj *t, - GLenum target, GLuint firstLevel, GLuint lastLevel, - GLuint width0, GLuint height0, GLuint depth0, - GLuint bpp, GLuint tilebits, GLuint compressed); -void r300_miptree_reference(r300_mipmap_tree *mt); -void r300_miptree_unreference(r300_mipmap_tree *mt); - -GLboolean r300_miptree_matches_image(r300_mipmap_tree *mt, - struct gl_texture_image *texImage, GLuint face, GLuint level); -GLboolean r300_miptree_matches_texture(r300_mipmap_tree *mt, struct gl_texture_object *texObj); -void r300_try_alloc_miptree(r300ContextPtr rmesa, r300TexObj *t, - struct gl_texture_image *texImage, GLuint face, GLuint level); - - -#endif /* __R300_MIPMAP_TREE_H_ */ diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index b1048f3b0c2..ea5d65542b2 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1444,7 +1444,7 @@ static GLuint translate_lod_bias(GLfloat bias) static void r300SetupTextures(GLcontext * ctx) { int i, mtu; - struct r300_tex_obj *t; + struct radeon_tex_obj *t; r300ContextPtr r300 = R300_CONTEXT(ctx); int hw_tmu = 0; int last_hw_tmu = -1; /* -1 translates into no setup costs for fields */ @@ -1480,14 +1480,14 @@ static void r300SetupTextures(GLcontext * ctx) if (ctx->Texture.Unit[i]._ReallyEnabled) { tmu_mappings[i] = hw_tmu; - t = r300_tex_obj(ctx->Texture.Unit[i]._Current); + t = radeon_tex_obj(ctx->Texture.Unit[i]._Current); if (!t) continue; - if ((t->format & 0xffffff00) == 0xffffff00) { + if ((t->pp_txformat & 0xffffff00) == 0xffffff00) { WARN_ONCE ("unknown texture format (entry %x) encountered. Help me !\n", - t->format & 0xff); + t->pp_txformat & 0xff); } if (RADEON_DEBUG & DEBUG_STATE) @@ -1498,21 +1498,21 @@ static void r300SetupTextures(GLcontext * ctx) r300->hw.tex.filter.cmd[R300_TEX_VALUE_0 + hw_tmu] = - gen_fixed_filter(t->filter) | (hw_tmu << 28); + gen_fixed_filter(t->pp_txfilter) | (hw_tmu << 28); /* Note: There is a LOD bias per texture unit and a LOD bias * per texture object. We add them here to get the correct behaviour. * (The per-texture object LOD bias was introduced in OpenGL 1.4 * and is not present in the EXT_texture_object extension). */ r300->hw.tex.filter_1.cmd[R300_TEX_VALUE_0 + hw_tmu] = - t->filter_1 | + t->pp_txfilter_1 | translate_lod_bias(ctx->Texture.Unit[i].LodBias + t->base.LodBias); r300->hw.tex.size.cmd[R300_TEX_VALUE_0 + hw_tmu] = - t->size; + t->pp_txsize; r300->hw.tex.format.cmd[R300_TEX_VALUE_0 + - hw_tmu] = t->format; + hw_tmu] = t->pp_txformat; r300->hw.tex.pitch.cmd[R300_TEX_VALUE_0 + hw_tmu] = - t->pitch_reg; + t->pp_txpitch; r300->hw.textures[hw_tmu] = t; if (t->tile_bits & R300_TXO_MACRO_TILE) { diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c index 9ceac70f5e3..e3b871c991d 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.c +++ b/src/mesa/drivers/dri/r300/r300_tex.c @@ -50,7 +50,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_context.h" #include "r300_state.h" #include "r300_ioctl.h" -#include "r300_mipmap_tree.h" +#include "radeon_mipmap_tree.h" #include "r300_tex.h" #include "xmlpool.h" @@ -79,20 +79,20 @@ static unsigned int translate_wrap_mode(GLenum wrapmode) * * \param t Texture object whose wrap modes are to be set */ -static void r300UpdateTexWrap(r300TexObjPtr t) +static void r300UpdateTexWrap(radeonTexObjPtr t) { struct gl_texture_object *tObj = &t->base; - t->filter &= + t->pp_txfilter &= ~(R300_TX_WRAP_S_MASK | R300_TX_WRAP_T_MASK | R300_TX_WRAP_R_MASK); - t->filter |= translate_wrap_mode(tObj->WrapS) << R300_TX_WRAP_S_SHIFT; + t->pp_txfilter |= translate_wrap_mode(tObj->WrapS) << R300_TX_WRAP_S_SHIFT; if (tObj->Target != GL_TEXTURE_1D) { - t->filter |= translate_wrap_mode(tObj->WrapT) << R300_TX_WRAP_T_SHIFT; + t->pp_txfilter |= translate_wrap_mode(tObj->WrapT) << R300_TX_WRAP_T_SHIFT; if (tObj->Target == GL_TEXTURE_3D) - t->filter |= translate_wrap_mode(tObj->WrapR) << R300_TX_WRAP_R_SHIFT; + t->pp_txfilter |= translate_wrap_mode(tObj->WrapR) << R300_TX_WRAP_R_SHIFT; } } @@ -119,13 +119,13 @@ static GLuint aniso_filter(GLfloat anisotropy) * \param magf Texture magnification mode * \param anisotropy Maximum anisotropy level */ -static void r300SetTexFilter(r300TexObjPtr t, GLenum minf, GLenum magf, GLfloat anisotropy) +static void r300SetTexFilter(radeonTexObjPtr t, GLenum minf, GLenum magf, GLfloat anisotropy) { /* Force revalidation to account for switches from/to mipmapping. */ t->validated = GL_FALSE; - t->filter &= ~(R300_TX_MIN_FILTER_MASK | R300_TX_MIN_FILTER_MIP_MASK | R300_TX_MAG_FILTER_MASK | R300_TX_MAX_ANISO_MASK); - t->filter_1 &= ~R300_EDGE_ANISO_EDGE_ONLY; + t->pp_txfilter &= ~(R300_TX_MIN_FILTER_MASK | R300_TX_MIN_FILTER_MIP_MASK | R300_TX_MAG_FILTER_MASK | R300_TX_MAX_ANISO_MASK); + t->pp_txfilter_1 &= ~R300_EDGE_ANISO_EDGE_ONLY; /* Note that EXT_texture_filter_anisotropic is extremely vague about * how anisotropic filtering interacts with the "normal" filter modes. @@ -133,7 +133,7 @@ static void r300SetTexFilter(r300TexObjPtr t, GLenum minf, GLenum magf, GLfloat * filter settings completely. This includes driconf's settings. */ if (anisotropy >= 2.0 && (minf != GL_NEAREST) && (magf != GL_NEAREST)) { - t->filter |= R300_TX_MAG_FILTER_ANISO + t->pp_txfilter |= R300_TX_MAG_FILTER_ANISO | R300_TX_MIN_FILTER_ANISO | R300_TX_MIN_FILTER_MIP_LINEAR | aniso_filter(anisotropy); @@ -144,22 +144,22 @@ static void r300SetTexFilter(r300TexObjPtr t, GLenum minf, GLenum magf, GLfloat switch (minf) { case GL_NEAREST: - t->filter |= R300_TX_MIN_FILTER_NEAREST; + t->pp_txfilter |= R300_TX_MIN_FILTER_NEAREST; break; case GL_LINEAR: - t->filter |= R300_TX_MIN_FILTER_LINEAR; + t->pp_txfilter |= R300_TX_MIN_FILTER_LINEAR; break; case GL_NEAREST_MIPMAP_NEAREST: - t->filter |= R300_TX_MIN_FILTER_NEAREST|R300_TX_MIN_FILTER_MIP_NEAREST; + t->pp_txfilter |= R300_TX_MIN_FILTER_NEAREST|R300_TX_MIN_FILTER_MIP_NEAREST; break; case GL_NEAREST_MIPMAP_LINEAR: - t->filter |= R300_TX_MIN_FILTER_NEAREST|R300_TX_MIN_FILTER_MIP_LINEAR; + t->pp_txfilter |= R300_TX_MIN_FILTER_NEAREST|R300_TX_MIN_FILTER_MIP_LINEAR; break; case GL_LINEAR_MIPMAP_NEAREST: - t->filter |= R300_TX_MIN_FILTER_LINEAR|R300_TX_MIN_FILTER_MIP_NEAREST; + t->pp_txfilter |= R300_TX_MIN_FILTER_LINEAR|R300_TX_MIN_FILTER_MIP_NEAREST; break; case GL_LINEAR_MIPMAP_LINEAR: - t->filter |= R300_TX_MIN_FILTER_LINEAR|R300_TX_MIN_FILTER_MIP_LINEAR; + t->pp_txfilter |= R300_TX_MIN_FILTER_LINEAR|R300_TX_MIN_FILTER_MIP_LINEAR; break; } @@ -168,15 +168,15 @@ static void r300SetTexFilter(r300TexObjPtr t, GLenum minf, GLenum magf, GLfloat */ switch (magf) { case GL_NEAREST: - t->filter |= R300_TX_MAG_FILTER_NEAREST; + t->pp_txfilter |= R300_TX_MAG_FILTER_NEAREST; break; case GL_LINEAR: - t->filter |= R300_TX_MAG_FILTER_LINEAR; + t->pp_txfilter |= R300_TX_MAG_FILTER_LINEAR; break; } } -static void r300SetTexBorderColor(r300TexObjPtr t, GLubyte c[4]) +static void r300SetTexBorderColor(radeonTexObjPtr t, GLubyte c[4]) { t->pp_border_color = PACK_COLOR_8888(c[3], c[0], c[1], c[2]); } @@ -423,7 +423,7 @@ static void r300FreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage r300_texture_image* image = get_r300_texture_image(timage); if (image->mt) { - r300_miptree_unreference(image->mt); + radeon_miptree_unreference(image->mt); image->mt = 0; assert(!image->base.Data); } else { @@ -439,7 +439,7 @@ static void r300FreeTexImageData(GLcontext *ctx, struct gl_texture_image *timage /* Set Data pointer and additional data for mapped texture image */ static void teximage_set_map_data(r300_texture_image *image) { - r300_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; + radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; image->base.Data = image->mt->bo->ptr + lvl->faces[image->mtface].offset; image->base.RowStride = lvl->rowstride / image->mt->bpp; } @@ -474,7 +474,7 @@ static void r300_teximage_unmap(r300_texture_image *image) */ static void r300MapTexture(GLcontext *ctx, struct gl_texture_object *texObj) { - r300TexObj* t = r300_tex_obj(texObj); + radeonTexObj* t = radeon_tex_obj(texObj); int face, level; assert(texObj->_Complete); @@ -489,7 +489,7 @@ static void r300MapTexture(GLcontext *ctx, struct gl_texture_object *texObj) static void r300UnmapTexture(GLcontext *ctx, struct gl_texture_object *texObj) { - r300TexObj* t = r300_tex_obj(texObj); + radeonTexObj* t = radeon_tex_obj(texObj); int face, level; assert(texObj->_Complete); @@ -518,7 +518,7 @@ static void r300_teximage( int compressed) { r300ContextPtr rmesa = R300_CONTEXT(ctx); - r300TexObj* t = r300_tex_obj(texObj); + radeonTexObj* t = radeon_tex_obj(texObj); r300_texture_image* image = get_r300_texture_image(texImage); R300_FIREVERTICES(rmesa); @@ -544,12 +544,12 @@ static void r300_teximage( r300FreeTexImageData(ctx, texImage); /* Mesa core only clears texImage->Data but not image->mt */ if (!t->mt) - r300_try_alloc_miptree(rmesa, t, texImage, face, level); - if (t->mt && r300_miptree_matches_image(t->mt, texImage, face, level)) { + 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; - r300_miptree_reference(t->mt); + radeon_miptree_reference(t->mt); } else { int size; if (texImage->IsCompressed) { @@ -578,7 +578,7 @@ static void r300_teximage( } else { GLuint dstRowStride; if (image->mt) { - r300_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; + radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; dstRowStride = lvl->rowstride; } else { dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes; @@ -700,7 +700,7 @@ static void r300_texsubimage(GLcontext* ctx, int dims, int level, r300_teximage_map(image, GL_TRUE); if (image->mt) { - r300_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; + radeon_mipmap_level *lvl = &image->mt->levels[image->mtlevel]; dstRowStride = lvl->rowstride; } else { dstRowStride = texImage->Width * texImage->TexFormat->TexelBytes; @@ -806,7 +806,7 @@ static void r300TexParameter(GLcontext * ctx, GLenum target, struct gl_texture_object *texObj, GLenum pname, const GLfloat * params) { - r300TexObj* t = r300_tex_obj(texObj); + radeonTexObj* t = radeon_tex_obj(texObj); if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) { fprintf(stderr, "%s( %s )\n", __FUNCTION__, @@ -840,7 +840,7 @@ static void r300TexParameter(GLcontext * ctx, GLenum target, * to simulate a clamped LOD. */ if (t->mt) { - r300_miptree_unreference(t->mt); + radeon_miptree_unreference(t->mt); t->mt = 0; t->validated = GL_FALSE; } @@ -869,7 +869,7 @@ static void r300TexParameter(GLcontext * ctx, GLenum target, static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj) { r300ContextPtr rmesa = R300_CONTEXT(ctx); - r300TexObj* t = r300_tex_obj(texObj); + radeonTexObj* t = radeon_tex_obj(texObj); if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) { fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__, @@ -887,7 +887,7 @@ static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj) } if (t->mt) { - r300_miptree_unreference(t->mt); + radeon_miptree_unreference(t->mt); t->mt = 0; } _mesa_delete_texture_object(ctx, texObj); @@ -905,7 +905,7 @@ static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx, GLenum target) { r300ContextPtr rmesa = R300_CONTEXT(ctx); - r300TexObj* t = CALLOC_STRUCT(r300_tex_obj); + radeonTexObj* t = CALLOC_STRUCT(radeon_tex_obj); if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) { diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index ed75bdd2c96..11c53d02700 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -48,7 +48,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_state.h" #include "r300_ioctl.h" #include "radeon_ioctl.h" -#include "r300_mipmap_tree.h" +#include "radeon_mipmap_tree.h" #include "r300_tex.h" #include "r300_reg.h" #include "radeon_buffer.h" @@ -145,12 +145,12 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj) }, }; const GLuint *format; - r300TexObjPtr t; + radeonTexObjPtr t; if (!tObj) return; - t = r300_tex_obj(tObj); + t = radeon_tex_obj(tObj); switch (tObj->Image[0][tObj->BaseLevel]->TexFormat->MesaFormat) { case MESA_FORMAT_Z16: @@ -172,13 +172,13 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj) switch (tObj->DepthMode) { case GL_LUMINANCE: - t->format = format[0]; + t->pp_txformat = format[0]; break; case GL_INTENSITY: - t->format = format[1]; + t->pp_txformat = format[1]; break; case GL_ALPHA: - t->format = format[2]; + t->pp_txformat = format[2]; break; default: /* Error...which should have already been caught by higher @@ -196,7 +196,7 @@ void r300SetDepthTexMode(struct gl_texture_object *tObj) * \param rmesa Context pointer * \param t the r300 texture object */ -static void setup_hardware_state(r300ContextPtr rmesa, r300TexObj *t) +static void setup_hardware_state(r300ContextPtr rmesa, radeonTexObj *t) { const struct gl_texture_image *firstImage = t->base.Image[0][t->mt->firstLevel]; @@ -206,10 +206,10 @@ static void setup_hardware_state(r300ContextPtr rmesa, r300TexObj *t) if (firstImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) { r300SetDepthTexMode(&t->base); } else { - t->format = tx_table[firstImage->TexFormat->MesaFormat].format; + t->pp_txformat = tx_table[firstImage->TexFormat->MesaFormat].format; } - t->filter |= tx_table[firstImage->TexFormat->MesaFormat].filter; + t->pp_txfilter |= tx_table[firstImage->TexFormat->MesaFormat].filter; } else if (!t->image_override) { _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__); @@ -219,26 +219,26 @@ static void setup_hardware_state(r300ContextPtr rmesa, r300TexObj *t) t->tile_bits = 0; if (t->base.Target == GL_TEXTURE_CUBE_MAP) - t->format |= R300_TX_FORMAT_CUBIC_MAP; + t->pp_txformat |= R300_TX_FORMAT_CUBIC_MAP; if (t->base.Target == GL_TEXTURE_3D) - t->format |= R300_TX_FORMAT_3D; + t->pp_txformat |= R300_TX_FORMAT_3D; - t->size = (((firstImage->Width - 1) << R300_TX_WIDTHMASK_SHIFT) + t->pp_txsize = (((firstImage->Width - 1) << R300_TX_WIDTHMASK_SHIFT) | ((firstImage->Height - 1) << R300_TX_HEIGHTMASK_SHIFT)) | ((t->mt->lastLevel - t->mt->firstLevel) << R300_TX_MAX_MIP_LEVEL_SHIFT); if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) { unsigned int align = (64 / t->mt->bpp) - 1; - t->size |= R300_TX_SIZE_TXPITCH_EN; + t->pp_txsize |= R300_TX_SIZE_TXPITCH_EN; if (!t->image_override) - t->pitch_reg = ((firstImage->Width + align) & ~align) - 1; + t->pp_txpitch = ((firstImage->Width + align) & ~align) - 1; } if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { if (firstImage->Width > 2048) - t->pitch_reg |= R500_TXWIDTH_BIT11; + t->pp_txpitch |= R500_TXWIDTH_BIT11; if (firstImage->Height > 2048) - t->pitch_reg |= R500_TXHEIGHT_BIT11; + t->pp_txpitch |= R500_TXHEIGHT_BIT11; } } @@ -265,9 +265,9 @@ static void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcst /** * Ensure that the given image is stored in the given miptree from now on. */ -static void migrate_image_to_miptree(r300_mipmap_tree *mt, r300_texture_image *image, int face, int level) +static void migrate_image_to_miptree(radeon_mipmap_tree *mt, r300_texture_image *image, int face, int level) { - r300_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel]; + radeon_mipmap_level *dstlvl = &mt->levels[level - mt->firstLevel]; unsigned char *dest; assert(image->mt != mt); @@ -283,7 +283,7 @@ static void migrate_image_to_miptree(r300_mipmap_tree *mt, r300_texture_image *i * In fact, that memcpy() could be done by the hardware in many * cases, provided that we have a proper memory manager. */ - r300_mipmap_level *srclvl = &image->mt->levels[image->mtlevel]; + radeon_mipmap_level *srclvl = &image->mt->levels[image->mtlevel]; assert(srclvl->size == dstlvl->size); assert(srclvl->rowstride == dstlvl->rowstride); @@ -294,7 +294,7 @@ static void migrate_image_to_miptree(r300_mipmap_tree *mt, r300_texture_image *i dstlvl->size); radeon_bo_unmap(image->mt->bo); - r300_miptree_unreference(image->mt); + radeon_miptree_unreference(image->mt); } else { uint srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes; @@ -313,7 +313,7 @@ static void migrate_image_to_miptree(r300_mipmap_tree *mt, r300_texture_image *i image->mt = mt; image->mtface = face; image->mtlevel = level; - r300_miptree_reference(image->mt); + radeon_miptree_reference(image->mt); } @@ -325,7 +325,7 @@ static void migrate_image_to_miptree(r300_mipmap_tree *mt, r300_texture_image *i static GLboolean r300_validate_texture(GLcontext * ctx, struct gl_texture_object *texObj) { r300ContextPtr rmesa = R300_CONTEXT(ctx); - r300TexObj *t = r300_tex_obj(texObj); + radeonTexObj *t = radeon_tex_obj(texObj); r300_texture_image *baseimage = get_r300_texture_image(texObj->Image[0][texObj->BaseLevel]); int face, level; @@ -350,19 +350,19 @@ static GLboolean r300_validate_texture(GLcontext * ctx, struct gl_texture_object */ if (baseimage->mt && baseimage->mt != t->mt && - r300_miptree_matches_texture(baseimage->mt, &t->base)) { - r300_miptree_unreference(t->mt); + radeon_miptree_matches_texture(baseimage->mt, &t->base)) { + radeon_miptree_unreference(t->mt); t->mt = baseimage->mt; - r300_miptree_reference(t->mt); - } else if (t->mt && !r300_miptree_matches_texture(t->mt, &t->base)) { - r300_miptree_unreference(t->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"); - r300_try_alloc_miptree(rmesa, t, &baseimage->base, 0, texObj->BaseLevel); + 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; @@ -421,7 +421,7 @@ void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname, r300ContextPtr rmesa = pDRICtx->driverPrivate; struct gl_texture_object *tObj = _mesa_lookup_texture(rmesa->radeon.glCtx, texname); - r300TexObjPtr t = r300_tex_obj(tObj); + radeonTexObjPtr t = radeon_tex_obj(tObj); uint32_t pitch_val; if (!tObj) @@ -433,30 +433,30 @@ void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname, return; t->bo = NULL; t->override_offset = offset; - t->pitch_reg &= (1 << 13) -1; + t->pp_txpitch &= (1 << 13) -1; pitch_val = pitch; switch (depth) { case 32: - t->format = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8); - t->filter |= tx_table[2].filter; + t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8); + t->pp_txfilter |= tx_table[2].filter; pitch_val /= 4; break; case 24: default: - t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8); - t->filter |= tx_table[4].filter; + t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8); + t->pp_txfilter |= tx_table[4].filter; pitch_val /= 4; break; case 16: - t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5); - t->filter |= tx_table[5].filter; + t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5); + t->pp_txfilter |= tx_table[5].filter; pitch_val /= 2; break; } pitch_val--; - t->pitch_reg |= pitch_val; + t->pp_txpitch |= pitch_val; } void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) @@ -469,7 +469,7 @@ void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) radeonContextPtr radeon; r300ContextPtr rmesa; GLframebuffer *fb; - r300TexObjPtr t; + radeonTexObjPtr t; uint32_t pitch_val; target = GL_TEXTURE_RECTANGLE_ARB; @@ -483,7 +483,7 @@ void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0); rImage = get_r300_texture_image(texImage); - t = r300_tex_obj(texObj); + t = radeon_tex_obj(texObj); if (t == NULL) { return; } @@ -514,7 +514,7 @@ void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) t->mt = NULL; } if (rImage->mt) { - r300_miptree_unreference(rImage->mt); + radeon_miptree_unreference(rImage->mt); rImage->mt = NULL; } fprintf(stderr,"settexbuf %dx%d@%d\n", rb->width, rb->height, rb->cpp); @@ -527,31 +527,31 @@ void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) t->tile_bits = 0; t->image_override = GL_TRUE; t->override_offset = 0; - t->pitch_reg &= (1 << 13) -1; + t->pp_txpitch &= (1 << 13) -1; pitch_val = rb->pitch; switch (rb->cpp) { case 4: - t->format = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8); - t->filter |= tx_table[2].filter; + t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8); + t->pp_txfilter |= tx_table[2].filter; pitch_val /= 4; break; case 3: default: - t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8); - t->filter |= tx_table[4].filter; + t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8); + t->pp_txfilter |= tx_table[4].filter; pitch_val /= 4; break; case 2: - t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5); - t->filter |= tx_table[5].filter; + t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5); + t->pp_txfilter |= tx_table[5].filter; pitch_val /= 2; break; } pitch_val--; - t->size = ((rb->width - 1) << R300_TX_WIDTHMASK_SHIFT) | + t->pp_txsize = ((rb->width - 1) << R300_TX_WIDTHMASK_SHIFT) | ((rb->height - 1) << R300_TX_HEIGHTMASK_SHIFT); - t->size |= R300_TX_SIZE_TXPITCH_EN; - t->pitch_reg |= pitch_val; + t->pp_txsize |= R300_TX_SIZE_TXPITCH_EN; + t->pp_txpitch |= pitch_val; t->validated = GL_TRUE; _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 22fb908fb4b..462b072676a 100644 --- a/src/mesa/drivers/dri/radeon/common_context.h +++ b/src/mesa/drivers/dri/radeon/common_context.h @@ -112,11 +112,25 @@ struct radeon_state_atom { typedef struct radeon_tex_obj radeonTexObj, *radeonTexObjPtr; +#define RADEON_TXO_MICRO_TILE (1 << 3) + /* Texture object in locally shared texture space. */ -#ifndef RADEON_COMMON_FOR_R300 struct radeon_tex_obj { - driTextureObject base; + // driTextureObject base; + struct gl_texture_object base; + struct _radeon_mipmap_tree *mt; + + /** + * This is true if we've verified that the mipmap tree above is complete + * and so on. + */ + GLboolean validated; + + GLuint override_offset; + GLboolean image_override; /* Image overridden by GLX_EXT_tfp */ + GLuint tile_bits; /* hw texture tile bits used on this texture */ + struct radeon_bo *bo; GLuint bufAddr; /* Offset to start of locally shared texture block */ @@ -131,7 +145,7 @@ struct radeon_tex_obj { drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS]; /* Six, for the cube faces */ - GLboolean image_override; /* Image overridden by GLX_EXT_tfp */ + GLuint pp_txfilter; /* hardware register values */ GLuint pp_txformat; @@ -143,11 +157,17 @@ struct radeon_tex_obj { GLuint pp_border_color; GLuint pp_cubic_faces; /* cube face 1,2,3,4 log2 sizes */ + GLuint pp_txfilter_1; /* r300 */ + GLboolean border_fallback; - GLuint tile_bits; /* hw texture tile bits used on this texture */ + }; -#endif + +static INLINE radeonTexObj* radeon_tex_obj(struct gl_texture_object *texObj) +{ + return (radeonTexObj*)texObj; +} /* Need refcounting on dma buffers: */ diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c new file mode 100644 index 00000000000..955d4b71ed5 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c @@ -0,0 +1,319 @@ +/* + * Copyright (C) 2008 Nicolai Haehnle. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "radeon_mipmap_tree.h" + +#include +#include + +#include "main/simple_list.h" +#include "main/texcompress.h" +#include "main/texformat.h" + +#include "radeon_buffer.h" + +static GLuint radeon_compressed_texture_size(GLcontext *ctx, + GLsizei width, GLsizei height, GLsizei depth, + GLuint mesaFormat) +{ + GLuint size = _mesa_compressed_texture_size(ctx, width, height, depth, mesaFormat); + + if (mesaFormat == MESA_FORMAT_RGB_DXT1 || + mesaFormat == MESA_FORMAT_RGBA_DXT1) { + if (width + 3 < 8) /* width one block */ + size = size * 4; + else if (width + 3 < 16) + size = size * 2; + } else { + /* DXT3/5, 16 bytes per block */ + // WARN_ONCE("DXT 3/5 suffers from multitexturing problems!\n"); + if (width + 3 < 8) + size = size * 2; + } + + return size; +} + +/** + * Compute sizes and fill in offset and blit information for the given + * image (determined by \p face and \p level). + * + * \param curOffset points to the offset at which the image is to be stored + * and is updated by this function according to the size of the image. + */ +static void compute_tex_image_offset(radeon_mipmap_tree *mt, + GLuint face, GLuint level, GLuint* curOffset) +{ + radeon_mipmap_level *lvl = &mt->levels[level]; + + /* Find image size in bytes */ + if (mt->compressed) { + /* TODO: Is this correct? Need test cases for compressed textures! */ + GLuint align; + + if (mt->target == GL_TEXTURE_RECTANGLE_NV) + align = 64 / mt->bpp; + else + align = 32 / mt->bpp; + lvl->rowstride = (lvl->width + align - 1) & ~(align - 1); + lvl->size = radeon_compressed_texture_size(mt->radeon->glCtx, + lvl->width, lvl->height, lvl->depth, mt->compressed); + } else if (mt->target == GL_TEXTURE_RECTANGLE_NV) { + lvl->rowstride = (lvl->width * mt->bpp + 63) & ~63; + lvl->size = lvl->rowstride * lvl->height; + } else if (mt->tilebits & RADEON_TXO_MICRO_TILE) { + /* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned, + * though the actual offset may be different (if texture is less than + * 32 bytes width) to the untiled case */ + lvl->rowstride = (lvl->width * mt->bpp * 2 + 31) & ~31; + lvl->size = lvl->rowstride * ((lvl->height + 1) / 2) * lvl->depth; + } else { + lvl->rowstride = (lvl->width * mt->bpp + 31) & ~31; + lvl->size = lvl->rowstride * lvl->height * lvl->depth; + } + assert(lvl->size > 0); + + /* All images are aligned to a 32-byte offset */ + *curOffset = (*curOffset + 0x1f) & ~0x1f; + lvl->faces[face].offset = *curOffset; + *curOffset += lvl->size; +} + +static GLuint minify(GLuint size, GLuint levels) +{ + size = size >> levels; + if (size < 1) + size = 1; + return size; +} + +static void calculate_miptree_layout(radeon_mipmap_tree *mt) +{ + GLuint curOffset; + GLuint numLevels; + GLuint i; + + numLevels = mt->lastLevel - mt->firstLevel + 1; + assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS); + + curOffset = 0; + for(i = 0; i < numLevels; i++) { + GLuint face; + + mt->levels[i].width = minify(mt->width0, i); + mt->levels[i].height = minify(mt->height0, i); + mt->levels[i].depth = minify(mt->depth0, i); + + for(face = 0; face < mt->faces; face++) + compute_tex_image_offset(mt, face, i, &curOffset); + } + + /* Note the required size in memory */ + mt->totalsize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; +} + + +/** + * Create a new mipmap tree, calculate its layout and allocate memory. + */ +radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, radeonTexObj *t, + GLenum target, GLuint firstLevel, GLuint lastLevel, + GLuint width0, GLuint height0, GLuint depth0, + GLuint bpp, GLuint tilebits, GLuint compressed) +{ + radeon_mipmap_tree *mt = CALLOC_STRUCT(_radeon_mipmap_tree); + + mt->radeon = rmesa; + mt->refcount = 1; + mt->t = t; + mt->target = target; + mt->faces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; + mt->firstLevel = firstLevel; + mt->lastLevel = lastLevel; + mt->width0 = width0; + mt->height0 = height0; + mt->depth0 = depth0; + mt->bpp = bpp; + mt->tilebits = tilebits; + mt->compressed = compressed; + + calculate_miptree_layout(mt); + + mt->bo = radeon_bo_open(rmesa->radeonScreen->bom, + 0, mt->totalsize, 1024, + RADEON_GEM_DOMAIN_VRAM, + 0); + + return mt; +} + +void radeon_miptree_reference(radeon_mipmap_tree *mt) +{ + mt->refcount++; + assert(mt->refcount > 0); +} + +void radeon_miptree_unreference(radeon_mipmap_tree *mt) +{ + if (!mt) + return; + + assert(mt->refcount > 0); + mt->refcount--; + if (!mt->refcount) { + radeon_bo_unref(mt->bo); + free(mt); + } +} + + +static void calculate_first_last_level(struct gl_texture_object *tObj, + GLuint *pfirstLevel, GLuint *plastLevel) +{ + const struct gl_texture_image * const baseImage = + tObj->Image[0][tObj->BaseLevel]; + + /* These must be signed values. MinLod and MaxLod can be negative numbers, + * and having firstLevel and lastLevel as signed prevents the need for + * extra sign checks. + */ + int firstLevel; + int lastLevel; + + /* Yes, this looks overly complicated, but it's all needed. + */ + switch (tObj->Target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + case GL_TEXTURE_CUBE_MAP: + if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) { + /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL. + */ + firstLevel = lastLevel = tObj->BaseLevel; + } else { + firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5); + firstLevel = MAX2(firstLevel, tObj->BaseLevel); + firstLevel = MIN2(firstLevel, tObj->BaseLevel + baseImage->MaxLog2); + lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5); + lastLevel = MAX2(lastLevel, tObj->BaseLevel); + lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); + lastLevel = MIN2(lastLevel, tObj->MaxLevel); + lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ + } + break; + case GL_TEXTURE_RECTANGLE_NV: + case GL_TEXTURE_4D_SGIS: + firstLevel = lastLevel = 0; + break; + default: + return; + } + + /* save these values */ + *pfirstLevel = firstLevel; + *plastLevel = lastLevel; +} + + +/** + * Checks whether the given miptree can hold the given texture image at the + * given face and level. + */ +GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt, + struct gl_texture_image *texImage, GLuint face, GLuint level) +{ + radeon_mipmap_level *lvl; + + if (face >= mt->faces || level < mt->firstLevel || level > mt->lastLevel) + return GL_FALSE; + + if (texImage->TexFormat->TexelBytes != mt->bpp) + return GL_FALSE; + + lvl = &mt->levels[level - mt->firstLevel]; + if (lvl->width != texImage->Width || + lvl->height != texImage->Height || + lvl->depth != texImage->Depth) + return GL_FALSE; + + return GL_TRUE; +} + + +/** + * Checks whether the given miptree has the right format to store the given texture object. + */ +GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_texture_object *texObj) +{ + struct gl_texture_image *firstImage; + GLuint compressed; + GLuint numfaces = 1; + GLuint firstLevel, lastLevel; + + calculate_first_last_level(texObj, &firstLevel, &lastLevel); + if (texObj->Target == GL_TEXTURE_CUBE_MAP) + numfaces = 6; + + firstImage = texObj->Image[0][firstLevel]; + compressed = firstImage->IsCompressed ? firstImage->TexFormat->MesaFormat : 0; + + return (mt->firstLevel == firstLevel && + mt->lastLevel == lastLevel && + mt->width0 == firstImage->Width && + mt->height0 == firstImage->Height && + mt->depth0 == firstImage->Depth && + mt->bpp == firstImage->TexFormat->TexelBytes && + mt->compressed == compressed); +} + + +/** + * Try to allocate a mipmap tree for the given texture that will fit the + * given image in the given position. + */ +void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t, + struct gl_texture_image *texImage, GLuint face, GLuint level) +{ + GLuint compressed = texImage->IsCompressed ? texImage->TexFormat->MesaFormat : 0; + GLuint numfaces = 1; + GLuint firstLevel, lastLevel; + + assert(!t->mt); + + calculate_first_last_level(&t->base, &firstLevel, &lastLevel); + if (t->base.Target == GL_TEXTURE_CUBE_MAP) + numfaces = 6; + + if (level != firstLevel || face >= numfaces) + return; + + t->mt = radeon_miptree_create(rmesa, t, t->base.Target, + firstLevel, lastLevel, + texImage->Width, texImage->Height, texImage->Depth, + texImage->TexFormat->TexelBytes, t->tile_bits, compressed); +} diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h new file mode 100644 index 00000000000..875e5e5aee6 --- /dev/null +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2008 Nicolai Haehnle. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __RADEON_MIPMAP_TREE_H_ +#define __RADEON_MIPMAP_TREE_H_ + +#include "common_context.h" + +typedef struct _radeon_mipmap_tree radeon_mipmap_tree; +typedef struct _radeon_mipmap_level radeon_mipmap_level; +typedef struct _radeon_mipmap_image radeon_mipmap_image; + +struct _radeon_mipmap_image { + GLuint offset; /** Offset of this image from the start of mipmap tree buffer, in bytes */ +}; + +struct _radeon_mipmap_level { + GLuint width; + GLuint height; + GLuint depth; + GLuint size; /** Size of each image, in bytes */ + GLuint rowstride; /** in bytes */ + radeon_mipmap_image faces[6]; +}; + + +/** + * A mipmap tree contains texture images in the layout that the hardware + * expects. + * + * The meta-data of mipmap trees is immutable, i.e. you cannot change the + * layout on-the-fly; however, the texture contents (i.e. texels) can be + * changed. + */ +struct _radeon_mipmap_tree { + radeonContextPtr radeon; + radeonTexObj *t; + struct radeon_bo *bo; + GLuint refcount; + + GLuint totalsize; /** total size of the miptree, in bytes */ + + GLenum target; /** GL_TEXTURE_xxx */ + GLuint faces; /** # of faces: 6 for cubemaps, 1 otherwise */ + GLuint firstLevel; /** First mip level stored in this mipmap tree */ + GLuint lastLevel; /** Last mip level stored in this mipmap tree */ + + GLuint width0; /** Width of firstLevel image */ + GLuint height0; /** Height of firstLevel image */ + GLuint depth0; /** Depth of firstLevel image */ + + GLuint bpp; /** Bytes per texel */ + GLuint tilebits; /** RADEON_TXO_xxx_TILE */ + GLuint compressed; /** MESA_FORMAT_xxx indicating a compressed format, or 0 if uncompressed */ + + radeon_mipmap_level levels[RADEON_MAX_TEXTURE_LEVELS]; +}; + +radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, radeonTexObj *t, + GLenum target, GLuint firstLevel, GLuint lastLevel, + GLuint width0, GLuint height0, GLuint depth0, + GLuint bpp, GLuint tilebits, GLuint compressed); +void radeon_miptree_reference(radeon_mipmap_tree *mt); +void radeon_miptree_unreference(radeon_mipmap_tree *mt); + +GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt, + struct gl_texture_image *texImage, GLuint face, GLuint level); +GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_texture_object *texObj); +void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t, + struct gl_texture_image *texImage, GLuint face, GLuint level); + + +#endif /* __RADEON_MIPMAP_TREE_H_ */