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