07f6de7ad4976d1eda54bc21437258c049d2f0a5
[mesa.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 r600SetTexSampler.BorderColor(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->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 r600SetTexSampler.BorderColor(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.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.MaxAnisotropy);
391 r600SetTexSampler.BorderColor(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 }