diff options
author | keithw <keithw> | 2003-06-05 12:41:43 +0000 |
---|---|---|
committer | keithw <keithw> | 2003-06-05 12:41:43 +0000 |
commit | 1ba00273ca63c725a48b4667fb5ee3f89cf5d891 (patch) | |
tree | 08ec74a9440e3e1cf16bf89f0087d887e230359a | |
parent | 6ae88aee5f088f700880e2c93a733f5c234a07c3 (diff) |
Get agp texturing basically working
-rw-r--r-- | xc/lib/GL/mesa/src/drv/i830/i830_context.c | 1 | ||||
-rw-r--r-- | xc/lib/GL/mesa/src/drv/i830/i830_ioctl.c | 51 | ||||
-rw-r--r-- | xc/lib/GL/mesa/src/drv/i830/i830_ioctl.h | 13 | ||||
-rw-r--r-- | xc/lib/GL/mesa/src/drv/i830/i830_pixel.c | 45 | ||||
-rw-r--r-- | xc/lib/GL/mesa/src/drv/i830/i830_tex.c | 125 | ||||
-rw-r--r-- | xc/lib/GL/mesa/src/drv/i830/i830_texmem.c | 163 | ||||
-rw-r--r-- | xc/lib/GL/mesa/src/drv/i830/i830_texstate.c | 20 |
7 files changed, 300 insertions, 118 deletions
diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_context.c b/xc/lib/GL/mesa/src/drv/i830/i830_context.c index 51a2e7517..9d7d35c1f 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_context.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_context.c @@ -135,6 +135,7 @@ static void i830BufferSize(GLframebuffer *buffer, */ static const char * const card_extensions[] = { + "GL_APPLE_client_storage", "GL_ARB_multisample", "GL_ARB_multitexture", "GL_ARB_texture_border_clamp", diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.c b/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.c index 00b70d794..d0f666a9a 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.c @@ -841,6 +841,55 @@ static void i830DDFinish( GLcontext *ctx ) i830DmaFinish( imesa ); } +/* Blitter ioctl + */ + +void i830EmitBlitLocked( i830ContextPtr imesa, + GLuint cpp, + GLshort src_pitch, + GLuint src_offset, + GLshort dst_pitch, + GLuint dst_offset, + GLshort srcx, GLshort srcy, + GLshort dstx, GLshort dsty, + GLshort w, GLshort h ) +{ + drmI830CopyBlit blit; + + if (I830_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "%s cpp %d src %d/0x%x dst %d/0x%x %d,%d:%d,%d:%dx%d\n", + __FUNCTION__, + cpp, + src_pitch, src_offset, + dst_pitch, dst_offset, + srcx, srcy, + dstx, dsty, + w, h); + + blit.cpp = cpp; + blit.src_pitch = src_pitch; + blit.src_offset = src_offset; + blit.dst_pitch = dst_pitch; + blit.dst_offset = dst_offset; + blit.src_x = srcx; + blit.src_y = srcy; + blit.dst_x = dstx; + blit.dst_y = dsty; + blit.w = w; + blit.h = h; + + if (drmCommandWrite(imesa->driFd, DRM_I830_COPY_BLIT, &blit, sizeof(blit))) { + fprintf(stderr, "DRM_I830_BLIT: %d\n", -errno); + UNLOCK_HARDWARE(imesa); + exit(1); + } +} + +void i830WaitForIdleLocked( i830ContextPtr imesa ) +{ + drmCommandNone(imesa->driFd, DRM_I830_FLUSH); +} + /* This version of AllocateMemoryNV allocates only agp memory, and * only does so after the point at which the driver has been @@ -887,6 +936,8 @@ void *i830AllocateMemoryNV(GLsizei size, GLfloat readfreq, return NULL; } + fprintf(stderr, "%s: allocated %d bytes\n", __FUNCTION__, size); + { char *region_start = (char *)imesa->i830Screen->tex.map; return (void *)(region_start + region_offset); diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.h b/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.h index aae8c6a2a..f329c066d 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.h +++ b/xc/lib/GL/mesa/src/drv/i830/i830_ioctl.h @@ -57,6 +57,19 @@ extern void i830DDInitIoctlFuncs( GLcontext *ctx ); extern void i830CopyBuffer( const __DRIdrawablePrivate *dpriv ); extern void i830PageFlip( const __DRIdrawablePrivate *dpriv ); +extern void i830EmitBlitLocked( i830ContextPtr imesa, + GLuint cpp, + GLshort src_pitch, + GLuint src_offset, + GLshort dst_pitch, + GLuint dst_offset, + GLshort srcx, GLshort srcy, + GLshort dstx, GLshort dsty, + GLshort w, GLshort h ); + +extern void i830WaitForIdleLocked( i830ContextPtr imesa ); + + extern void *i830AllocateMemoryNV( GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority ); extern void i830FreeMemoryNV( GLvoid *pointer ); diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_pixel.c b/xc/lib/GL/mesa/src/drv/i830/i830_pixel.c index 8ea0358f4..efa81818a 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_pixel.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_pixel.c @@ -46,51 +46,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "i830_pixel.h" -static void i830EmitBlitLocked( i830ContextPtr imesa, - GLuint cpp, - GLshort src_pitch, - GLuint src_offset, - GLshort dst_pitch, - GLuint dst_offset, - GLshort srcx, GLshort srcy, - GLshort dstx, GLshort dsty, - GLshort w, GLshort h ) -{ - drmI830CopyBlit blit; - - if (I830_DEBUG & DEBUG_PIXEL) - fprintf(stderr, "%s cpp %d src %d/0x%x dst %d/0x%x %d,%d:%d,%d:%dx%d\n", - __FUNCTION__, - cpp, - src_pitch, src_offset, - dst_pitch, dst_offset, - srcx, srcy, - dstx, dsty, - w, h); - - blit.cpp = cpp; - blit.src_pitch = src_pitch; - blit.src_offset = src_offset; - blit.dst_pitch = dst_pitch; - blit.dst_offset = dst_offset; - blit.src_x = srcx; - blit.src_y = srcy; - blit.dst_x = dstx; - blit.dst_y = dsty; - blit.w = w; - blit.h = h; - - if (drmCommandWrite(imesa->driFd, DRM_I830_COPY_BLIT, &blit, sizeof(blit))) { - fprintf(stderr, "DRM_I830_BLIT: %d\n", -errno); - UNLOCK_HARDWARE(imesa); - exit(1); - } -} - -static void i830WaitForIdleLocked( i830ContextPtr imesa ) -{ - drmCommandNone(imesa->driFd, DRM_I830_FLUSH); -} static GLboolean diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_tex.c b/xc/lib/GL/mesa/src/drv/i830/i830_tex.c index 77def05fd..77ac62243 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_tex.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_tex.c @@ -364,7 +364,110 @@ static void i830TexEnv( GLcontext *ctx, GLenum target, default: break; } -} +} + + +static GLboolean +i830ValidateClientStorage( GLcontext *ctx, GLenum target, + GLint internalFormat, + GLint srcWidth, GLint srcHeight, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) + +{ + i830ContextPtr imesa = I830_CONTEXT(ctx); + int texelBytes; + + if (0) + fprintf(stderr, "intformat %s format %s type %s\n", + _mesa_lookup_enum_by_nr( internalFormat ), + _mesa_lookup_enum_by_nr( format ), + _mesa_lookup_enum_by_nr( type )); + + if (!ctx->Unpack.ClientStorage) + return 0; + + if (ctx->_ImageTransferState || + texImage->IsCompressed || + texObj->GenerateMipmap) + return 0; + + + /* This list is incomplete, may be different on ppc??? + */ + switch ( internalFormat ) { + case GL_RGBA: + if ( format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV ) { + texImage->TexFormat = &_mesa_texformat_argb8888; + texelBytes = 4; + } + else + return 0; + break; + + case GL_YCBCR_MESA: + if ( format == GL_YCBCR_MESA && + type == GL_UNSIGNED_SHORT_8_8_REV_APPLE ) { + texImage->TexFormat = &_mesa_texformat_ycbcr_rev; + texelBytes = 2; + } + else if ( format == GL_YCBCR_MESA && + (type == GL_UNSIGNED_SHORT_8_8_APPLE || + type == GL_UNSIGNED_BYTE)) { + texImage->TexFormat = &_mesa_texformat_ycbcr; + texelBytes = 2; + } + else + return 0; + break; + + + default: + return 0; + } + + /* Could deal with these packing issues, but currently don't: + */ + if (packing->SkipPixels || + packing->SkipRows || + packing->SwapBytes || + packing->LsbFirst) { + return 0; + } + + { + GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth, + format, type); + + + if (0) + fprintf(stderr, "%s: srcRowStride %d/%x\n", + __FUNCTION__, srcRowStride, srcRowStride); + + /* Could check this later in upload, pitch restrictions could be + * relaxed, but would need to store the image pitch somewhere, + * as packing details might change before image is uploaded: + */ + if (!i830IsAgpMemory( imesa, pixels, srcHeight * srcRowStride ) || + (srcRowStride & 63)) + return 0; + + + /* Have validated that _mesa_transfer_teximage would be a straight + * memcpy at this point. NOTE: future calls to TexSubImage will + * overwrite the client data. This is explicitly mentioned in the + * extension spec. + */ + texImage->Data = (void *)pixels; + texImage->IsClientData = GL_TRUE; + texImage->RowStride = srcRowStride / texelBytes; + return 1; + } +} + + static void i830TexImage2D( GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, @@ -387,9 +490,23 @@ static void i830TexImage2D( GLcontext *ctx, GLenum target, GLint level, } } - _mesa_store_teximage2d( ctx, target, level, internalFormat, - width, height, border, format, type, - pixels, packing, texObj, texImage ); + texImage->IsClientData = GL_FALSE; + + if (i830ValidateClientStorage( ctx, target, + internalFormat, + width, height, + format, type, pixels, + packing, texObj, texImage)) { + if (I830_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, "%s: Using client storage\n", __FUNCTION__); + } + else { + _mesa_store_teximage2d( ctx, target, level, internalFormat, + width, height, border, format, type, + pixels, packing, texObj, texImage ); + + t->dirty_images[0] |= (1 << level); + } } static void i830TexSubImage2D( GLcontext *ctx, diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_texmem.c b/xc/lib/GL/mesa/src/drv/i830/i830_texmem.c index 389462102..8cb633115 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_texmem.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_texmem.c @@ -96,7 +96,8 @@ return (to); /* Upload an image from mesa's internal copy. */ -static void i830UploadTexLevel( i830TextureObjectPtr t, int hwlevel ) +static void i830UploadTexLevel( i830ContextPtr imesa, + i830TextureObjectPtr t, int hwlevel ) { int level = hwlevel + t->firstLevel; const struct gl_texture_image *image = t->image[0][hwlevel].image; @@ -107,14 +108,37 @@ static void i830UploadTexLevel( i830TextureObjectPtr t, int hwlevel ) if (0) fprintf(stderr, "Uploading level : %d\n", level); - if (image->Width * image->TexFormat->TexelBytes == t->Pitch) { - GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[0][hwlevel].offset); - GLubyte *src = (GLubyte *)image->Data; - - memcpy( dst, src, t->Pitch * image->Height ); + + if (image->IsClientData) { + fprintf(stderr, "Blit uploading level : %d\n", level); + + /* Do it with a blit. + */ + i830EmitBlitLocked( imesa, + image->TexFormat->TexelBytes, + image->RowStride, /* ? */ + i830GetAGPOffset( image->Data ), + t->Pitch / image->TexFormat->TexelBytes, + i830GetAGPOffset( t->BufAddr + + t->image[0][hwlevel].offset ), + 0, 0, + 0, 0, + image->Width, + image->Height); } - else switch (image->TexFormat->TexelBytes) { - case 1: + else if (image->Width * image->TexFormat->TexelBytes == t->Pitch) { + GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[0][hwlevel].offset); + GLubyte *src = (GLubyte *)image->Data; + + fprintf(stderr, "memcpy uploading level : %d\n", level); + + memcpy( dst, src, t->Pitch * image->Height ); + } + else { + fprintf(stderr, "spanline uploading level : %d\n", level); + + switch (image->TexFormat->TexelBytes) { + case 1: { GLubyte *dst = (GLubyte *)(t->BufAddr + t->image[0][hwlevel].offset); GLubyte *src = (GLubyte *)image->Data; @@ -126,7 +150,7 @@ static void i830UploadTexLevel( i830TextureObjectPtr t, int hwlevel ) } break; - case 2: + case 2: { GLushort *dst = (GLushort *)(t->BufAddr + t->image[0][hwlevel].offset); GLushort *src = (GLushort *)image->Data; @@ -138,7 +162,7 @@ static void i830UploadTexLevel( i830TextureObjectPtr t, int hwlevel ) } break; - case 4: + case 4: { GLuint *dst = (GLuint *)(t->BufAddr + t->image[0][hwlevel].offset); GLuint *src = (GLuint *)image->Data; @@ -150,12 +174,27 @@ static void i830UploadTexLevel( i830TextureObjectPtr t, int hwlevel ) } break; - default: - fprintf(stderr, "%s: Not supported texel size %d\n", - __FUNCTION__, image->TexFormat->TexelBytes); + default: + fprintf(stderr, "%s: Not supported texel size %d\n", + __FUNCTION__, image->TexFormat->TexelBytes); + } } } +static void upload_dirty( i830ContextPtr imesa, i830TextureObjectPtr t ) +{ + if (t == imesa->CurrentTexObj[0]) + imesa->dirty |= I830_UPLOAD_TEX0; + + if (t == imesa->CurrentTexObj[1]) + imesa->dirty |= I830_UPLOAD_TEX1; + + if (t == imesa->CurrentTexObj[2]) + I830_STATECHANGE(imesa, I830_UPLOAD_TEX2); + + if (t == imesa->CurrentTexObj[3]) + I830_STATECHANGE(imesa, I830_UPLOAD_TEX3); +} /* This is called with the lock held. May have to eject our own and/or * other client's texture objects to make room for the upload. @@ -164,58 +203,64 @@ static void i830UploadTexLevel( i830TextureObjectPtr t, int hwlevel ) int i830UploadTexImagesLocked( i830ContextPtr imesa, i830TextureObjectPtr t ) { int ofs; - - if ( t->base.memBlock == NULL ) { - int heap; - - heap = driAllocateTexture( imesa->texture_heaps, imesa->nr_heaps, - (driTextureObject *) t ); - if ( heap == -1 ) { - return -1; - } - - /* Set the base offset of the texture image */ - ofs = t->base.memBlock->ofs; - t->BufAddr = imesa->i830Screen->tex.map + ofs; - t->Setup[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | - (imesa->i830Screen->textureOffset + ofs)); - - if (t == imesa->CurrentTexObj[0]) - imesa->dirty |= I830_UPLOAD_TEX0; - - if (t == imesa->CurrentTexObj[1]) - imesa->dirty |= I830_UPLOAD_TEX1; -#if 0 - if (t == imesa->CurrentTexObj[2]) - I830_STATECHANGE(imesa, I830_UPLOAD_TEX2); - - if (t == imesa->CurrentTexObj[3]) - I830_STATECHANGE(imesa, I830_UPLOAD_TEX3); -#endif + const int numLevels = t->lastLevel - t->firstLevel + 1; + const struct gl_texture_image *firstImage = t->image[0][t->firstLevel].image; + int pitch = firstImage->RowStride * firstImage->TexFormat->TexelBytes; + + /* Can we texture out of the existing client data? */ + if ( numLevels == 1 && + firstImage->IsClientData && + (pitch & 3) == 0) { + + fprintf(stderr, "AGP texturing from client memory\n"); + + ofs = i830AgpOffsetFromVirtual( imesa, firstImage->Data ); + t->Setup[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | ofs); + t->Setup[I830_TEXREG_TM0S2] = (((pitch / 4) - 1) << TM0S2_PITCH_SHIFT); + t->BufAddr = 0; + upload_dirty( imesa, t ); + return GL_TRUE; } + else { + fprintf(stderr, "Uploading client data to agp\n"); + + if ( t->base.memBlock == NULL ) { + int heap; + + heap = driAllocateTexture( imesa->texture_heaps, imesa->nr_heaps, + (driTextureObject *) t ); + if ( heap == -1 ) + return GL_FALSE; + + /* Set the base offset of the texture image */ + ofs = t->base.memBlock->ofs; + t->BufAddr = imesa->i830Screen->tex.map + ofs; + t->Setup[I830_TEXREG_TM0S0] = (TM0S0_USE_FENCE | + (imesa->i830Screen->textureOffset + ofs)); + upload_dirty( imesa, t ); + } - /* Let the world know we've used this memory recently. - */ - driUpdateTextureLRU( (driTextureObject *) t ); - + /* Let the world know we've used this memory recently. + */ + driUpdateTextureLRU( (driTextureObject *) t ); - if (imesa->dirtyAge >= GET_DISPATCH_AGE(imesa)) - i830WaitAgeLocked( imesa, imesa->dirtyAge ); + if (imesa->dirtyAge >= GET_DISPATCH_AGE(imesa)) + i830WaitAgeLocked( imesa, imesa->dirtyAge ); - /* Upload any images that are new */ - if (t->base.dirty_images[0]) { - int i; - const int numLevels = t->lastLevel - t->firstLevel + 1; + /* Upload any images that are new */ + if (t->base.dirty_images[0]) { + int i; - for (i = 0 ; i < numLevels ; i++) { - if ( (t->base.dirty_images[0] & (1 << (i+t->firstLevel))) != 0 ) { - i830UploadTexLevel( t, i ); - } + for (i = 0 ; i < numLevels ; i++) { + if ( (t->base.dirty_images[0] & (1 << (i+t->firstLevel))) != 0 ) { + i830UploadTexLevel( imesa, t, i ); + } + } + t->base.dirty_images[0] = 0; + imesa->sarea->perf_boxes |= I830_BOX_TEXTURE_LOAD; } - t->base.dirty_images[0] = 0; - imesa->sarea->perf_boxes |= I830_BOX_TEXTURE_LOAD; + + return GL_TRUE; } - - return 0; } diff --git a/xc/lib/GL/mesa/src/drv/i830/i830_texstate.c b/xc/lib/GL/mesa/src/drv/i830/i830_texstate.c index 236cbc316..a7ccf8487 100644 --- a/xc/lib/GL/mesa/src/drv/i830/i830_texstate.c +++ b/xc/lib/GL/mesa/src/drv/i830/i830_texstate.c @@ -56,13 +56,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define I830_TEX_UNIT_ENABLED(unit) (1<<unit) -static void i830SetTexImages( i830ContextPtr imesa, - struct gl_texture_object *tObj ) +static GLboolean i830SetTexImages( i830ContextPtr imesa, + struct gl_texture_object *tObj ) { GLuint total_height, pitch, i, textureFormat; i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData; const struct gl_texture_image *baseImage = tObj->Image[tObj->BaseLevel]; - GLint firstLevel, lastLevel, numLevels; + GLint firstLevel, lastLevel, numLevels, ret; switch( baseImage->TexFormat->MesaFormat ) { case MESA_FORMAT_L8: @@ -115,7 +115,7 @@ static void i830SetTexImages( i830ContextPtr imesa, default: fprintf(stderr, "%s: bad image format\n", __FUNCTION__); free( t ); - return; + return GL_FALSE; } /* Compute which mipmap levels we really want to send to the hardware. @@ -140,7 +140,7 @@ static void i830SetTexImages( i830ContextPtr imesa, default: fprintf(stderr, "%s: bad target %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(tObj->Target)); - return; + return GL_FALSE; } @@ -190,15 +190,17 @@ static void i830SetTexImages( i830ContextPtr imesa, ((tObj->Image[firstLevel]->Width - 1) << TM0S1_WIDTH_SHIFT) | textureFormat); t->Setup[I830_TEXREG_TM0S2] = - ((((pitch / 4) - 1) << TM0S2_PITCH_SHIFT)); + (((pitch / 4) - 1) << TM0S2_PITCH_SHIFT); t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAX_MIP_MASK; t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_MIP_MASK; t->Setup[I830_TEXREG_TM0S3] |= ((numLevels - 1)*4) << TM0S3_MIN_MIP_SHIFT; t->dirty = I830_UPLOAD_TEX0 | I830_UPLOAD_TEX1; LOCK_HARDWARE( imesa ); - i830UploadTexImagesLocked( imesa, t ); + ret = i830UploadTexImagesLocked( imesa, t ); UNLOCK_HARDWARE( imesa ); + + return ret; } /* ================================================================ @@ -1369,10 +1371,8 @@ static GLboolean enable_tex_common( GLcontext *ctx, GLuint unit ) /* Upload teximages (not pipelined) */ if (t->base.dirty_images[0]) { - i830SetTexImages( imesa, tObj ); - if (!t->base.memBlock) { + if (!i830SetTexImages( imesa, tObj )) return GL_FALSE; - } } /* Update state if this is a different texture object to last |