From 628b18b8cac5e691e7145deb1026e91d3cf03094 Mon Sep 17 00:00:00 2001 From: Alan Hourihane Date: Tue, 31 May 2005 18:10:03 +0000 Subject: [PATCH] Add Intel(R) 945G support (Keith Whitwell, Tungsten Graphics) --- src/mesa/drivers/dri/i915/i915_texstate.c | 203 +++++++++++++++++++++- src/mesa/drivers/dri/i915/intel_context.c | 4 +- src/mesa/drivers/dri/i915/intel_context.h | 1 + src/mesa/drivers/dri/i915/intel_screen.c | 1 + 4 files changed, 207 insertions(+), 2 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) | diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index f6012373534..c042111996c 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -73,7 +73,7 @@ int prevLockLine; * Mesa's Driver Functions ***************************************/ -#define DRIVER_DATE "20041217" +#define DRIVER_DATE "20050225" const GLubyte *intelGetString( GLcontext *ctx, GLenum name ) { @@ -99,6 +99,8 @@ const GLubyte *intelGetString( GLcontext *ctx, GLenum name ) chipset = "Intel(R) 915G"; break; case PCI_CHIP_I915_GM: chipset = "Intel(R) 915GM"; break; + case PCI_CHIP_I945_G: + chipset = "Intel(R) 945G"; break; default: chipset = "Unknown Intel Chipset"; break; } diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h index 442c5a759a6..da1ef701bf5 100644 --- a/src/mesa/drivers/dri/i915/intel_context.h +++ b/src/mesa/drivers/dri/i915/intel_context.h @@ -412,6 +412,7 @@ extern int INTEL_DEBUG; #define PCI_CHIP_I865_G 0x2572 #define PCI_CHIP_I915_G 0x2582 #define PCI_CHIP_I915_GM 0x2592 +#define PCI_CHIP_I945_G 0x2772 /* ================================================================ diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c index a73137f7581..d41cda1be77 100644 --- a/src/mesa/drivers/dri/i915/intel_screen.c +++ b/src/mesa/drivers/dri/i915/intel_screen.c @@ -349,6 +349,7 @@ static GLboolean intelCreateContext( const __GLcontextModes *mesaVis, case PCI_CHIP_I915_G: case PCI_CHIP_I915_GM: + case PCI_CHIP_I945_G: return i915CreateContext( mesaVis, driContextPriv, sharedContextPrivate ); -- 2.30.2