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