static void r300TexSubImage2D(GLcontext * ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { driTextureObject *t = (driTextureObject *) texObj->DriverData; GLuint face; /* which cube face or ordinary 2D image */ switch (target) { case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; ASSERT(face < 6); break; default: face = 0; } assert(t); /* this _should_ be true */ if (t) { driSwapOutTextureObject(t); } else { t = (driTextureObject *) r300AllocTexObj(texObj); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); return; } } _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, height, format, type, pixels, packing, texObj, texImage); t->dirty_images[face] |= (1 << level); }
static void radeonTexImage2D( GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint border, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { driTextureObject * t = (driTextureObject *) texObj->DriverData; GLuint face; /* which cube face or ordinary 2D image */ switch (target) { case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; ASSERT(face < 6); break; default: face = 0; } if ( t != NULL ) { driSwapOutTextureObject( t ); } else { t = (driTextureObject *) radeonAllocTexObj( texObj ); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); return; } } /* Note, this will call ChooseTextureFormat */ _mesa_store_teximage2d(ctx, target, level, internalFormat, width, height, border, format, type, pixels, &ctx->Unpack, texObj, texImage); t->dirty_images[face] |= (1 << level); }
static void i830TexParameter( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLenum pname, const GLfloat *params ) { i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData; if (!t) return; switch (pname) { case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MAG_FILTER: case GL_TEXTURE_MAX_ANISOTROPY_EXT: i830SetTexFilter( t, tObj->MinFilter, tObj->MagFilter, tObj->MaxAnisotropy); break; case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_T: i830SetTexWrapping( t, tObj->WrapS, tObj->WrapT ); break; case GL_TEXTURE_BORDER_COLOR: i830SetTexBorderColor( t, tObj->_BorderChan ); break; case GL_TEXTURE_BASE_LEVEL: case GL_TEXTURE_MAX_LEVEL: case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MAX_LOD: /* The i830 and its successors can do a lot of this without * reloading the textures. A project for someone? */ intelFlush( ctx ); driSwapOutTextureObject( (driTextureObject *) t ); break; default: return; } t->intel.dirty = I830_UPLOAD_TEX_ALL; }
static void i915TexParameter( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLenum pname, const GLfloat *params ) { i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData; switch (pname) { case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MAG_FILTER: case GL_TEXTURE_MAX_ANISOTROPY_EXT: case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_T: case GL_TEXTURE_WRAP_R: case GL_TEXTURE_BORDER_COLOR: t->intel.dirty = I915_UPLOAD_TEX_ALL; break; case GL_TEXTURE_COMPARE_MODE: t->intel.dirty = I915_UPLOAD_TEX_ALL; break; case GL_TEXTURE_COMPARE_FUNC: t->intel.dirty = I915_UPLOAD_TEX_ALL; break; case GL_TEXTURE_BASE_LEVEL: case GL_TEXTURE_MAX_LEVEL: case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MAX_LOD: /* The i915 and its successors can do a lot of this without * reloading the textures. A project for someone? */ intelFlush( ctx ); driSwapOutTextureObject( (driTextureObject *) t ); t->intel.dirty = I915_UPLOAD_TEX_ALL; break; default: return; } }
static void i810TexSubImage2D( GLcontext *ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { driTextureObject *t = (driTextureObject *)texObj->DriverData; if (t) { I810_FIREVERTICES( I810_CONTEXT(ctx) ); driSwapOutTextureObject( t ); } _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, height, format, type, pixels, packing, texObj, texImage); }
static void i810TexParameter( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLenum pname, const GLfloat *params ) { i810ContextPtr imesa = I810_CONTEXT(ctx); i810TextureObjectPtr t = (i810TextureObjectPtr) tObj->DriverData; if (!t) return; if ( target != GL_TEXTURE_2D ) return; /* Can't do the update now as we don't know whether to flush * vertices or not. Setting imesa->new_state means that * i810UpdateTextureState() will be called before any triangles are * rendered. If a statechange has occurred, it will be detected at * that point, and buffered vertices flushed. */ switch (pname) { case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MAG_FILTER: { GLfloat bias = ctx->Texture.Unit[ctx->Texture.CurrentUnit].LodBias; i810SetTexFilter( imesa, t, tObj->MinFilter, tObj->MagFilter, bias ); } break; case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_T: i810SetTexWrapping( t, tObj->WrapS, tObj->WrapT ); break; case GL_TEXTURE_BORDER_COLOR: i810SetTexBorderColor( t, tObj->_BorderChan ); break; case GL_TEXTURE_BASE_LEVEL: case GL_TEXTURE_MAX_LEVEL: case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MAX_LOD: /* This isn't the most efficient solution but there doesn't appear to * be a nice alternative for Radeon. Since there's no LOD clamping, * we just have to rely on loading the right subset of mipmap levels * to simulate a clamped LOD. */ I810_FIREVERTICES( I810_CONTEXT(ctx) ); driSwapOutTextureObject( (driTextureObject *) t ); break; default: return; } if (t == imesa->CurrentTexObj[0]) { I810_STATECHANGE( imesa, I810_UPLOAD_TEX0 ); } if (t == imesa->CurrentTexObj[1]) { I810_STATECHANGE( imesa, I810_UPLOAD_TEX1 ); } }
static void r200UploadRectSubImage( r200ContextPtr rmesa, r200TexObjPtr t, struct gl_texture_image *texImage, GLint x, GLint y, GLint width, GLint height ) { const struct gl_texture_format *texFormat = texImage->TexFormat; int blit_format, dstPitch, done; switch ( texFormat->TexelBytes ) { case 1: blit_format = R200_CP_COLOR_FORMAT_CI8; break; case 2: blit_format = R200_CP_COLOR_FORMAT_RGB565; break; case 4: blit_format = R200_CP_COLOR_FORMAT_ARGB8888; break; default: return; } t->image[0][0].data = texImage->Data; /* Currently don't need to cope with small pitches. */ width = texImage->Width; height = texImage->Height; dstPitch = t->pp_txpitch + 32; if (rmesa->prefer_gart_client_texturing && texImage->IsClientData) { /* In this case, could also use GART texturing. This is * currently disabled, but has been tested & works. */ if ( !t->image_override ) t->pp_txoffset = r200GartOffsetFromVirtual( rmesa, texImage->Data ); t->pp_txpitch = texImage->RowStride * texFormat->TexelBytes - 32; if (R200_DEBUG & DEBUG_TEXTURE) fprintf(stderr, "Using GART texturing for rectangular client texture\n"); /* Release FB memory allocated for this image: */ /* FIXME This may not be correct as driSwapOutTextureObject sets * FIXME dirty_images. It may be fine, though. */ if ( t->base.memBlock ) { driSwapOutTextureObject( (driTextureObject *) t ); } } else if (texImage->IsClientData) { /* Data already in GART memory, with usable pitch. */ GLuint srcPitch; srcPitch = texImage->RowStride * texFormat->TexelBytes; r200EmitBlit( rmesa, blit_format, srcPitch, r200GartOffsetFromVirtual( rmesa, texImage->Data ), dstPitch, t->bufAddr, 0, 0, 0, 0, width, height ); } else { /* Data not in GART memory, or bad pitch. */ for (done = 0; done < height ; ) { struct r200_dma_region region; int lines = MIN2( height - done, RADEON_BUFFER_SIZE / dstPitch ); int src_pitch; char *tex; src_pitch = texImage->RowStride * texFormat->TexelBytes; tex = (char *)texImage->Data + done * src_pitch; memset(®ion, 0, sizeof(region)); r200AllocDmaRegion( rmesa, ®ion, lines * dstPitch, 1024 ); /* Copy texdata to dma: */ if (0) fprintf(stderr, "%s: src_pitch %d dst_pitch %d\n", __FUNCTION__, src_pitch, dstPitch); if (src_pitch == dstPitch) { memcpy( region.address + region.start, tex, lines * src_pitch ); } else { char *buf = region.address + region.start; int i; for (i = 0 ; i < lines ; i++) { memcpy( buf, tex, src_pitch ); buf += dstPitch; tex += src_pitch; } } r200EmitWait( rmesa, RADEON_WAIT_3D ); /* Blit to framebuffer */ r200EmitBlit( rmesa, blit_format, dstPitch, GET_START( ®ion ), dstPitch | (t->tile_bits >> 16), t->bufAddr, 0, 0, 0, done, width, lines ); r200EmitWait( rmesa, RADEON_WAIT_2D ); r200ReleaseDmaRegion( rmesa, ®ion, __FUNCTION__ ); done += lines; } } }
static void r300CompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint border, GLsizei imageSize, const GLvoid *data, struct gl_texture_object *texObj, struct gl_texture_image *texImage ) { driTextureObject * t = (driTextureObject *) texObj->DriverData; GLuint face; /* which cube face or ordinary 2D image */ switch (target) { case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; ASSERT(face < 6); break; default: face = 0; } if ( t != NULL ) { driSwapOutTextureObject( t ); } else { t = (driTextureObject *) r300AllocTexObj( texObj ); if (!t) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); return; } } texImage->IsClientData = GL_FALSE; /* can't call this, different parameters. Would never evaluate to true anyway currently if (r300ValidateClientStorage( ctx, target, internalFormat, width, height, format, type, pixels, packing, texObj, texImage)) { if (RADEON_DEBUG & DEBUG_TEXTURE) fprintf(stderr, "%s: Using client storage\n", __FUNCTION__); } else */{ if (RADEON_DEBUG & DEBUG_TEXTURE) fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__); /* Normal path: copy (to cached memory) and eventually upload * via another copy to GART memory and then a blit... Could * eliminate one copy by going straight to (permanent) GART. * * Note, this will call r300ChooseTextureFormat. */ _mesa_store_compressed_teximage2d(ctx, target, level, internalFormat, width, height, border, imageSize, data, texObj, texImage); t->dirty_images[face] |= (1 << level); } }