diff options
Diffstat (limited to 'src/mesa/drivers/dri/i915/i915_texstate.c')
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_texstate.c | 975 |
1 files changed, 0 insertions, 975 deletions
diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c deleted file mode 100644 index 2b806cc36ef..00000000000 --- a/src/mesa/drivers/dri/i915/i915_texstate.c +++ /dev/null @@ -1,975 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * 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, sub license, 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 NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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 "glheader.h" -#include "macros.h" -#include "mtypes.h" -#include "simple_list.h" -#include "enums.h" -#include "texformat.h" -#include "texstore.h" - -#include "mm.h" - -#include "intel_screen.h" -#include "intel_ioctl.h" -#include "intel_tex.h" - -#include "i915_context.h" -#include "i915_reg.h" - -static GLint initial_offsets[6][2] = { {0,0}, - {0,2}, - {1,0}, - {1,2}, - {1,1}, - {1,3} }; - - -static GLint step_offsets[6][2] = { {0,2}, - {0,2}, - {-1,2}, - {-1,2}, - {-1,1}, - {-1,1} }; - - -#define I915_TEX_UNIT_ENABLED(unit) (1<<unit) - -static GLuint i915_compressed_alignment(GLint internal_fmt) -{ - GLuint alignment = 4; - - switch (internal_fmt) { - case GL_COMPRESSED_RGB_FXT1_3DFX: - case GL_COMPRESSED_RGBA_FXT1_3DFX: - alignment = 8; - break; - - default: - break; - } - - return alignment; -} - -static int align(int value, GLuint alignment) -{ - return (value + alignment - 1) & ~(alignment - 1); -} - -static GLuint minify(GLuint d) -{ - return MAX2(1, d >> 1); -} - -static void i915LayoutTextureImages( i915ContextPtr i915, - struct gl_texture_object *tObj ) -{ - const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel]; - i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData; - GLint firstLevel, lastLevel, numLevels; - GLint i, total_height, pitch; - - /* Compute which mipmap levels we really want to send to the hardware. - */ - driCalculateTextureFirstLastLevel( (driTextureObject *) t ); - - /* Figure out the amount of memory required to hold all the mipmap - * levels. Choose the smallest pitch to accomodate the largest - * mipmap: - */ - firstLevel = t->intel.base.firstLevel; - lastLevel = t->intel.base.lastLevel; - numLevels = lastLevel - firstLevel + 1; - - - - /* All images must be loaded at this pitch. Count the number of - * lines required: - */ - switch (tObj->Target) { - case GL_TEXTURE_CUBE_MAP: { - const GLuint dim = tObj->Image[0][firstLevel]->Width; - GLuint face; - - pitch = dim * t->intel.texelBytes; - pitch *= 2; /* double pitch for cube layouts */ - pitch = (pitch + 3) & ~3; - - total_height = dim * 4; - - for ( face = 0 ; face < 6 ; face++) { - GLuint x = initial_offsets[face][0] * dim; - GLuint y = initial_offsets[face][1] * dim; - GLuint d = dim; - - t->intel.base.dirty_images[face] = ~0; - - assert(tObj->Image[face][firstLevel]->Width == dim); - assert(tObj->Image[face][firstLevel]->Height == dim); - - for (i = 0; i < numLevels; i++) { - t->intel.image[face][i].image = tObj->Image[face][firstLevel + i]; - if (!t->intel.image[face][i].image) { - fprintf(stderr, "no image %d %d\n", face, i); - break; /* can't happen */ - } - - t->intel.image[face][i].offset = - y * pitch + x * t->intel.texelBytes; - t->intel.image[face][i].internalFormat = baseImage->_BaseFormat; - - d >>= 1; - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - } - } - break; - } - case GL_TEXTURE_3D: { - GLuint virtual_height; - GLuint tmp_numLevels = numLevels; - pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes; - pitch = (pitch + 3) & ~3; - t->intel.base.dirty_images[0] = ~0; - - /* Calculate the size of a single slice. Hardware demands a - * minimum of 8 mipmaps, some of which might ultimately not be - * used: - */ - if (tmp_numLevels < 9) - tmp_numLevels = 9; - - virtual_height = tObj->Image[0][firstLevel]->Height; - - for ( total_height = i = 0 ; i < tmp_numLevels ; i++ ) { - t->intel.image[0][i].image = tObj->Image[0][firstLevel + i]; - if (t->intel.image[0][i].image) { - t->intel.image[0][i].offset = total_height * pitch; - t->intel.image[0][i].internalFormat = baseImage->_BaseFormat; - } - - total_height += MAX2(2, virtual_height); - virtual_height >>= 1; - } - - t->intel.depth_pitch = total_height * pitch; - - /* Multiply slice size by texture depth for total size. It's - * remarkable how wasteful of memory all the i8x0 texture - * layouts are. - */ - total_height *= t->intel.image[0][0].image->Depth; - break; - } - default: - if (baseImage->IsCompressed) { - GLuint alignment = i915_compressed_alignment(baseImage->InternalFormat); - - pitch = align(tObj->Image[0][firstLevel]->Width, alignment) * t->intel.texelBytes; - } else { - pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes; - pitch = (pitch + 3) & ~3; - } - - t->intel.base.dirty_images[0] = ~0; - - for ( total_height = i = 0 ; i < numLevels ; i++ ) { - t->intel.image[0][i].image = tObj->Image[0][firstLevel + i]; - if (!t->intel.image[0][i].image) - break; - - t->intel.image[0][i].offset = total_height * pitch; - t->intel.image[0][i].internalFormat = baseImage->_BaseFormat; - if (t->intel.image[0][i].image->IsCompressed) { - total_height += (t->intel.image[0][i].image->Height + 3) / 4; - } - else - total_height += MAX2(2, t->intel.image[0][i].image->Height); - } - break; - } - - t->intel.Pitch = pitch; - t->intel.base.totalSize = total_height*pitch; - t->intel.max_level = numLevels-1; -} - - -static void i945LayoutTextureImages( i915ContextPtr i915, - struct gl_texture_object *tObj ) -{ - const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel]; - i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData; - GLint firstLevel, lastLevel, numLevels; - GLint i, total_height, pitch, sz, max_offset = 0, offset; - - - /* Compute which mipmap levels we really want to send to the hardware. - */ - driCalculateTextureFirstLastLevel( (driTextureObject *) t ); - - /* Figure out the amount of memory required to hold all the mipmap - * levels. Choose the smallest pitch to accomodate the largest - * mipmap: - */ - firstLevel = t->intel.base.firstLevel; - lastLevel = t->intel.base.lastLevel; - numLevels = lastLevel - firstLevel + 1; - - - - /* All images must be loaded at this pitch. Count the number of - * lines required: - */ - switch (tObj->Target) { - case GL_TEXTURE_CUBE_MAP: { - const GLuint dim = tObj->Image[0][firstLevel]->Width; - GLuint face; - - /* Depending on the size of the largest images, pitch can be - * determined either by the old-style packing of cubemap faces, - * or the final row of 4x4, 2x2 and 1x1 faces below this. - */ - if (dim > 32) { - pitch = dim * t->intel.texelBytes; - pitch *= 2; /* double pitch for cube layouts */ - pitch = (pitch + 3) & ~3; - } - else { - pitch = 14 * 8 * t->intel.texelBytes; /* determined by row of - * little maps at - * bottom */ - } - - total_height = dim * 4 + 4; - - for ( face = 0 ; face < 6 ; face++) { - GLuint x = initial_offsets[face][0] * dim; - GLuint y = initial_offsets[face][1] * dim; - GLuint d = dim; - - if (dim == 4 && face >= 4) { - y = total_height - 4; - x = (face - 4) * 8; - } - else if (dim < 4) { - y = total_height - 4; - x = face * 8; - } - - t->intel.base.dirty_images[face] = ~0; - - assert(tObj->Image[face][firstLevel]->Width == dim); - assert(tObj->Image[face][firstLevel]->Height == dim); - - for (i = 0; i < numLevels; i++) { - - - t->intel.image[face][i].image = tObj->Image[face][firstLevel + i]; - assert(t->intel.image[face][i].image); - - t->intel.image[face][i].offset = - y * pitch + x * t->intel.texelBytes; - t->intel.image[face][i].internalFormat = baseImage->_BaseFormat; - - d >>= 1; - - switch (d) { - case 4: - switch (face) { - case FACE_POS_X: - case FACE_NEG_X: - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - break; - case FACE_POS_Y: - case FACE_NEG_Y: - y += 12; - x -= 8; - break; - case FACE_POS_Z: - case FACE_NEG_Z: - y = total_height - 4; - x = (face - 4) * 8; - break; - } - - case 2: - y = total_height - 4; - x = 16 + face * 8; - break; - - case 1: - x += 48; - break; - - default: - x += step_offsets[face][0] * d; - y += step_offsets[face][1] * d; - break; - } - } - } - max_offset = total_height * pitch; - break; - } - case GL_TEXTURE_3D: { - GLuint depth_packing = 0, depth_pack_pitch; - GLuint tmp_numLevels = numLevels; - pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes; - pitch = (pitch + 3) & ~3; - depth_pack_pitch = pitch; - - t->intel.base.dirty_images[0] = ~0; - - - for ( total_height = i = 0 ; i < tmp_numLevels ; i++ ) { - t->intel.image[0][i].image = tObj->Image[0][firstLevel + i]; - if (!t->intel.image[0][i].image) - break; - - - t->intel.image[0][i].offset = total_height * pitch; - t->intel.image[0][i].internalFormat = baseImage->_BaseFormat; - - - - total_height += MAX2(2, t->intel.image[0][i].image->Height) * - MAX2((t->intel.image[0][i].image->Depth >> depth_packing), 1); - - /* When alignment dominates, can't increase depth packing? - * Or does pitch grow??? What are the alignment constraints, - * anyway? - */ - if (depth_pack_pitch > 4) { - depth_packing++; - depth_pack_pitch <<= 2; - } - } - - max_offset = total_height * pitch; - break; - } - default: - if (baseImage->IsCompressed) { - GLuint alignment = i915_compressed_alignment(baseImage->InternalFormat); - - pitch = align(tObj->Image[0][firstLevel]->Width, alignment); - if (numLevels > 2) { - GLint width0 = align(minify(tObj->Image[0][firstLevel]->Width), alignment) + - + align(minify(minify(tObj->Image[0][firstLevel]->Width)), alignment); - - if (width0 > pitch) - pitch = width0; - } - pitch = pitch * t->intel.texelBytes; - } else { - pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes; - pitch = (pitch + 3) & ~3; - } - - t->intel.base.dirty_images[0] = ~0; - max_offset = 0; - - for ( offset = i = 0 ; i < numLevels ; i++ ) { - t->intel.image[0][i].image = tObj->Image[0][firstLevel + i]; - if (!t->intel.image[0][i].image) - break; - - t->intel.image[0][i].offset = offset; - t->intel.image[0][i].internalFormat = baseImage->_BaseFormat; - - if (t->intel.image[0][i].image->IsCompressed) - sz = MAX2(1, t->intel.image[0][i].image->Height/4) * pitch; - else - sz = MAX2(2, t->intel.image[0][i].image->Height) * pitch; - - /* Because the images are packed better, the final offset - * might not be the maximal one: - */ - max_offset = MAX2(max_offset, offset + sz); - - /* LPT change: step right after second mipmap. - */ - if (i == 1) - offset += pitch / 2; - else - offset += sz; - - } - break; - } - - t->intel.Pitch = pitch; - t->intel.base.totalSize = max_offset; - t->intel.max_level = numLevels-1; -} - - - - -static void i915SetTexImages( i915ContextPtr i915, - struct gl_texture_object *tObj ) -{ - GLuint textureFormat; - i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData; - const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel]; - GLint ss2 = 0; - - switch( baseImage->TexFormat->MesaFormat ) { - case MESA_FORMAT_L8: - t->intel.texelBytes = 1; - textureFormat = MAPSURF_8BIT | MT_8BIT_L8; - break; - - case MESA_FORMAT_I8: - t->intel.texelBytes = 1; - textureFormat = MAPSURF_8BIT | MT_8BIT_I8; - break; - - case MESA_FORMAT_A8: - t->intel.texelBytes = 1; - textureFormat = MAPSURF_8BIT | MT_8BIT_A8; - break; - - case MESA_FORMAT_AL88: - t->intel.texelBytes = 2; - textureFormat = MAPSURF_16BIT | MT_16BIT_AY88; - break; - - case MESA_FORMAT_RGB565: - t->intel.texelBytes = 2; - textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565; - break; - - case MESA_FORMAT_ARGB1555: - t->intel.texelBytes = 2; - textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555; - break; - - case MESA_FORMAT_ARGB4444: - t->intel.texelBytes = 2; - textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB4444; - break; - - case MESA_FORMAT_ARGB8888: - t->intel.texelBytes = 4; - textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888; - break; - - case MESA_FORMAT_YCBCR_REV: - t->intel.texelBytes = 2; - textureFormat = (MAPSURF_422 | MT_422_YCRCB_NORMAL); - ss2 |= SS2_COLORSPACE_CONVERSION; - break; - - case MESA_FORMAT_YCBCR: - t->intel.texelBytes = 2; - textureFormat = (MAPSURF_422 | MT_422_YCRCB_SWAPY); - ss2 |= SS2_COLORSPACE_CONVERSION; - break; - - case MESA_FORMAT_RGB_FXT1: - case MESA_FORMAT_RGBA_FXT1: - t->intel.texelBytes = 2; - textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); - break; - - case MESA_FORMAT_Z16: - t->intel.texelBytes = 2; - textureFormat = (MAPSURF_16BIT | MT_16BIT_L16); - break; - - case MESA_FORMAT_RGBA_DXT1: - case MESA_FORMAT_RGB_DXT1: - /* - * DXTn pitches are Width/4 * blocksize in bytes - * for DXT1: blocksize=8 so Width/4*8 = Width * 2 - * for DXT3/5: blocksize=16 so Width/4*16 = Width * 4 - */ - t->intel.texelBytes = 2; - textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); - break; - - case MESA_FORMAT_RGBA_DXT3: - t->intel.texelBytes = 4; - textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); - break; - - case MESA_FORMAT_RGBA_DXT5: - t->intel.texelBytes = 4; - textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); - break; - -#if 0 - case MESA_FORMAT_Z24_S8: - t->intel.texelBytes = 4; - textureFormat = (MAPSURF_32BIT | MT_32BIT_xL824); - break; -#endif - - default: - fprintf(stderr, "%s: bad image format %x\n", __FUNCTION__, - baseImage->TexFormat->MesaFormat); - abort(); - } - - switch (i915->intel.intelScreen->deviceID) { - case PCI_CHIP_I945_G: - case PCI_CHIP_I945_GM: - case PCI_CHIP_I945_GME: - case PCI_CHIP_G33_G: - case PCI_CHIP_Q33_G: - case PCI_CHIP_Q35_G: - i945LayoutTextureImages( i915, tObj ); - break; - default: - i915LayoutTextureImages( i915, tObj ); - break; - } - - t->Setup[I915_TEXREG_MS3] = - (((tObj->Image[0][t->intel.base.firstLevel]->Height - 1) << MS3_HEIGHT_SHIFT) | - ((tObj->Image[0][t->intel.base.firstLevel]->Width - 1) << MS3_WIDTH_SHIFT) | - textureFormat | - MS3_USE_FENCE_REGS); - - t->Setup[I915_TEXREG_MS4] = - ((((t->intel.Pitch / 4) - 1) << MS4_PITCH_SHIFT) | - MS4_CUBE_FACE_ENA_MASK | - (((t->intel.max_level * 4)) << MS4_MAX_LOD_SHIFT) | - ((tObj->Image[0][t->intel.base.firstLevel]->Depth - 1) << MS4_VOLUME_DEPTH_SHIFT)); - - t->Setup[I915_TEXREG_SS2] &= ~(SS2_COLORSPACE_CONVERSION); - t->Setup[I915_TEXREG_SS2] |= ss2; - - t->intel.dirty = I915_UPLOAD_TEX_ALL; - -} - - -/* The i915 (and related graphics cores) do not support GL_CLAMP. The - * Intel drivers for "other operating systems" implement GL_CLAMP as - * GL_CLAMP_TO_EDGE, so the same is done here. - */ -static GLuint translate_wrap_mode( GLenum wrap ) -{ - switch( wrap ) { - case GL_REPEAT: return TEXCOORDMODE_WRAP; - case GL_CLAMP: return TEXCOORDMODE_CLAMP_EDGE; /* not quite correct */ - case GL_CLAMP_TO_EDGE: return TEXCOORDMODE_CLAMP_EDGE; - case GL_CLAMP_TO_BORDER: return TEXCOORDMODE_CLAMP_BORDER; - case GL_MIRRORED_REPEAT: return TEXCOORDMODE_MIRROR; - default: return TEXCOORDMODE_WRAP; - } -} - - -/** - */ -static void i915ImportTexObjState( struct gl_texture_object *texObj ) -{ - i915TextureObjectPtr t = (i915TextureObjectPtr)texObj->DriverData; - int minFilt = 0, mipFilt = 0, magFilt = 0, shadow = 0; - - if(INTEL_DEBUG&DEBUG_DRI) - fprintf(stderr, "%s\n", __FUNCTION__); - - switch (texObj->MinFilter) { - case GL_NEAREST: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_NONE; - break; - case GL_LINEAR: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_NONE; - break; - case GL_NEAREST_MIPMAP_NEAREST: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_NEAREST; - break; - case GL_LINEAR_MIPMAP_NEAREST: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_NEAREST; - break; - case GL_NEAREST_MIPMAP_LINEAR: - minFilt = FILTER_NEAREST; - mipFilt = MIPFILTER_LINEAR; - break; - case GL_LINEAR_MIPMAP_LINEAR: - minFilt = FILTER_LINEAR; - mipFilt = MIPFILTER_LINEAR; - break; - default: - break; - } - - if ( texObj->MaxAnisotropy > 1.0 ) { - minFilt = FILTER_ANISOTROPIC; - magFilt = FILTER_ANISOTROPIC; - } - else { - switch (texObj->MagFilter) { - case GL_NEAREST: - magFilt = FILTER_NEAREST; - break; - case GL_LINEAR: - magFilt = FILTER_LINEAR; - break; - default: - break; - } - } - - if (texObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB && - texObj->Target != GL_TEXTURE_3D) { - - shadow = SS2_SHADOW_ENABLE; - shadow |= intel_translate_compare_func( texObj->CompareFunc ); - - minFilt = FILTER_4X4_FLAT; - magFilt = FILTER_4X4_FLAT; - } - - - t->Setup[I915_TEXREG_SS2] &= ~(SS2_MIN_FILTER_MASK | - SS2_MIP_FILTER_MASK | - SS2_MAG_FILTER_MASK | - SS2_SHADOW_ENABLE | - SS2_SHADOW_FUNC_MASK); - t->Setup[I915_TEXREG_SS2] |= ((minFilt << SS2_MIN_FILTER_SHIFT) | - (mipFilt << SS2_MIP_FILTER_SHIFT) | - (magFilt << SS2_MAG_FILTER_SHIFT) | - shadow); - - { - GLuint ss3 = t->Setup[I915_TEXREG_SS3] & ~(SS3_TCX_ADDR_MODE_MASK | - SS3_TCY_ADDR_MODE_MASK | - SS3_TCZ_ADDR_MODE_MASK); - GLenum ws = texObj->WrapS; - GLenum wt = texObj->WrapT; - GLenum wr = texObj->WrapR; - - t->refs_border_color = 0; - - if (texObj->Target == GL_TEXTURE_3D && - (texObj->MinFilter != GL_NEAREST || - texObj->MagFilter != GL_NEAREST)) { - - /* Try to mimic GL_CLAMP functionality a little better - - * switch to CLAMP_TO_BORDER whenever a non-NEAREST filter is - * in use. Only do this for 3D textures at the moment -- - * doing it universally would fix the conform texbc.c - * failure, though. - */ - if (ws == GL_CLAMP) ws = GL_CLAMP_TO_BORDER; - if (wt == GL_CLAMP) wt = GL_CLAMP_TO_BORDER; - if (wr == GL_CLAMP) wr = GL_CLAMP_TO_BORDER; - - /* 3D textures don't seem to respect the border color. - * Fallback if there's ever a danger that they might refer to - * it. - */ - if (ws == GL_CLAMP_TO_BORDER) t->refs_border_color = 1; - if (wt == GL_CLAMP_TO_BORDER) t->refs_border_color = 1; - if (wr == GL_CLAMP_TO_BORDER) t->refs_border_color = 1; - } - - ss3 |= translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT; - ss3 |= translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT; - ss3 |= translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT; - - if (ss3 != t->Setup[I915_TEXREG_SS3]) { - t->intel.dirty = I915_UPLOAD_TEX_ALL; - t->Setup[I915_TEXREG_SS3] = ss3; - } - } - - { - const GLubyte *color = texObj->_BorderChan; - - t->Setup[I915_TEXREG_SS4] = INTEL_PACKCOLOR8888(color[0],color[1], - color[2],color[3]); - } -} - - - -static void i915_import_tex_unit( i915ContextPtr i915, - i915TextureObjectPtr t, - GLuint unit ) -{ - GLuint state[I915_TEX_SETUP_SIZE]; - - if(INTEL_DEBUG&DEBUG_TEXTURE) - fprintf(stderr, "%s unit(%d)\n", __FUNCTION__, unit); - - if (i915->intel.CurrentTexObj[unit]) - i915->intel.CurrentTexObj[unit]->base.bound &= ~(1U << unit); - - i915->intel.CurrentTexObj[unit] = (intelTextureObjectPtr)t; - t->intel.base.bound |= (1 << unit); - - if (t->intel.dirty & I915_UPLOAD_TEX(unit)) { - i915ImportTexObjState( t->intel.base.tObj ); - t->intel.dirty &= ~I915_UPLOAD_TEX(unit); - } - - state[I915_TEXREG_MS2] = t->intel.TextureOffset; - state[I915_TEXREG_MS3] = t->Setup[I915_TEXREG_MS3]; - state[I915_TEXREG_MS4] = t->Setup[I915_TEXREG_MS4]; - - state[I915_TEXREG_SS2] = (i915->state.Tex[unit][I915_TEXREG_SS2] & - SS2_LOD_BIAS_MASK); - state[I915_TEXREG_SS2] |= (t->Setup[I915_TEXREG_SS2] & ~SS2_LOD_BIAS_MASK); - - state[I915_TEXREG_SS3] = (i915->state.Tex[unit][I915_TEXREG_SS3] & - SS3_NORMALIZED_COORDS); - state[I915_TEXREG_SS3] |= (t->Setup[I915_TEXREG_SS3] & - ~(SS3_NORMALIZED_COORDS| - SS3_TEXTUREMAP_INDEX_MASK)); - - state[I915_TEXREG_SS3] |= (unit<<SS3_TEXTUREMAP_INDEX_SHIFT); - - state[I915_TEXREG_SS4] = t->Setup[I915_TEXREG_SS4]; - - - if (memcmp(state, i915->state.Tex[unit], sizeof(state)) != 0) { - I915_STATECHANGE( i915, I915_UPLOAD_TEX(unit) ); - memcpy(i915->state.Tex[unit], state, sizeof(state)); - } -} - - - -static GLboolean enable_tex_common( GLcontext *ctx, GLuint unit ) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - struct gl_texture_object *tObj = texUnit->_Current; - i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData; - - if (0) fprintf(stderr, "%s %d\n", __FUNCTION__, unit); - - if (!(i915->state.active & I915_UPLOAD_TEX(unit))) { - I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_TRUE); - } - - /* 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 (i915->intel.CurrentTexObj[unit] != &t->intel || - (t->intel.dirty & I915_UPLOAD_TEX(unit))) { - i915_import_tex_unit( i915, t, unit); - i915->tex_program.translated = 0; - } - - return GL_TRUE; -} - -static GLboolean enable_tex_rect( GLcontext *ctx, GLuint unit ) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - struct gl_texture_object *tObj = texUnit->_Current; - i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData; - GLuint ss3 = i915->state.Tex[unit][I915_TEXREG_SS3]; - - ss3 &= ~SS3_NORMALIZED_COORDS; - - if (ss3 != i915->state.Tex[unit][I915_TEXREG_SS3]) { - I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); - i915->state.Tex[unit][I915_TEXREG_SS3] = ss3; - } - - /* Upload teximages (not pipelined) - */ - if (t->intel.base.dirty_images[0]) { - i915SetTexImages( i915, tObj ); - if (!intelUploadTexImages( &i915->intel, &t->intel, 0 )) { - return GL_FALSE; - } - } - - return GL_TRUE; -} - - -static GLboolean enable_tex_2d( GLcontext *ctx, GLuint unit ) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - struct gl_texture_object *tObj = texUnit->_Current; - i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData; - GLuint ss3 = i915->state.Tex[unit][I915_TEXREG_SS3]; - - ss3 |= SS3_NORMALIZED_COORDS; - - if (ss3 != i915->state.Tex[unit][I915_TEXREG_SS3]) { - I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); - i915->state.Tex[unit][I915_TEXREG_SS3] = ss3; - } - - /* Upload teximages (not pipelined) - */ - if (t->intel.base.dirty_images[0]) { - i915SetTexImages( i915, tObj ); - if (!intelUploadTexImages( &i915->intel, &t->intel, 0 )) { - return GL_FALSE; - } - } - - return GL_TRUE; -} - -static GLboolean enable_tex_cube( GLcontext *ctx, GLuint unit ) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - struct gl_texture_object *tObj = texUnit->_Current; - i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData; - GLuint ss3 = i915->state.Tex[unit][I915_TEXREG_SS3]; - GLuint face; - - ss3 |= SS3_NORMALIZED_COORDS; - - if (ss3 != i915->state.Tex[unit][I915_TEXREG_SS3]) { - I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit)); - i915->state.Tex[unit][I915_TEXREG_SS3] = ss3; - } - - /* Upload teximages (not pipelined) - */ - if ( t->intel.base.dirty_images[0] || t->intel.base.dirty_images[1] || - t->intel.base.dirty_images[2] || t->intel.base.dirty_images[3] || - t->intel.base.dirty_images[4] || t->intel.base.dirty_images[5] ) { - i915SetTexImages( i915, tObj ); - } - - /* upload (per face) */ - for (face = 0; face < 6; face++) { - if (t->intel.base.dirty_images[face]) { - if (!intelUploadTexImages( &i915->intel, &t->intel, face )) { - return GL_FALSE; - } - } - } - - - return GL_TRUE; -} - -static GLboolean enable_tex_3d( GLcontext *ctx, GLuint unit ) -{ - struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; - i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData; - - /* 3D textures on I915 seem to get bogus border colors, hence this - * fallback: - */ - if (t->refs_border_color) - return GL_FALSE; - - return GL_TRUE; -} - - - - -static GLboolean disable_tex( GLcontext *ctx, GLuint unit ) -{ - i915ContextPtr i915 = I915_CONTEXT(ctx); - - if (i915->state.active & I915_UPLOAD_TEX(unit)) { - I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_FALSE); - } - - /* The old texture is no longer bound to this texture unit. - * Mark it as such. - */ - if ( i915->intel.CurrentTexObj[unit] != NULL ) { - i915->intel.CurrentTexObj[unit]->base.bound &= ~(1U << 0); - i915->intel.CurrentTexObj[unit] = NULL; - } - - return GL_TRUE; -} - -static GLboolean i915UpdateTexUnit( GLcontext *ctx, GLuint unit ) -{ - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - - if (texUnit->_ReallyEnabled && - INTEL_CONTEXT(ctx)->intelScreen->tex.size < 2048 * 1024) - return GL_FALSE; - - switch (texUnit->_ReallyEnabled) { - case TEXTURE_1D_BIT: - case TEXTURE_2D_BIT: - return (enable_tex_2d( ctx, unit ) && - enable_tex_common( ctx, unit )); - case TEXTURE_RECT_BIT: - return (enable_tex_rect( ctx, unit ) && - enable_tex_common( ctx, unit )); - case TEXTURE_CUBE_BIT: - return (enable_tex_cube( ctx, unit ) && - enable_tex_common( ctx, unit )); - case TEXTURE_3D_BIT: - return (enable_tex_2d( ctx, unit ) && - enable_tex_common( ctx, unit ) && - enable_tex_3d( ctx, unit)); - case 0: - return disable_tex( ctx, unit ); - default: - return GL_FALSE; - } -} - - -void i915UpdateTextureState( intelContextPtr intel ) -{ - GLcontext *ctx = &intel->ctx; - GLboolean ok = GL_TRUE; - GLuint i; - - for (i = 0 ; i < I915_TEX_UNITS && ok ; i++) { - ok = i915UpdateTexUnit( ctx, i ); - } - - FALLBACK( intel, I915_FALLBACK_TEXTURE, !ok ); -} - - - |