diff options
author | Alan Hourihane <[email protected]> | 2005-05-31 18:10:03 +0000 |
---|---|---|
committer | Alan Hourihane <[email protected]> | 2005-05-31 18:10:03 +0000 |
commit | 628b18b8cac5e691e7145deb1026e91d3cf03094 (patch) | |
tree | 754df773bc4d84ea876c1787d64c5df934a6aff4 /src/mesa/drivers/dri/i915/i915_texstate.c | |
parent | 4ec6eceea93e613b5078dc388925cf866ed8c88b (diff) |
Add Intel(R) 945G support (Keith Whitwell, Tungsten Graphics)
Diffstat (limited to 'src/mesa/drivers/dri/i915/i915_texstate.c')
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_texstate.c | 203 |
1 files changed, 202 insertions, 1 deletions
diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c index 6dede76b2e7..7a274bb6929 100644 --- a/src/mesa/drivers/dri/i915/i915_texstate.c +++ b/src/mesa/drivers/dri/i915/i915_texstate.c @@ -191,6 +191,203 @@ static void i915LayoutTextureImages( i915ContextPtr i915, } +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->Format; + + 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->Format; + + + + 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: + 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->Format; + + 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 ) @@ -298,7 +495,11 @@ static void i915SetTexImages( i915ContextPtr i915, abort(); } - i915LayoutTextureImages( i915, tObj ); + + if (i915->intel.intelScreen->deviceID == PCI_CHIP_I945_G) + i945LayoutTextureImages( i915, tObj ); + else + i915LayoutTextureImages( i915, tObj ); t->Setup[I915_TEXREG_MS3] = (((tObj->Image[0][t->intel.base.firstLevel]->Height - 1) << MS3_HEIGHT_SHIFT) | |