OSDN Git Service

R600: initial copy of r300 code
[android-x86/external-mesa.git] / src / mesa / drivers / dri / r600 / r600_texstate.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 /**
31  * \file
32  *
33  * \author Keith Whitwell <keith@tungstengraphics.com>
34  *
35  * \todo Enable R300 texture tiling code?
36  */
37
38 #include "main/glheader.h"
39 #include "main/imports.h"
40 #include "main/context.h"
41 #include "main/macros.h"
42 #include "main/texformat.h"
43 #include "main/teximage.h"
44 #include "main/texobj.h"
45 #include "main/enums.h"
46
47 #include "r600_context.h"
48 #include "r600_state.h"
49 #include "r600_ioctl.h"
50 #include "radeon_mipmap_tree.h"
51 #include "r600_tex.h"
52 #include "r600_reg.h"
53
54 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5                 \
55                            || ((f) >= MESA_FORMAT_RGBA_FLOAT32 &&       \
56                                (f) <= MESA_FORMAT_INTENSITY_FLOAT16))   \
57                           && tx_table[f].flag )
58
59 #define _ASSIGN(entry, format)                          \
60         [ MESA_FORMAT_ ## entry ] = { format, 0, 1}
61
62 /*
63  * Note that the _REV formats are the same as the non-REV formats.  This is
64  * because the REV and non-REV formats are identical as a byte string, but
65  * differ when accessed as 16-bit or 32-bit words depending on the endianness of
66  * the host.  Since the textures are transferred to the R300 as a byte string
67  * (i.e. without any byte-swapping), the R300 sees the REV and non-REV formats
68  * identically.  -- paulus
69  */
70
71 static const struct tx_table {
72         GLuint format, filter, flag;
73 } tx_table[] = {
74         /* *INDENT-OFF* */
75 #ifdef MESA_LITTLE_ENDIAN
76         _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
77         _ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)),
78         _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
79         _ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
80 #else
81         _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)),
82         _ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)),
83         _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)),
84         _ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)),
85 #endif
86         _ASSIGN(RGB888, R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8)),
87         _ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
88         _ASSIGN(RGB565_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)),
89         _ASSIGN(ARGB4444, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
90         _ASSIGN(ARGB4444_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)),
91         _ASSIGN(ARGB1555, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
92         _ASSIGN(ARGB1555_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)),
93         _ASSIGN(AL88, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
94         _ASSIGN(AL88_REV, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)),
95         _ASSIGN(RGB332, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z3Y3X2)),
96         _ASSIGN(A8, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8)),
97         _ASSIGN(L8, R300_EASY_TX_FORMAT(X, X, X, ONE, X8)),
98         _ASSIGN(I8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
99         _ASSIGN(CI8, R300_EASY_TX_FORMAT(X, X, X, X, X8)),
100         _ASSIGN(YCBCR, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE),
101         _ASSIGN(YCBCR_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE),
102         _ASSIGN(RGB_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1)),
103         _ASSIGN(RGBA_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1)),
104         _ASSIGN(RGBA_DXT3, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3)),
105         _ASSIGN(RGBA_DXT5, R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5)),
106         _ASSIGN(RGBA_FLOAT32, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R32G32B32A32)),
107         _ASSIGN(RGBA_FLOAT16, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R16G16B16A16)),
108         _ASSIGN(RGB_FLOAT32, 0xffffffff),
109         _ASSIGN(RGB_FLOAT16, 0xffffffff),
110         _ASSIGN(ALPHA_FLOAT32, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I32)),
111         _ASSIGN(ALPHA_FLOAT16, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I16)),
112         _ASSIGN(LUMINANCE_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I32)),
113         _ASSIGN(LUMINANCE_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I16)),
114         _ASSIGN(LUMINANCE_ALPHA_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I32A32)),
115         _ASSIGN(LUMINANCE_ALPHA_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I16A16)),
116         _ASSIGN(INTENSITY_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, X, FL_I32)),
117         _ASSIGN(INTENSITY_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, X, FL_I16)),
118         _ASSIGN(Z16, R300_EASY_TX_FORMAT(X, X, X, X, X16)),
119         _ASSIGN(Z24_S8, R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8)),
120         _ASSIGN(Z32, R300_EASY_TX_FORMAT(X, X, X, X, X32)),
121         /* *INDENT-ON* */
122 };
123
124 #undef _ASSIGN
125
126 void r300SetDepthTexMode(struct gl_texture_object *tObj)
127 {
128         static const GLuint formats[3][3] = {
129                 {
130                         R300_EASY_TX_FORMAT(X, X, X, ONE, X16),
131                         R300_EASY_TX_FORMAT(X, X, X, X, X16),
132                         R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X16),
133                 },
134                 {
135                         R300_EASY_TX_FORMAT(X, X, X, ONE, X24_Y8),
136                         R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8),
137                         R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X24_Y8),
138                 },
139                 {
140                         R300_EASY_TX_FORMAT(X, X, X, ONE, X32),
141                         R300_EASY_TX_FORMAT(X, X, X, X, X32),
142                         R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X32),
143                 },
144         };
145         const GLuint *format;
146         radeonTexObjPtr t;
147
148         if (!tObj)
149                 return;
150
151         t = radeon_tex_obj(tObj);
152
153         switch (tObj->Image[0][tObj->BaseLevel]->TexFormat->MesaFormat) {
154         case MESA_FORMAT_Z16:
155                 format = formats[0];
156                 break;
157         case MESA_FORMAT_Z24_S8:
158                 format = formats[1];
159                 break;
160         case MESA_FORMAT_Z32:
161                 format = formats[2];
162                 break;
163         default:
164                 /* Error...which should have already been caught by higher
165                  * levels of Mesa.
166                  */
167                 ASSERT(0);
168                 return;
169         }
170
171         switch (tObj->DepthMode) {
172         case GL_LUMINANCE:
173                 t->pp_txformat = format[0];
174                 break;
175         case GL_INTENSITY:
176                 t->pp_txformat = format[1];
177                 break;
178         case GL_ALPHA:
179                 t->pp_txformat = format[2];
180                 break;
181         default:
182                 /* Error...which should have already been caught by higher
183                  * levels of Mesa.
184                  */
185                 ASSERT(0);
186                 return;
187         }
188 }
189
190
191 /**
192  * Compute the cached hardware register values for the given texture object.
193  *
194  * \param rmesa Context pointer
195  * \param t the r300 texture object
196  */
197 static void setup_hardware_state(r300ContextPtr rmesa, radeonTexObj *t)
198 {
199         const struct gl_texture_image *firstImage;
200         int firstlevel = t->mt ? t->mt->firstLevel : 0;
201             
202         firstImage = t->base.Image[0][firstlevel];
203
204         if (!t->image_override
205             && VALID_FORMAT(firstImage->TexFormat->MesaFormat)) {
206                 if (firstImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) {
207                         r300SetDepthTexMode(&t->base);
208                 } else {
209                         t->pp_txformat = tx_table[firstImage->TexFormat->MesaFormat].format;
210                 }
211
212                 t->pp_txfilter |= tx_table[firstImage->TexFormat->MesaFormat].filter;
213         } else if (!t->image_override) {
214                 _mesa_problem(NULL, "unexpected texture format in %s",
215                               __FUNCTION__);
216                 return;
217         }
218
219         if (t->image_override && t->bo)
220                 return;
221
222         t->pp_txsize = (((firstImage->Width - 1) << R300_TX_WIDTHMASK_SHIFT)
223                         | ((firstImage->Height - 1) << R300_TX_HEIGHTMASK_SHIFT)
224                         | ((firstImage->DepthLog2) << R300_TX_DEPTHMASK_SHIFT)
225                         | ((t->mt->lastLevel - t->mt->firstLevel) << R300_TX_MAX_MIP_LEVEL_SHIFT));
226
227         t->tile_bits = 0;
228
229         if (t->base.Target == GL_TEXTURE_CUBE_MAP)
230                 t->pp_txformat |= R300_TX_FORMAT_CUBIC_MAP;
231         if (t->base.Target == GL_TEXTURE_3D)
232                 t->pp_txformat |= R300_TX_FORMAT_3D;
233
234
235         if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
236                 unsigned int align = (64 / t->mt->bpp) - 1;
237                 t->pp_txsize |= R300_TX_SIZE_TXPITCH_EN;
238                 if (!t->image_override)
239                         t->pp_txpitch = ((firstImage->Width + align) & ~align) - 1;
240         }
241
242         if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
243             if (firstImage->Width > 2048)
244                 t->pp_txpitch |= R500_TXWIDTH_BIT11;
245             if (firstImage->Height > 2048)
246                 t->pp_txpitch |= R500_TXHEIGHT_BIT11;
247         }
248 }
249
250 /**
251  * Ensure the given texture is ready for rendering.
252  *
253  * Mostly this means populating the texture object's mipmap tree.
254  */
255 static GLboolean r300_validate_texture(GLcontext * ctx, struct gl_texture_object *texObj)
256 {
257         r300ContextPtr rmesa = R300_CONTEXT(ctx);
258         radeonTexObj *t = radeon_tex_obj(texObj);
259
260         if (!radeon_validate_texture_miptree(ctx, texObj))
261                 return GL_FALSE;
262
263         /* Configure the hardware registers (more precisely, the cached version
264          * of the hardware registers). */
265         setup_hardware_state(rmesa, t);
266
267         t->validated = GL_TRUE;
268         return GL_TRUE;
269 }
270
271 /**
272  * Ensure all enabled and complete textures are uploaded along with any buffers being used.
273  */
274 GLboolean r300ValidateBuffers(GLcontext * ctx)
275 {
276         r300ContextPtr rmesa = R300_CONTEXT(ctx);
277         struct radeon_renderbuffer *rrb;
278         int i;
279
280         radeon_validate_reset_bos(&rmesa->radeon);
281
282         rrb = radeon_get_colorbuffer(&rmesa->radeon);
283         /* color buffer */
284         if (rrb && rrb->bo) {
285                 radeon_validate_bo(&rmesa->radeon, rrb->bo,
286                                    0, RADEON_GEM_DOMAIN_VRAM);
287         }
288
289         /* depth buffer */
290         rrb = radeon_get_depthbuffer(&rmesa->radeon);
291         if (rrb && rrb->bo) {
292                 radeon_validate_bo(&rmesa->radeon, rrb->bo,
293                                    0, RADEON_GEM_DOMAIN_VRAM);
294         }
295         
296         for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
297                 radeonTexObj *t;
298
299                 if (!ctx->Texture.Unit[i]._ReallyEnabled)
300                         continue;
301
302                 if (!r300_validate_texture(ctx, ctx->Texture.Unit[i]._Current)) {
303                         _mesa_warning(ctx,
304                                       "failed to validate texture for unit %d.\n",
305                                       i);
306                 }
307                 t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
308                 if (t->image_override && t->bo)
309                         radeon_validate_bo(&rmesa->radeon, t->bo,
310                                            RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
311
312                 else if (t->mt->bo)
313                         radeon_validate_bo(&rmesa->radeon, t->mt->bo,
314                                            RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
315         }
316         if (rmesa->radeon.dma.current)
317                 radeon_validate_bo(&rmesa->radeon, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0);
318
319         return radeon_revalidate_bos(ctx);
320 }
321
322 void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
323                       unsigned long long offset, GLint depth, GLuint pitch)
324 {
325         r300ContextPtr rmesa = pDRICtx->driverPrivate;
326         struct gl_texture_object *tObj =
327             _mesa_lookup_texture(rmesa->radeon.glCtx, texname);
328         radeonTexObjPtr t = radeon_tex_obj(tObj);
329         uint32_t pitch_val;
330
331         if (!tObj)
332                 return;
333
334         t->image_override = GL_TRUE;
335
336         if (!offset)
337                 return;
338
339         t->bo = NULL;
340         t->override_offset = offset;
341         t->pp_txpitch &= (1 << 13) -1;
342         pitch_val = pitch;
343
344         switch (depth) {
345         case 32:
346                 t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
347                 t->pp_txfilter |= tx_table[2].filter;
348                 pitch_val /= 4;
349                 break;
350         case 24:
351         default:
352                 t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
353                 t->pp_txfilter |= tx_table[4].filter;
354                 pitch_val /= 4;
355                 break;
356         case 16:
357                 t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
358                 t->pp_txfilter |= tx_table[5].filter;
359                 pitch_val /= 2;
360                 break;
361         }
362         pitch_val--;
363
364         t->pp_txpitch |= pitch_val;
365 }
366
367 void r300SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_format, __DRIdrawable *dPriv)
368 {
369         struct gl_texture_unit *texUnit;
370         struct gl_texture_object *texObj;
371         struct gl_texture_image *texImage;
372         struct radeon_renderbuffer *rb;
373         radeon_texture_image *rImage;
374         radeonContextPtr radeon;
375         r300ContextPtr rmesa;
376         struct radeon_framebuffer *rfb;
377         radeonTexObjPtr t;
378         uint32_t pitch_val;
379         uint32_t internalFormat, type, format;
380
381         type = GL_BGRA;
382         format = GL_UNSIGNED_BYTE;
383         internalFormat = (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT ? 3 : 4);
384
385         radeon = pDRICtx->driverPrivate;
386         rmesa = pDRICtx->driverPrivate;
387
388         rfb = dPriv->driverPrivate;
389         texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit];
390         texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target);
391         texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0);
392
393         rImage = get_radeon_texture_image(texImage);
394         t = radeon_tex_obj(texObj);
395         if (t == NULL) {
396             return;
397         }
398
399         radeon_update_renderbuffers(pDRICtx, dPriv);
400         /* back & depth buffer are useless free them right away */
401         rb = (void*)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer;
402         if (rb && rb->bo) {
403                 radeon_bo_unref(rb->bo);
404         rb->bo = NULL;
405         }
406         rb = (void*)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
407         if (rb && rb->bo) {
408                 radeon_bo_unref(rb->bo);
409                 rb->bo = NULL;
410         }
411         rb = rfb->color_rb[0];
412         if (rb->bo == NULL) {
413                 /* Failed to BO for the buffer */
414                 return;
415         }
416         
417         _mesa_lock_texture(radeon->glCtx, texObj);
418         if (t->bo) {
419                 radeon_bo_unref(t->bo);
420                 t->bo = NULL;
421         }
422         if (rImage->bo) {
423                 radeon_bo_unref(rImage->bo);
424                 rImage->bo = NULL;
425         }
426         if (t->mt) {
427                 radeon_miptree_unreference(t->mt);
428                 t->mt = NULL;
429         }
430         if (rImage->mt) {
431                 radeon_miptree_unreference(rImage->mt);
432                 rImage->mt = NULL;
433         }
434         fprintf(stderr,"settexbuf %dx%d@%d %d targ %x format %x\n", rb->width, rb->height, rb->cpp, rb->pitch, target, format);
435         _mesa_init_teximage_fields(radeon->glCtx, target, texImage,
436                                    rb->width, rb->height, 1, 0, rb->cpp);
437         texImage->RowStride = rb->pitch / rb->cpp;
438         texImage->TexFormat = radeonChooseTextureFormat(radeon->glCtx,
439                                                         internalFormat,
440                                                         type, format, 0);
441         rImage->bo = rb->bo;
442         radeon_bo_ref(rImage->bo);
443         t->bo = rb->bo;
444         radeon_bo_ref(t->bo);
445         t->tile_bits = 0;
446         t->image_override = GL_TRUE;
447         t->override_offset = 0;
448         t->pp_txpitch &= (1 << 13) -1;
449         pitch_val = rb->pitch;
450         switch (rb->cpp) {
451         case 4:
452                 t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
453                 t->pp_txfilter |= tx_table[2].filter;
454                 pitch_val /= 4;
455                 break;
456         case 3:
457         default:
458                 t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
459                 t->pp_txfilter |= tx_table[4].filter;
460                 pitch_val /= 4;
461                 break;
462         case 2:
463                 t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
464                 t->pp_txfilter |= tx_table[5].filter;
465                 pitch_val /= 2;
466                 break;
467         }
468         pitch_val--;
469         t->pp_txsize = ((rb->width - 1) << R300_TX_WIDTHMASK_SHIFT) |
470               ((rb->height - 1) << R300_TX_HEIGHTMASK_SHIFT);
471         t->pp_txsize |= R300_TX_SIZE_TXPITCH_EN;
472         t->pp_txpitch |= pitch_val;
473
474         if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
475             if (rb->width > 2048)
476                 t->pp_txpitch |= R500_TXWIDTH_BIT11;
477             if (rb->height > 2048)
478                 t->pp_txpitch |= R500_TXHEIGHT_BIT11;
479         }
480         t->validated = GL_TRUE;
481         _mesa_unlock_texture(radeon->glCtx, texObj);
482         return;
483 }
484
485 void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
486 {
487         r300SetTexBuffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv);
488 }