intel_tex.c revision 101abee6c4fc2c9284ff2ba6f9f9138327d6963d
1#include "swrast/swrast.h" 2#include "texobj.h" 3#include "mipmap.h" 4#include "intel_context.h" 5#include "intel_mipmap_tree.h" 6#include "intel_tex.h" 7 8#define FILE_DEBUG_FLAG DEBUG_TEXTURE 9 10static GLboolean 11intelIsTextureResident(GLcontext * ctx, struct gl_texture_object *texObj) 12{ 13#if 0 14 struct intel_context *intel = intel_context(ctx); 15 struct intel_texture_object *intelObj = intel_texture_object(texObj); 16 17 return 18 intelObj->mt && 19 intelObj->mt->region && 20 intel_is_region_resident(intel, intelObj->mt->region); 21#endif 22 return 1; 23} 24 25 26 27static struct gl_texture_image * 28intelNewTextureImage(GLcontext * ctx) 29{ 30 DBG("%s\n", __FUNCTION__); 31 (void) ctx; 32 return (struct gl_texture_image *) CALLOC_STRUCT(intel_texture_image); 33} 34 35 36static struct gl_texture_object * 37intelNewTextureObject(GLcontext * ctx, GLuint name, GLenum target) 38{ 39 struct intel_texture_object *obj = CALLOC_STRUCT(intel_texture_object); 40 41 DBG("%s\n", __FUNCTION__); 42 _mesa_initialize_texture_object(&obj->base, name, target); 43 44 return &obj->base; 45} 46 47static void 48intelDeleteTextureObject(GLcontext *ctx, 49 struct gl_texture_object *texObj) 50{ 51 struct intel_context *intel = intel_context(ctx); 52 struct intel_texture_object *intelObj = intel_texture_object(texObj); 53 54 if (intelObj->mt) 55 intel_miptree_release(intel, &intelObj->mt); 56 57 _mesa_delete_texture_object(ctx, texObj); 58} 59 60 61static void 62intelFreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage) 63{ 64 struct intel_context *intel = intel_context(ctx); 65 struct intel_texture_image *intelImage = intel_texture_image(texImage); 66 67 DBG("%s\n", __FUNCTION__); 68 69 if (intelImage->mt) { 70 intel_miptree_release(intel, &intelImage->mt); 71 } 72 73 if (texImage->Data) { 74 free(texImage->Data); 75 texImage->Data = NULL; 76 } 77} 78 79 80/* The system memcpy (at least on ubuntu 5.10) has problems copying 81 * to agp (writecombined) memory from a source which isn't 64-byte 82 * aligned - there is a 4x performance falloff. 83 * 84 * The x86 __memcpy is immune to this but is slightly slower 85 * (10%-ish) than the system memcpy. 86 * 87 * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but 88 * isn't much faster than x86_memcpy for agp copies. 89 * 90 * TODO: switch dynamically. 91 */ 92static void * 93do_memcpy(void *dest, const void *src, size_t n) 94{ 95 if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) { 96 return __memcpy(dest, src, n); 97 } 98 else 99 return memcpy(dest, src, n); 100} 101 102 103#if DO_DEBUG 104 105#ifndef __x86_64__ 106static unsigned 107fastrdtsc(void) 108{ 109 unsigned eax; 110 __asm__ volatile ("\t" 111 "pushl %%ebx\n\t" 112 "cpuid\n\t" ".byte 0x0f, 0x31\n\t" 113 "popl %%ebx\n":"=a" (eax) 114 :"0"(0) 115 :"ecx", "edx", "cc"); 116 117 return eax; 118} 119#else 120static unsigned 121fastrdtsc(void) 122{ 123 unsigned eax; 124 __asm__ volatile ("\t" "cpuid\n\t" ".byte 0x0f, 0x31\n\t":"=a" (eax) 125 :"0"(0) 126 :"ecx", "edx", "ebx", "cc"); 127 128 return eax; 129} 130#endif 131 132static unsigned 133time_diff(unsigned t, unsigned t2) 134{ 135 return ((t < t2) ? t2 - t : 0xFFFFFFFFU - (t - t2 - 1)); 136} 137 138 139static void * 140timed_memcpy(void *dest, const void *src, size_t n) 141{ 142 void *ret; 143 unsigned t1, t2; 144 double rate; 145 146 if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) 147 _mesa_printf("Warning - non-aligned texture copy!\n"); 148 149 t1 = fastrdtsc(); 150 ret = do_memcpy(dest, src, n); 151 t2 = fastrdtsc(); 152 153 rate = time_diff(t1, t2); 154 rate /= (double) n; 155 _mesa_printf("timed_memcpy: %u %u --> %f clocks/byte\n", t1, t2, rate); 156 return ret; 157} 158#endif /* DO_DEBUG */ 159 160/** 161 * Generate new mipmap data from BASE+1 to BASE+p (the minimally-sized mipmap 162 * level). 163 * 164 * The texture object's miptree must be mapped. 165 * 166 * It would be really nice if this was just called by Mesa whenever mipmaps 167 * needed to be regenerated, rather than us having to remember to do so in 168 * each texture image modification path. 169 * 170 * This function should also include an accelerated path. 171 */ 172void 173intel_generate_mipmap(GLcontext *ctx, GLenum target, 174 const struct gl_texture_unit *texUnit, 175 struct gl_texture_object *texObj) 176{ 177 struct intel_texture_object *intelObj = intel_texture_object(texObj); 178 GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 179 int face, i; 180 181 _mesa_generate_mipmap(ctx, target, texUnit, texObj); 182 183 /* Update the level information in our private data in the new images, since 184 * it didn't get set as part of a normal TexImage path. 185 */ 186 for (face = 0; face < nr_faces; face++) { 187 for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) { 188 struct intel_texture_image *intelImage; 189 190 intelImage = intel_texture_image(texObj->Image[face][i]); 191 if (intelImage == NULL) 192 break; 193 194 intelImage->level = i; 195 intelImage->face = face; 196 } 197 } 198} 199 200 201void 202intelInitTextureFuncs(struct dd_function_table *functions) 203{ 204 functions->ChooseTextureFormat = intelChooseTextureFormat; 205 functions->TexImage1D = intelTexImage1D; 206 functions->TexImage2D = intelTexImage2D; 207 functions->TexImage3D = intelTexImage3D; 208 functions->TexSubImage1D = intelTexSubImage1D; 209 functions->TexSubImage2D = intelTexSubImage2D; 210 functions->TexSubImage3D = intelTexSubImage3D; 211#ifdef I915 212 functions->CopyTexImage1D = intelCopyTexImage1D; 213 functions->CopyTexImage2D = intelCopyTexImage2D; 214 functions->CopyTexSubImage1D = intelCopyTexSubImage1D; 215 functions->CopyTexSubImage2D = intelCopyTexSubImage2D; 216#else 217 functions->CopyTexImage1D = _swrast_copy_teximage1d; 218 functions->CopyTexImage2D = _swrast_copy_teximage2d; 219 functions->CopyTexSubImage1D = _swrast_copy_texsubimage1d; 220 functions->CopyTexSubImage2D = _swrast_copy_texsubimage2d; 221#endif 222 functions->GetTexImage = intelGetTexImage; 223 224 /* compressed texture functions */ 225 functions->CompressedTexImage2D = intelCompressedTexImage2D; 226 functions->GetCompressedTexImage = intelGetCompressedTexImage; 227 228 functions->NewTextureObject = intelNewTextureObject; 229 functions->NewTextureImage = intelNewTextureImage; 230 functions->DeleteTexture = intelDeleteTextureObject; 231 functions->FreeTexImageData = intelFreeTextureImageData; 232 functions->UpdateTexturePalette = 0; 233 functions->IsTextureResident = intelIsTextureResident; 234 235#if DO_DEBUG 236 if (INTEL_DEBUG & DEBUG_BUFMGR) 237 functions->TextureMemCpy = timed_memcpy; 238 else 239#endif 240 functions->TextureMemCpy = do_memcpy; 241} 242