Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / r600 / r600_tex.c
1 /*
2 Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
3
4 The Weather Channel (TM) funded Tungsten Graphics to develop the
5 initial release of the Radeon 8500 driver under the XFree86 license.
6 This notice must be preserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
15
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 */
28
29 /**
30  * \file
31  *
32  * \author Keith Whitwell <keith@tungstengraphics.com>
33  */
34
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/colormac.h"
38 #include "main/context.h"
39 #include "main/enums.h"
40 #include "main/image.h"
41 #include "main/mfeatures.h"
42 #include "main/mipmap.h"
43 #include "main/simple_list.h"
44 #include "main/texstore.h"
45 #include "main/texobj.h"
46
47 #include "texmem.h"
48
49 #include "r600_context.h"
50 #include "radeon_mipmap_tree.h"
51 #include "r600_tex.h"
52
53
54 static unsigned int translate_wrap_mode(GLenum wrapmode)
55 {
56         switch(wrapmode) {
57         case GL_REPEAT: return SQ_TEX_WRAP;
58         case GL_CLAMP: return SQ_TEX_CLAMP_HALF_BORDER;
59         case GL_CLAMP_TO_EDGE: return SQ_TEX_CLAMP_LAST_TEXEL;
60         case GL_CLAMP_TO_BORDER: return SQ_TEX_CLAMP_BORDER;
61         case GL_MIRRORED_REPEAT: return SQ_TEX_MIRROR;
62         case GL_MIRROR_CLAMP_EXT: return SQ_TEX_MIRROR_ONCE_HALF_BORDER;
63         case GL_MIRROR_CLAMP_TO_EDGE_EXT: return SQ_TEX_MIRROR_ONCE_LAST_TEXEL;
64         case GL_MIRROR_CLAMP_TO_BORDER_EXT: return SQ_TEX_MIRROR_ONCE_BORDER;
65         default:
66                 radeon_error("bad wrap mode in %s", __FUNCTION__);
67                 return 0;
68         }
69 }
70
71
72 /**
73  * Update the cached hardware registers based on the current texture wrap modes.
74  *
75  * \param t Texture object whose wrap modes are to be set
76  */
77 static void r600UpdateTexWrap(radeonTexObjPtr t)
78 {
79         struct gl_texture_object *tObj = &t->base;
80
81         SETfield(t->SQ_TEX_SAMPLER0, translate_wrap_mode(tObj->Sampler.WrapS),
82                  SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_shift, SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_mask);
83
84         if (tObj->Target != GL_TEXTURE_1D) {
85                 SETfield(t->SQ_TEX_SAMPLER0, translate_wrap_mode(tObj->Sampler.WrapT),
86                          CLAMP_Y_shift, CLAMP_Y_mask);
87
88                 if (tObj->Target == GL_TEXTURE_3D)
89                         SETfield(t->SQ_TEX_SAMPLER0, translate_wrap_mode(tObj->Sampler.WrapR),
90                                  CLAMP_Z_shift, CLAMP_Z_mask);
91         }
92 }
93
94 static void r600SetTexDefaultState(radeonTexObjPtr t)
95 {
96         /* Init text object to default states. */
97         t->SQ_TEX_RESOURCE0              = 0;
98         SETfield(t->SQ_TEX_RESOURCE0, SQ_TEX_DIM_2D, DIM_shift, DIM_mask);
99         SETfield(t->SQ_TEX_RESOURCE0, ARRAY_LINEAR_GENERAL,
100                  SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_shift, SQ_TEX_RESOURCE_WORD0_0__TILE_MODE_mask);
101         CLEARbit(t->SQ_TEX_RESOURCE0, TILE_TYPE_bit);
102
103         t->SQ_TEX_RESOURCE1                = 0;
104         SETfield(t->SQ_TEX_RESOURCE1, FMT_8_8_8_8,
105                  SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
106
107         t->SQ_TEX_RESOURCE2                = 0;
108         t->SQ_TEX_RESOURCE3                = 0;
109
110         t->SQ_TEX_RESOURCE4                   = 0;
111         SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
112                  FORMAT_COMP_X_shift, FORMAT_COMP_X_mask);
113         SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
114                  FORMAT_COMP_Y_shift, FORMAT_COMP_Y_mask);
115         SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
116                  FORMAT_COMP_Z_shift, FORMAT_COMP_Z_mask);
117         SETfield(t->SQ_TEX_RESOURCE4, SQ_FORMAT_COMP_UNSIGNED,
118                  FORMAT_COMP_W_shift, FORMAT_COMP_W_mask);
119         SETfield(t->SQ_TEX_RESOURCE4, SQ_NUM_FORMAT_NORM,
120                  SQ_TEX_RESOURCE_WORD4_0__NUM_FORMAT_ALL_shift, SQ_TEX_RESOURCE_WORD4_0__NUM_FORMAT_ALL_mask);
121         CLEARbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__SRF_MODE_ALL_bit);
122         CLEARbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit);
123         SETfield(t->SQ_TEX_RESOURCE4, SQ_ENDIAN_NONE,
124                  SQ_TEX_RESOURCE_WORD4_0__ENDIAN_SWAP_shift, SQ_TEX_RESOURCE_WORD4_0__ENDIAN_SWAP_mask);
125         SETfield(t->SQ_TEX_RESOURCE4, 1, REQUEST_SIZE_shift, REQUEST_SIZE_mask);
126         SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
127                  SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift,
128                  SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
129         SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
130                  SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift,
131                  SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
132         SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
133                  SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift,
134                  SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
135         SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
136                  SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift,
137                  SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
138         SETfield(t->SQ_TEX_RESOURCE4, 0, BASE_LEVEL_shift, BASE_LEVEL_mask); /* mip-maps */
139
140         t->SQ_TEX_RESOURCE5 = 0;
141         t->SQ_TEX_RESOURCE6 = 0;
142
143         SETfield(t->SQ_TEX_RESOURCE6, SQ_TEX_VTX_VALID_TEXTURE,
144                  SQ_TEX_RESOURCE_WORD6_0__TYPE_shift, SQ_TEX_RESOURCE_WORD6_0__TYPE_mask);
145
146         /* Initialize sampler registers */
147         t->SQ_TEX_SAMPLER0                           = 0;
148         SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_WRAP, SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_shift,
149                  SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_mask);
150         SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_WRAP, CLAMP_Y_shift, CLAMP_Y_mask);
151         SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_WRAP, CLAMP_Z_shift, CLAMP_Z_mask);
152         SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_XY_FILTER_POINT, XY_MAG_FILTER_shift, XY_MAG_FILTER_mask);
153         SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_XY_FILTER_POINT, XY_MIN_FILTER_shift, XY_MIN_FILTER_mask);
154         SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_Z_FILTER_NONE, Z_FILTER_shift, Z_FILTER_mask);
155         SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_Z_FILTER_NONE, MIP_FILTER_shift, MIP_FILTER_mask);
156         SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_BORDER_COLOR_TRANS_BLACK, BORDER_COLOR_TYPE_shift, BORDER_COLOR_TYPE_mask);
157
158         t->SQ_TEX_SAMPLER1                           = 0;
159         SETfield(t->SQ_TEX_SAMPLER1, 0x3ff, MAX_LOD_shift, MAX_LOD_mask);
160
161         t->SQ_TEX_SAMPLER2                          = 0;
162         SETbit(t->SQ_TEX_SAMPLER2, SQ_TEX_SAMPLER_WORD2_0__TYPE_bit);
163 }
164
165
166 #if 0
167 static GLuint aniso_filter(GLfloat anisotropy)
168 {
169         if (anisotropy >= 16.0) {
170                 return R300_TX_MAX_ANISO_16_TO_1;
171         } else if (anisotropy >= 8.0) {
172                 return R300_TX_MAX_ANISO_8_TO_1;
173         } else if (anisotropy >= 4.0) {
174                 return R300_TX_MAX_ANISO_4_TO_1;
175         } else if (anisotropy >= 2.0) {
176                 return R300_TX_MAX_ANISO_2_TO_1;
177         } else {
178                 return R300_TX_MAX_ANISO_1_TO_1;
179         }
180         return 0;
181 }
182 #endif
183
184 /**
185  * Set the texture magnification and minification modes.
186  *
187  * \param t Texture whose filter modes are to be set
188  * \param minf Texture minification mode
189  * \param magf Texture magnification mode
190  * \param anisotropy Maximum anisotropy level
191  */
192 static void r600SetTexFilter(radeonTexObjPtr t, GLenum minf, GLenum magf, GLfloat anisotropy)
193 {
194         /* Force revalidation to account for switches from/to mipmapping. */
195         t->validated = GL_FALSE;
196
197         /* Note that EXT_texture_filter_anisotropic is extremely vague about
198          * how anisotropic filtering interacts with the "normal" filter modes.
199          * When anisotropic filtering is enabled, we override min and mag
200          * filter settings completely. This includes driconf's settings.
201          */
202         if (anisotropy >= 2.0 && (minf != GL_NEAREST) && (magf != GL_NEAREST)) {
203                 /*t->pp_txfilter |= R300_TX_MAG_FILTER_ANISO
204                         | R300_TX_MIN_FILTER_ANISO
205                         | R300_TX_MIN_FILTER_MIP_LINEAR
206                         | aniso_filter(anisotropy);*/
207                 radeon_print(RADEON_TEXTURE, RADEON_NORMAL, "Using maximum anisotropy of %f\n", anisotropy);
208                 return;
209         }
210
211         switch (minf) {
212         case GL_NEAREST:
213                 SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Point,
214                          XY_MIN_FILTER_shift, XY_MIN_FILTER_mask);
215                 SETfield(t->SQ_TEX_SAMPLER0, TEX_MipFilter_None,
216                          MIP_FILTER_shift, MIP_FILTER_mask);
217                 break;
218         case GL_LINEAR:
219                 SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Linear,
220                          XY_MIN_FILTER_shift, XY_MIN_FILTER_mask);
221                 SETfield(t->SQ_TEX_SAMPLER0, TEX_MipFilter_None,
222                          MIP_FILTER_shift, MIP_FILTER_mask);
223                 break;
224         case GL_NEAREST_MIPMAP_NEAREST:
225                 SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Point,
226                          XY_MIN_FILTER_shift, XY_MIN_FILTER_mask);
227                 SETfield(t->SQ_TEX_SAMPLER0, TEX_MipFilter_Point,
228                          MIP_FILTER_shift, MIP_FILTER_mask);
229                 break;
230         case GL_NEAREST_MIPMAP_LINEAR:
231                 SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Point,
232                          XY_MIN_FILTER_shift, XY_MIN_FILTER_mask);
233                 SETfield(t->SQ_TEX_SAMPLER0, TEX_MipFilter_Linear,
234                          MIP_FILTER_shift, MIP_FILTER_mask);
235                 break;
236         case GL_LINEAR_MIPMAP_NEAREST:
237                 SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Linear,
238                          XY_MIN_FILTER_shift, XY_MIN_FILTER_mask);
239                 SETfield(t->SQ_TEX_SAMPLER0, TEX_MipFilter_Point,
240                          MIP_FILTER_shift, MIP_FILTER_mask);
241                 break;
242         case GL_LINEAR_MIPMAP_LINEAR:
243                 SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Linear,
244                          XY_MIN_FILTER_shift, XY_MIN_FILTER_mask);
245                 SETfield(t->SQ_TEX_SAMPLER0, TEX_MipFilter_Linear,
246                          MIP_FILTER_shift, MIP_FILTER_mask);
247                 break;
248         }
249
250         /* Note we don't have 3D mipmaps so only use the mag filter setting
251          * to set the 3D texture filter mode.
252          */
253         switch (magf) {
254         case GL_NEAREST:
255                 SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Point,
256                          XY_MAG_FILTER_shift, XY_MAG_FILTER_mask);
257                 break;
258         case GL_LINEAR:
259                 SETfield(t->SQ_TEX_SAMPLER0, TEX_XYFilter_Linear,
260                          XY_MAG_FILTER_shift, XY_MAG_FILTER_mask);
261                 break;
262         }
263 }
264
265 static void r600SetTexBorderColor(radeonTexObjPtr t, const GLfloat color[4])
266 {
267         t->TD_PS_SAMPLER0_BORDER_ALPHA = *((uint32_t*)&(color[3]));
268         t->TD_PS_SAMPLER0_BORDER_BLUE = *((uint32_t*)&(color[2]));
269         t->TD_PS_SAMPLER0_BORDER_GREEN = *((uint32_t*)&(color[1]));
270         t->TD_PS_SAMPLER0_BORDER_RED = *((uint32_t*)&(color[0]));
271         SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_BORDER_COLOR_REGISTER,
272                  BORDER_COLOR_TYPE_shift, BORDER_COLOR_TYPE_mask);
273 }
274
275 /**
276  * Changes variables and flags for a state update, which will happen at the
277  * next UpdateTextureState
278  */
279
280 static void r600TexParameter(struct gl_context * ctx, GLenum target,
281                              struct gl_texture_object *texObj,
282                              GLenum pname, const GLfloat * params)
283 {
284         radeonTexObj* t = radeon_tex_obj(texObj);
285         GLenum baseFormat;
286
287         radeon_print(RADEON_STATE | RADEON_TEXTURE, RADEON_VERBOSE,
288                         "%s( %s )\n", __FUNCTION__,
289                         _mesa_lookup_enum_by_nr(pname));
290
291         switch (pname) {
292         case GL_TEXTURE_MIN_FILTER:
293         case GL_TEXTURE_MAG_FILTER:
294         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
295                 r600SetTexFilter(t, texObj->Sampler.MinFilter, texObj->Sampler.MagFilter, texObj->Sampler.MaxAnisotropy);
296                 break;
297
298         case GL_TEXTURE_WRAP_S:
299         case GL_TEXTURE_WRAP_T:
300         case GL_TEXTURE_WRAP_R:
301                 r600UpdateTexWrap(t);
302                 break;
303
304         case GL_TEXTURE_BORDER_COLOR:
305                 r600SetTexBorderColor(t, texObj->Sampler.BorderColor.f);
306                 break;
307
308         case GL_TEXTURE_BASE_LEVEL:
309         case GL_TEXTURE_MAX_LEVEL:
310         case GL_TEXTURE_MIN_LOD:
311         case GL_TEXTURE_MAX_LOD:
312                 t->validated = GL_FALSE;
313                 break;
314
315         case GL_DEPTH_TEXTURE_MODE:
316                 if (!texObj->Image[0][texObj->BaseLevel])
317                         return;
318                 baseFormat = texObj->Image[0][texObj->BaseLevel]->_BaseFormat;
319                 if (baseFormat == GL_DEPTH_COMPONENT ||
320                     baseFormat == GL_DEPTH_STENCIL) {
321                         r600SetDepthTexMode(texObj);
322                         break;
323                 } else {
324                         /* If the texture isn't a depth texture, changing this
325                          * state won't cause any changes to the hardware.
326                          * Don't force a flush of texture state.
327                          */
328                         return;
329                 }
330
331         default:
332                 return;
333         }
334 }
335
336 static void r600DeleteTexture(struct gl_context * ctx, struct gl_texture_object *texObj)
337 {
338         context_t* rmesa = R700_CONTEXT(ctx);
339         radeonTexObj* t = radeon_tex_obj(texObj);
340
341         radeon_print(RADEON_STATE | RADEON_TEXTURE, RADEON_NORMAL,
342                 "%s( %p (target = %s) )\n", __FUNCTION__,
343                         (void *)texObj,
344                         _mesa_lookup_enum_by_nr(texObj->Target));
345
346         if (rmesa) {
347                 int i;
348                 radeon_firevertices(&rmesa->radeon);
349
350                 for(i = 0; i < R700_MAX_TEXTURE_UNITS; ++i)
351                         if (rmesa->hw.textures[i] == t)
352                                 rmesa->hw.textures[i] = 0;
353         }
354
355         if (t->bo) {
356                 radeon_bo_unref(t->bo);
357                 t->bo = NULL;
358         }
359
360         radeon_miptree_unreference(&t->mt);
361
362         _mesa_delete_texture_object(ctx, texObj);
363 }
364
365 /**
366  * Allocate a new texture object.
367  * Called via ctx->Driver.NewTextureObject.
368  * Note: this function will be called during context creation to
369  * allocate the default texture objects.
370  * Fixup MaxAnisotropy according to user preference.
371  */
372 static struct gl_texture_object *r600NewTextureObject(struct gl_context * ctx,
373                                                       GLuint name,
374                                                       GLenum target)
375 {
376         context_t* rmesa = R700_CONTEXT(ctx);
377         radeonTexObj* t = CALLOC_STRUCT(radeon_tex_obj);
378
379
380         radeon_print(RADEON_STATE | RADEON_TEXTURE, RADEON_NORMAL,
381                 "%s( %p (target = %s) )\n", __FUNCTION__,
382                         t, _mesa_lookup_enum_by_nr(target));
383
384         _mesa_initialize_texture_object(&t->base, name, target);
385         t->base.Sampler.MaxAnisotropy = rmesa->radeon.initialMaxAnisotropy;
386
387         /* Initialize hardware state */
388         r600SetTexDefaultState(t);
389         r600UpdateTexWrap(t);
390         r600SetTexFilter(t, t->base.Sampler.MinFilter, t->base.Sampler.MagFilter, t->base.Sampler.MaxAnisotropy);
391         r600SetTexBorderColor(t, t->base.Sampler.BorderColor.f);
392
393         return &t->base;
394 }
395
396 unsigned r600IsFormatRenderable(gl_format mesa_format)
397 {
398         switch (mesa_format) {
399         case MESA_FORMAT_RGBA8888:
400         case MESA_FORMAT_SIGNED_RGBA8888:
401         case MESA_FORMAT_RGBA8888_REV:
402         case MESA_FORMAT_SIGNED_RGBA8888_REV:
403         case MESA_FORMAT_ARGB8888:
404         case MESA_FORMAT_XRGB8888:
405         case MESA_FORMAT_ARGB8888_REV:
406         case MESA_FORMAT_XRGB8888_REV:
407         case MESA_FORMAT_RGB565:
408         case MESA_FORMAT_RGB565_REV:
409         case MESA_FORMAT_ARGB4444:
410         case MESA_FORMAT_ARGB4444_REV:
411         case MESA_FORMAT_ARGB1555:
412         case MESA_FORMAT_ARGB1555_REV:
413         case MESA_FORMAT_AL88:
414         case MESA_FORMAT_AL88_REV:
415         case MESA_FORMAT_RGB332:
416         case MESA_FORMAT_A8:
417         case MESA_FORMAT_I8:
418         case MESA_FORMAT_CI8:
419         case MESA_FORMAT_L8:
420         case MESA_FORMAT_RGBA_FLOAT32:
421         case MESA_FORMAT_RGBA_FLOAT16:
422         case MESA_FORMAT_ALPHA_FLOAT32:
423         case MESA_FORMAT_ALPHA_FLOAT16:
424         case MESA_FORMAT_LUMINANCE_FLOAT32:
425         case MESA_FORMAT_LUMINANCE_FLOAT16:
426         case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32:
427         case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16:
428         case MESA_FORMAT_INTENSITY_FLOAT32: /* X, X, X, X */
429         case MESA_FORMAT_INTENSITY_FLOAT16: /* X, X, X, X */
430         case MESA_FORMAT_X8_Z24:
431         case MESA_FORMAT_S8_Z24:
432         case MESA_FORMAT_Z24_S8:
433         case MESA_FORMAT_Z16:
434         case MESA_FORMAT_Z32:
435         case MESA_FORMAT_SARGB8:
436         case MESA_FORMAT_SLA8:
437         case MESA_FORMAT_SL8:
438                 return 1;
439         default:
440                 return 0;
441         }
442 }
443
444 void r600InitTextureFuncs(radeonContextPtr radeon, struct dd_function_table *functions)
445 {
446         /* Note: we only plug in the functions we implement in the driver
447          * since _mesa_init_driver_functions() was already called.
448          */
449         functions->NewTextureImage = radeonNewTextureImage;
450         functions->FreeTexImageData = radeonFreeTexImageData;
451         functions->MapTexture = radeonMapTexture;
452         functions->UnmapTexture = radeonUnmapTexture;
453
454         functions->ChooseTextureFormat = radeonChooseTextureFormat_mesa;
455         functions->TexImage1D = radeonTexImage1D;
456         functions->TexImage2D = radeonTexImage2D;
457         functions->TexImage3D = radeonTexImage3D;
458         functions->TexSubImage1D = radeonTexSubImage1D;
459         functions->TexSubImage2D = radeonTexSubImage2D;
460         functions->TexSubImage3D = radeonTexSubImage3D;
461         functions->GetTexImage = radeonGetTexImage;
462         functions->GetCompressedTexImage = radeonGetCompressedTexImage;
463         functions->NewTextureObject = r600NewTextureObject;
464         functions->DeleteTexture = r600DeleteTexture;
465         functions->IsTextureResident = driIsTextureResident;
466
467         functions->TexParameter = r600TexParameter;
468
469         functions->CompressedTexImage2D = radeonCompressedTexImage2D;
470         functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D;
471
472         if (radeon->radeonScreen->kernel_mm) {
473                 functions->CopyTexImage2D = radeonCopyTexImage2D;
474                 functions->CopyTexSubImage2D = radeonCopyTexSubImage2D;
475         }
476
477         functions->GenerateMipmap = radeonGenerateMipmap;
478
479 #if FEATURE_OES_EGL_image
480         functions->EGLImageTargetTexture2D = radeon_image_target_texture_2d;
481 #endif
482
483         driInitTextureFormats();
484 }