radeon/r200/r300: cleanup some of the renderbuffer code
[mesa.git] / src / mesa / drivers / dri / r300 / r300_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 "r300_context.h"
48 #include "r300_state.h"
49 #include "r300_ioctl.h"
50 #include "radeon_mipmap_tree.h"
51 #include "r300_tex.h"
52 #include "r300_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 /**
273 * Ensure all enabled and complete textures are uploaded along with any buffers being used.
274 */
275 GLboolean r300ValidateBuffers(GLcontext * ctx)
276 {
277 r300ContextPtr rmesa = R300_CONTEXT(ctx);
278 struct radeon_cs_space_check bos[16];
279 struct radeon_renderbuffer *rrb;
280 int num_bo = 0;
281 int i;
282 int flushed = 0, ret;
283 again:
284 num_bo = 0;
285
286 rrb = radeon_get_colorbuffer(&rmesa->radeon);
287 /* color buffer */
288 if (rrb && rrb->bo) {
289 bos[num_bo].bo = rrb->bo;
290 bos[num_bo].read_domains = 0;
291 bos[num_bo].write_domain = RADEON_GEM_DOMAIN_VRAM;
292 bos[num_bo].new_accounted = 0;
293 num_bo++;
294 }
295
296 /* depth buffer */
297 rrb = radeon_get_depthbuffer(&rmesa->radeon);
298 /* color buffer */
299 if (rrb && rrb->bo) {
300 bos[num_bo].bo = rrb->bo;
301 bos[num_bo].read_domains = 0;
302 bos[num_bo].write_domain = RADEON_GEM_DOMAIN_VRAM;
303 bos[num_bo].new_accounted = 0;
304 num_bo++;
305 }
306
307 for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
308 radeonTexObj *t;
309
310 if (!ctx->Texture.Unit[i]._ReallyEnabled)
311 continue;
312
313 if (!r300_validate_texture(ctx, ctx->Texture.Unit[i]._Current)) {
314 _mesa_warning(ctx,
315 "failed to validate texture for unit %d.\n",
316 i);
317 }
318 t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
319 if (t->image_override && t->bo)
320 bos[num_bo].bo = t->bo;
321 else if (t->mt->bo)
322 bos[num_bo].bo = t->mt->bo;
323 bos[num_bo].read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
324 bos[num_bo].write_domain = 0;
325 bos[num_bo].new_accounted = 0;
326 num_bo++;
327 }
328
329 ret = radeon_cs_space_check(rmesa->radeon.cmdbuf.cs, bos, num_bo);
330 if (ret == RADEON_CS_SPACE_OP_TO_BIG)
331 return GL_FALSE;
332 if (ret == RADEON_CS_SPACE_FLUSH) {
333 radeonFlush(ctx);
334 if (flushed)
335 return GL_FALSE;
336 flushed = 1;
337 goto again;
338 }
339 return GL_TRUE;
340 }
341
342 void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
343 unsigned long long offset, GLint depth, GLuint pitch)
344 {
345 r300ContextPtr rmesa = pDRICtx->driverPrivate;
346 struct gl_texture_object *tObj =
347 _mesa_lookup_texture(rmesa->radeon.glCtx, texname);
348 radeonTexObjPtr t = radeon_tex_obj(tObj);
349 uint32_t pitch_val;
350
351 if (!tObj)
352 return;
353
354 t->image_override = GL_TRUE;
355
356 if (!offset)
357 return;
358
359 t->bo = NULL;
360 t->override_offset = offset;
361 t->pp_txpitch &= (1 << 13) -1;
362 pitch_val = pitch;
363
364 switch (depth) {
365 case 32:
366 t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
367 t->pp_txfilter |= tx_table[2].filter;
368 pitch_val /= 4;
369 break;
370 case 24:
371 default:
372 t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
373 t->pp_txfilter |= tx_table[4].filter;
374 pitch_val /= 4;
375 break;
376 case 16:
377 t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
378 t->pp_txfilter |= tx_table[5].filter;
379 pitch_val /= 2;
380 break;
381 }
382 pitch_val--;
383
384 t->pp_txpitch |= pitch_val;
385 }
386
387 void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
388 {
389 struct gl_texture_unit *texUnit;
390 struct gl_texture_object *texObj;
391 struct gl_texture_image *texImage;
392 struct radeon_renderbuffer *rb;
393 radeon_texture_image *rImage;
394 radeonContextPtr radeon;
395 r300ContextPtr rmesa;
396 struct radeon_framebuffer *rfb;
397 radeonTexObjPtr t;
398 uint32_t pitch_val;
399
400 target = GL_TEXTURE_RECTANGLE_ARB;
401
402 radeon = pDRICtx->driverPrivate;
403 rmesa = pDRICtx->driverPrivate;
404
405 rfb = dPriv->driverPrivate;
406 texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit];
407 texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target);
408 texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0);
409
410 rImage = get_radeon_texture_image(texImage);
411 t = radeon_tex_obj(texObj);
412 if (t == NULL) {
413 return;
414 }
415
416 radeon_update_renderbuffers(pDRICtx, dPriv);
417 /* back & depth buffer are useless free them right away */
418 rb = (void*)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer;
419 if (rb && rb->bo) {
420 radeon_bo_unref(rb->bo);
421 rb->bo = NULL;
422 }
423 rb = (void*)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
424 if (rb && rb->bo) {
425 radeon_bo_unref(rb->bo);
426 rb->bo = NULL;
427 }
428 rb = rfb->color_rb[0];
429 if (rb->bo == NULL) {
430 /* Failed to BO for the buffer */
431 return;
432 }
433
434 _mesa_lock_texture(radeon->glCtx, texObj);
435 if (t->bo) {
436 radeon_bo_unref(t->bo);
437 t->bo = NULL;
438 }
439 if (rImage->bo) {
440 radeon_bo_unref(rImage->bo);
441 rImage->bo = NULL;
442 }
443 if (t->mt) {
444 radeon_miptree_unreference(t->mt);
445 t->mt = NULL;
446 }
447 if (rImage->mt) {
448 radeon_miptree_unreference(rImage->mt);
449 rImage->mt = NULL;
450 }
451 fprintf(stderr,"settexbuf %dx%d@%d\n", rb->width, rb->height, rb->cpp);
452 _mesa_init_teximage_fields(radeon->glCtx, target, texImage,
453 rb->width, rb->height, 1, 0, rb->cpp);
454 texImage->TexFormat = &_mesa_texformat_rgba8888_rev;
455 rImage->bo = rb->bo;
456 radeon_bo_ref(rImage->bo);
457 t->bo = rb->bo;
458 radeon_bo_ref(t->bo);
459 t->tile_bits = 0;
460 t->image_override = GL_TRUE;
461 t->override_offset = 0;
462 t->pp_txpitch &= (1 << 13) -1;
463 pitch_val = rb->pitch;
464 switch (rb->cpp) {
465 case 4:
466 t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
467 t->pp_txfilter |= tx_table[2].filter;
468 pitch_val /= 4;
469 break;
470 case 3:
471 default:
472 t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
473 t->pp_txfilter |= tx_table[4].filter;
474 pitch_val /= 4;
475 break;
476 case 2:
477 t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
478 t->pp_txfilter |= tx_table[5].filter;
479 pitch_val /= 2;
480 break;
481 }
482 pitch_val--;
483 t->pp_txsize = ((rb->width - 1) << R300_TX_WIDTHMASK_SHIFT) |
484 ((rb->height - 1) << R300_TX_HEIGHTMASK_SHIFT);
485 t->pp_txsize |= R300_TX_SIZE_TXPITCH_EN;
486 t->pp_txpitch |= pitch_val;
487
488 if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
489 if (rb->width > 2048)
490 t->pp_txpitch |= R500_TXWIDTH_BIT11;
491 if (rb->height > 2048)
492 t->pp_txpitch |= R500_TXHEIGHT_BIT11;
493 }
494 t->validated = GL_TRUE;
495 _mesa_unlock_texture(radeon->glCtx, texObj);
496 return;
497 }