Merge remote branch 'main/radeon-rewrite'
[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(S8_Z24, R300_EASY_TX_FORMAT(Y, Y, Y, Y, X24_Y8)),
121 _ASSIGN(Z32, R300_EASY_TX_FORMAT(X, X, X, X, X32)),
122 /* *INDENT-ON* */
123 };
124
125 #undef _ASSIGN
126
127 void r300SetDepthTexMode(struct gl_texture_object *tObj)
128 {
129 static const GLuint formats[3][3] = {
130 {
131 R300_EASY_TX_FORMAT(X, X, X, ONE, X16),
132 R300_EASY_TX_FORMAT(X, X, X, X, X16),
133 R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X16),
134 },
135 {
136 R300_EASY_TX_FORMAT(X, X, X, ONE, X24_Y8),
137 R300_EASY_TX_FORMAT(X, X, X, X, X24_Y8),
138 R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X24_Y8),
139 },
140 {
141 R300_EASY_TX_FORMAT(X, X, X, ONE, X32),
142 R300_EASY_TX_FORMAT(X, X, X, X, X32),
143 R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X32),
144 },
145 };
146 const GLuint *format;
147 radeonTexObjPtr t;
148
149 if (!tObj)
150 return;
151
152 t = radeon_tex_obj(tObj);
153
154 switch (tObj->Image[0][tObj->BaseLevel]->TexFormat->MesaFormat) {
155 case MESA_FORMAT_Z16:
156 format = formats[0];
157 break;
158 case MESA_FORMAT_Z24_S8:
159 format = formats[1];
160 break;
161 case MESA_FORMAT_Z32:
162 format = formats[2];
163 break;
164 default:
165 /* Error...which should have already been caught by higher
166 * levels of Mesa.
167 */
168 ASSERT(0);
169 return;
170 }
171
172 switch (tObj->DepthMode) {
173 case GL_LUMINANCE:
174 t->pp_txformat = format[0];
175 break;
176 case GL_INTENSITY:
177 t->pp_txformat = format[1];
178 break;
179 case GL_ALPHA:
180 t->pp_txformat = format[2];
181 break;
182 default:
183 /* Error...which should have already been caught by higher
184 * levels of Mesa.
185 */
186 ASSERT(0);
187 return;
188 }
189 }
190
191
192 /**
193 * Compute the cached hardware register values for the given texture object.
194 *
195 * \param rmesa Context pointer
196 * \param t the r300 texture object
197 */
198 static void setup_hardware_state(r300ContextPtr rmesa, radeonTexObj *t)
199 {
200 const struct gl_texture_image *firstImage;
201 int firstlevel = t->mt ? t->mt->firstLevel : 0;
202
203 firstImage = t->base.Image[0][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 if (t->image_override && t->bo)
221 return;
222
223 t->pp_txsize = (((firstImage->Width - 1) << R300_TX_WIDTHMASK_SHIFT)
224 | ((firstImage->Height - 1) << R300_TX_HEIGHTMASK_SHIFT)
225 | ((firstImage->DepthLog2) << R300_TX_DEPTHMASK_SHIFT)
226 | ((t->mt->lastLevel - t->mt->firstLevel) << R300_TX_MAX_MIP_LEVEL_SHIFT));
227
228 t->tile_bits = 0;
229
230 if (t->base.Target == GL_TEXTURE_CUBE_MAP)
231 t->pp_txformat |= R300_TX_FORMAT_CUBIC_MAP;
232 if (t->base.Target == GL_TEXTURE_3D)
233 t->pp_txformat |= R300_TX_FORMAT_3D;
234
235
236 if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
237 unsigned int align = (64 / t->mt->bpp) - 1;
238 t->pp_txsize |= R300_TX_SIZE_TXPITCH_EN;
239 if (!t->image_override)
240 t->pp_txpitch = ((firstImage->Width + align) & ~align) - 1;
241 }
242
243 if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
244 if (firstImage->Width > 2048)
245 t->pp_txpitch |= R500_TXWIDTH_BIT11;
246 if (firstImage->Height > 2048)
247 t->pp_txpitch |= R500_TXHEIGHT_BIT11;
248 }
249 }
250
251 /**
252 * Ensure the given texture is ready for rendering.
253 *
254 * Mostly this means populating the texture object's mipmap tree.
255 */
256 static GLboolean r300_validate_texture(GLcontext * ctx, struct gl_texture_object *texObj)
257 {
258 r300ContextPtr rmesa = R300_CONTEXT(ctx);
259 radeonTexObj *t = radeon_tex_obj(texObj);
260
261 if (!radeon_validate_texture_miptree(ctx, texObj))
262 return GL_FALSE;
263
264 /* Configure the hardware registers (more precisely, the cached version
265 * of the hardware registers). */
266 setup_hardware_state(rmesa, t);
267
268 t->validated = GL_TRUE;
269 return GL_TRUE;
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_renderbuffer *rrb;
279 int i;
280
281 radeon_validate_reset_bos(&rmesa->radeon);
282
283 rrb = radeon_get_colorbuffer(&rmesa->radeon);
284 /* color buffer */
285 if (rrb && rrb->bo) {
286 radeon_validate_bo(&rmesa->radeon, rrb->bo,
287 0, RADEON_GEM_DOMAIN_VRAM);
288 }
289
290 /* depth buffer */
291 rrb = radeon_get_depthbuffer(&rmesa->radeon);
292 if (rrb && rrb->bo) {
293 radeon_validate_bo(&rmesa->radeon, rrb->bo,
294 0, RADEON_GEM_DOMAIN_VRAM);
295 }
296
297 for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
298 radeonTexObj *t;
299
300 if (!ctx->Texture.Unit[i]._ReallyEnabled)
301 continue;
302
303 if (!r300_validate_texture(ctx, ctx->Texture.Unit[i]._Current)) {
304 _mesa_warning(ctx,
305 "failed to validate texture for unit %d.\n",
306 i);
307 }
308 t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
309 if (t->image_override && t->bo)
310 radeon_validate_bo(&rmesa->radeon, t->bo,
311 RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
312
313 else if (t->mt->bo)
314 radeon_validate_bo(&rmesa->radeon, t->mt->bo,
315 RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
316 }
317 if (rmesa->radeon.dma.current)
318 radeon_validate_bo(&rmesa->radeon, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0);
319
320 return radeon_revalidate_bos(ctx);
321 }
322
323 void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
324 unsigned long long offset, GLint depth, GLuint pitch)
325 {
326 r300ContextPtr rmesa = pDRICtx->driverPrivate;
327 struct gl_texture_object *tObj =
328 _mesa_lookup_texture(rmesa->radeon.glCtx, texname);
329 radeonTexObjPtr t = radeon_tex_obj(tObj);
330 uint32_t pitch_val;
331
332 if (!tObj)
333 return;
334
335 t->image_override = GL_TRUE;
336
337 if (!offset)
338 return;
339
340 t->bo = NULL;
341 t->override_offset = offset;
342 t->pp_txpitch &= (1 << 13) -1;
343 pitch_val = pitch;
344
345 switch (depth) {
346 case 32:
347 t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
348 t->pp_txfilter |= tx_table[2].filter;
349 pitch_val /= 4;
350 break;
351 case 24:
352 default:
353 t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
354 t->pp_txfilter |= tx_table[4].filter;
355 pitch_val /= 4;
356 break;
357 case 16:
358 t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
359 t->pp_txfilter |= tx_table[5].filter;
360 pitch_val /= 2;
361 break;
362 }
363 pitch_val--;
364
365 t->pp_txpitch |= pitch_val;
366 }
367
368 void r300SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_format, __DRIdrawable *dPriv)
369 {
370 struct gl_texture_unit *texUnit;
371 struct gl_texture_object *texObj;
372 struct gl_texture_image *texImage;
373 struct radeon_renderbuffer *rb;
374 radeon_texture_image *rImage;
375 radeonContextPtr radeon;
376 r300ContextPtr rmesa;
377 struct radeon_framebuffer *rfb;
378 radeonTexObjPtr t;
379 uint32_t pitch_val;
380 uint32_t internalFormat, type, format;
381
382 type = GL_BGRA;
383 format = GL_UNSIGNED_BYTE;
384 internalFormat = (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT ? 3 : 4);
385
386 radeon = pDRICtx->driverPrivate;
387 rmesa = pDRICtx->driverPrivate;
388
389 rfb = dPriv->driverPrivate;
390 texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit];
391 texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target);
392 texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0);
393
394 rImage = get_radeon_texture_image(texImage);
395 t = radeon_tex_obj(texObj);
396 if (t == NULL) {
397 return;
398 }
399
400 radeon_update_renderbuffers(pDRICtx, dPriv);
401 /* back & depth buffer are useless free them right away */
402 rb = (void*)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer;
403 if (rb && rb->bo) {
404 radeon_bo_unref(rb->bo);
405 rb->bo = NULL;
406 }
407 rb = (void*)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
408 if (rb && rb->bo) {
409 radeon_bo_unref(rb->bo);
410 rb->bo = NULL;
411 }
412 rb = rfb->color_rb[0];
413 if (rb->bo == NULL) {
414 /* Failed to BO for the buffer */
415 return;
416 }
417
418 _mesa_lock_texture(radeon->glCtx, texObj);
419 if (t->bo) {
420 radeon_bo_unref(t->bo);
421 t->bo = NULL;
422 }
423 if (rImage->bo) {
424 radeon_bo_unref(rImage->bo);
425 rImage->bo = NULL;
426 }
427 if (t->mt) {
428 radeon_miptree_unreference(t->mt);
429 t->mt = NULL;
430 }
431 if (rImage->mt) {
432 radeon_miptree_unreference(rImage->mt);
433 rImage->mt = NULL;
434 }
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 if (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT)
453 t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
454 else
455 t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8);
456 t->pp_txfilter |= tx_table[2].filter;
457 pitch_val /= 4;
458 break;
459 case 3:
460 default:
461 t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8);
462 t->pp_txfilter |= tx_table[4].filter;
463 pitch_val /= 4;
464 break;
465 case 2:
466 t->pp_txformat = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5);
467 t->pp_txfilter |= tx_table[5].filter;
468 pitch_val /= 2;
469 break;
470 }
471 pitch_val--;
472 t->pp_txsize = ((rb->width - 1) << R300_TX_WIDTHMASK_SHIFT) |
473 ((rb->height - 1) << R300_TX_HEIGHTMASK_SHIFT);
474 t->pp_txsize |= R300_TX_SIZE_TXPITCH_EN;
475 t->pp_txpitch |= pitch_val;
476
477 if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
478 if (rb->width > 2048)
479 t->pp_txpitch |= R500_TXWIDTH_BIT11;
480 if (rb->height > 2048)
481 t->pp_txpitch |= R500_TXHEIGHT_BIT11;
482 }
483 t->validated = GL_TRUE;
484 _mesa_unlock_texture(radeon->glCtx, texObj);
485 return;
486 }
487
488 void r300SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
489 {
490 r300SetTexBuffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv);
491 }