intel_tex.c revision c0b4257aa9ba783674ccf7162799385734dff211
1#include "swrast/swrast.h" 2#include "texobj.h" 3#include "intel_context.h" 4#include "intel_mipmap_tree.h" 5#include "intel_tex.h" 6 7#define FILE_DEBUG_FLAG DEBUG_TEXTURE 8 9static GLboolean 10intelIsTextureResident(GLcontext * ctx, struct gl_texture_object *texObj) 11{ 12#if 0 13 struct intel_context *intel = intel_context(ctx); 14 struct intel_texture_object *intelObj = intel_texture_object(texObj); 15 16 return 17 intelObj->mt && 18 intelObj->mt->region && 19 intel_is_region_resident(intel, intelObj->mt->region); 20#endif 21 return 1; 22} 23 24 25 26static struct gl_texture_image * 27intelNewTextureImage(GLcontext * ctx) 28{ 29 DBG("%s\n", __FUNCTION__); 30 (void) ctx; 31 return (struct gl_texture_image *) CALLOC_STRUCT(intel_texture_image); 32} 33 34 35static struct gl_texture_object * 36intelNewTextureObject(GLcontext * ctx, GLuint name, GLenum target) 37{ 38 struct intel_texture_object *obj = CALLOC_STRUCT(intel_texture_object); 39 40 DBG("%s\n", __FUNCTION__); 41 _mesa_initialize_texture_object(&obj->base, name, target); 42 43 return &obj->base; 44} 45 46static void 47intelDeleteTextureObject(GLcontext *ctx, 48 struct gl_texture_object *texObj) 49{ 50 struct intel_context *intel = intel_context(ctx); 51 struct intel_texture_object *intelObj = intel_texture_object(texObj); 52 53 if (intelObj->mt) 54 intel_miptree_release(intel, &intelObj->mt); 55 56 _mesa_delete_texture_object(ctx, texObj); 57} 58 59 60static void 61intelFreeTextureImageData(GLcontext * ctx, struct gl_texture_image *texImage) 62{ 63 struct intel_context *intel = intel_context(ctx); 64 struct intel_texture_image *intelImage = intel_texture_image(texImage); 65 66 DBG("%s\n", __FUNCTION__); 67 68 if (intelImage->mt) { 69 intel_miptree_release(intel, &intelImage->mt); 70 } 71 72 if (texImage->Data) { 73 free(texImage->Data); 74 texImage->Data = NULL; 75 } 76} 77 78 79/* The system memcpy (at least on ubuntu 5.10) has problems copying 80 * to agp (writecombined) memory from a source which isn't 64-byte 81 * aligned - there is a 4x performance falloff. 82 * 83 * The x86 __memcpy is immune to this but is slightly slower 84 * (10%-ish) than the system memcpy. 85 * 86 * The sse_memcpy seems to have a slight cliff at 64/32 bytes, but 87 * isn't much faster than x86_memcpy for agp copies. 88 * 89 * TODO: switch dynamically. 90 */ 91static void * 92do_memcpy(void *dest, const void *src, size_t n) 93{ 94 if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) { 95 return __memcpy(dest, src, n); 96 } 97 else 98 return memcpy(dest, src, n); 99} 100 101 102#if DO_DEBUG 103 104#ifndef __x86_64__ 105static unsigned 106fastrdtsc(void) 107{ 108 unsigned eax; 109 __asm__ volatile ("\t" 110 "pushl %%ebx\n\t" 111 "cpuid\n\t" ".byte 0x0f, 0x31\n\t" 112 "popl %%ebx\n":"=a" (eax) 113 :"0"(0) 114 :"ecx", "edx", "cc"); 115 116 return eax; 117} 118#else 119static unsigned 120fastrdtsc(void) 121{ 122 unsigned eax; 123 __asm__ volatile ("\t" "cpuid\n\t" ".byte 0x0f, 0x31\n\t":"=a" (eax) 124 :"0"(0) 125 :"ecx", "edx", "ebx", "cc"); 126 127 return eax; 128} 129#endif 130 131static unsigned 132time_diff(unsigned t, unsigned t2) 133{ 134 return ((t < t2) ? t2 - t : 0xFFFFFFFFU - (t - t2 - 1)); 135} 136 137 138static void * 139timed_memcpy(void *dest, const void *src, size_t n) 140{ 141 void *ret; 142 unsigned t1, t2; 143 double rate; 144 145 if ((((unsigned) src) & 63) || (((unsigned) dest) & 63)) 146 _mesa_printf("Warning - non-aligned texture copy!\n"); 147 148 t1 = fastrdtsc(); 149 ret = do_memcpy(dest, src, n); 150 t2 = fastrdtsc(); 151 152 rate = time_diff(t1, t2); 153 rate /= (double) n; 154 _mesa_printf("timed_memcpy: %u %u --> %f clocks/byte\n", t1, t2, rate); 155 return ret; 156} 157#endif /* DO_DEBUG */ 158 159 160void 161intelInitTextureFuncs(struct dd_function_table *functions) 162{ 163 functions->ChooseTextureFormat = intelChooseTextureFormat; 164 functions->TexImage1D = intelTexImage1D; 165 functions->TexImage2D = intelTexImage2D; 166 functions->TexImage3D = intelTexImage3D; 167 functions->TexSubImage1D = intelTexSubImage1D; 168 functions->TexSubImage2D = intelTexSubImage2D; 169 functions->TexSubImage3D = intelTexSubImage3D; 170#ifdef I915 171 functions->CopyTexImage1D = intelCopyTexImage1D; 172 functions->CopyTexImage2D = intelCopyTexImage2D; 173 functions->CopyTexSubImage1D = intelCopyTexSubImage1D; 174 functions->CopyTexSubImage2D = intelCopyTexSubImage2D; 175#else 176 functions->CopyTexImage1D = _swrast_copy_teximage1d; 177 functions->CopyTexImage2D = _swrast_copy_teximage2d; 178 functions->CopyTexSubImage1D = _swrast_copy_texsubimage1d; 179 functions->CopyTexSubImage2D = _swrast_copy_texsubimage2d; 180#endif 181 functions->GetTexImage = intelGetTexImage; 182 183 /* compressed texture functions */ 184 functions->CompressedTexImage2D = intelCompressedTexImage2D; 185 functions->GetCompressedTexImage = intelGetCompressedTexImage; 186 187 functions->NewTextureObject = intelNewTextureObject; 188 functions->NewTextureImage = intelNewTextureImage; 189 functions->DeleteTexture = intelDeleteTextureObject; 190 functions->FreeTexImageData = intelFreeTextureImageData; 191 functions->UpdateTexturePalette = 0; 192 functions->IsTextureResident = intelIsTextureResident; 193 194#if DO_DEBUG 195 if (INTEL_DEBUG & DEBUG_BUFMGR) 196 functions->TextureMemCpy = timed_memcpy; 197 else 198#endif 199 functions->TextureMemCpy = do_memcpy; 200} 201