Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/r300/r300_texture.c
4570 views
1
/*
2
* Copyright 2008 Corbin Simpson <[email protected]>
3
* Copyright 2010 Marek Olšák <[email protected]>
4
*
5
* Permission is hereby granted, free of charge, to any person obtaining a
6
* copy of this software and associated documentation files (the "Software"),
7
* to deal in the Software without restriction, including without limitation
8
* on the rights to use, copy, modify, merge, publish, distribute, sub
9
* license, and/or sell copies of the Software, and to permit persons to whom
10
* the Software is furnished to do so, subject to the following conditions:
11
*
12
* The above copyright notice and this permission notice (including the next
13
* paragraph) shall be included in all copies or substantial portions of the
14
* Software.
15
*
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
23
24
/* Always include headers in the reverse order!! ~ M. */
25
#include "r300_texture.h"
26
27
#include "r300_context.h"
28
#include "r300_reg.h"
29
#include "r300_texture_desc.h"
30
#include "r300_transfer.h"
31
#include "r300_screen.h"
32
33
#include "util/format/u_format.h"
34
#include "util/format/u_format_s3tc.h"
35
#include "util/u_math.h"
36
#include "util/u_memory.h"
37
38
#include "pipe/p_screen.h"
39
#include "frontend/winsys_handle.h"
40
41
/* These formats are supported by swapping their bytes.
42
* The swizzles must be set exactly like their non-swapped counterparts,
43
* because byte-swapping is what reverses the component order, not swizzling.
44
*
45
* This function returns the format that must be used to program CB and TX
46
* swizzles.
47
*/
48
static enum pipe_format r300_unbyteswap_array_format(enum pipe_format format)
49
{
50
/* FIXME: Disabled on little endian because of a reported regression:
51
* https://bugs.freedesktop.org/show_bug.cgi?id=98869 */
52
if (PIPE_ENDIAN_NATIVE != PIPE_ENDIAN_BIG)
53
return format;
54
55
/* Only BGRA 8888 array formats are supported for simplicity of
56
* the implementation. */
57
switch (format) {
58
case PIPE_FORMAT_A8R8G8B8_UNORM:
59
return PIPE_FORMAT_B8G8R8A8_UNORM;
60
case PIPE_FORMAT_A8R8G8B8_SRGB:
61
return PIPE_FORMAT_B8G8R8A8_SRGB;
62
case PIPE_FORMAT_X8R8G8B8_UNORM:
63
return PIPE_FORMAT_B8G8R8X8_UNORM;
64
case PIPE_FORMAT_X8R8G8B8_SRGB:
65
return PIPE_FORMAT_B8G8R8X8_SRGB;
66
default:
67
return format;
68
}
69
}
70
71
static unsigned r300_get_endian_swap(enum pipe_format format)
72
{
73
const struct util_format_description *desc;
74
unsigned swap_size;
75
76
if (r300_unbyteswap_array_format(format) != format)
77
return R300_SURF_DWORD_SWAP;
78
79
if (PIPE_ENDIAN_NATIVE != PIPE_ENDIAN_BIG)
80
return R300_SURF_NO_SWAP;
81
82
desc = util_format_description(format);
83
if (!desc)
84
return R300_SURF_NO_SWAP;
85
86
/* Compressed formats should be in the little endian format. */
87
if (desc->block.width != 1 || desc->block.height != 1)
88
return R300_SURF_NO_SWAP;
89
90
swap_size = desc->is_array ? desc->channel[0].size : desc->block.bits;
91
92
switch (swap_size) {
93
default: /* shouldn't happen? */
94
case 8:
95
return R300_SURF_NO_SWAP;
96
case 16:
97
return R300_SURF_WORD_SWAP;
98
case 32:
99
return R300_SURF_DWORD_SWAP;
100
}
101
}
102
103
unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
104
const unsigned char *swizzle_view,
105
boolean dxtc_swizzle)
106
{
107
unsigned i;
108
unsigned char swizzle[4];
109
unsigned result = 0;
110
const uint32_t swizzle_shift[4] = {
111
R300_TX_FORMAT_R_SHIFT,
112
R300_TX_FORMAT_G_SHIFT,
113
R300_TX_FORMAT_B_SHIFT,
114
R300_TX_FORMAT_A_SHIFT
115
};
116
uint32_t swizzle_bit[4] = {
117
dxtc_swizzle ? R300_TX_FORMAT_Z : R300_TX_FORMAT_X,
118
R300_TX_FORMAT_Y,
119
dxtc_swizzle ? R300_TX_FORMAT_X : R300_TX_FORMAT_Z,
120
R300_TX_FORMAT_W
121
};
122
123
if (swizzle_view) {
124
/* Combine two sets of swizzles. */
125
util_format_compose_swizzles(swizzle_format, swizzle_view, swizzle);
126
} else {
127
memcpy(swizzle, swizzle_format, 4);
128
}
129
130
/* Get swizzle. */
131
for (i = 0; i < 4; i++) {
132
switch (swizzle[i]) {
133
case PIPE_SWIZZLE_Y:
134
result |= swizzle_bit[1] << swizzle_shift[i];
135
break;
136
case PIPE_SWIZZLE_Z:
137
result |= swizzle_bit[2] << swizzle_shift[i];
138
break;
139
case PIPE_SWIZZLE_W:
140
result |= swizzle_bit[3] << swizzle_shift[i];
141
break;
142
case PIPE_SWIZZLE_0:
143
result |= R300_TX_FORMAT_ZERO << swizzle_shift[i];
144
break;
145
case PIPE_SWIZZLE_1:
146
result |= R300_TX_FORMAT_ONE << swizzle_shift[i];
147
break;
148
default: /* PIPE_SWIZZLE_X */
149
result |= swizzle_bit[0] << swizzle_shift[i];
150
}
151
}
152
return result;
153
}
154
155
/* Translate a pipe_format into a useful texture format for sampling.
156
*
157
* Some special formats are translated directly using R300_EASY_TX_FORMAT,
158
* but the majority of them is translated in a generic way, automatically
159
* supporting all the formats hw can support.
160
*
161
* R300_EASY_TX_FORMAT swizzles the texture.
162
* Note the signature of R300_EASY_TX_FORMAT:
163
* R300_EASY_TX_FORMAT(B, G, R, A, FORMAT);
164
*
165
* The FORMAT specifies how the texture sampler will treat the texture, and
166
* makes available X, Y, Z, W, ZERO, and ONE for swizzling. */
167
uint32_t r300_translate_texformat(enum pipe_format format,
168
const unsigned char *swizzle_view,
169
boolean is_r500,
170
boolean dxtc_swizzle)
171
{
172
uint32_t result = 0;
173
const struct util_format_description *desc;
174
unsigned i;
175
boolean uniform = TRUE;
176
const uint32_t sign_bit[4] = {
177
R300_TX_FORMAT_SIGNED_W,
178
R300_TX_FORMAT_SIGNED_Z,
179
R300_TX_FORMAT_SIGNED_Y,
180
R300_TX_FORMAT_SIGNED_X,
181
};
182
183
format = r300_unbyteswap_array_format(format);
184
desc = util_format_description(format);
185
186
/* Colorspace (return non-RGB formats directly). */
187
switch (desc->colorspace) {
188
/* Depth stencil formats.
189
* Swizzles are added in r300_merge_textures_and_samplers. */
190
case UTIL_FORMAT_COLORSPACE_ZS:
191
switch (format) {
192
case PIPE_FORMAT_Z16_UNORM:
193
return R300_TX_FORMAT_X16;
194
case PIPE_FORMAT_X8Z24_UNORM:
195
case PIPE_FORMAT_S8_UINT_Z24_UNORM:
196
if (is_r500)
197
return R500_TX_FORMAT_Y8X24;
198
else
199
return R300_TX_FORMAT_Y16X16;
200
default:
201
return ~0; /* Unsupported. */
202
}
203
204
/* YUV formats. */
205
case UTIL_FORMAT_COLORSPACE_YUV:
206
result |= R300_TX_FORMAT_YUV_TO_RGB;
207
208
switch (format) {
209
case PIPE_FORMAT_UYVY:
210
return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result;
211
case PIPE_FORMAT_YUYV:
212
return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result;
213
default:
214
return ~0; /* Unsupported/unknown. */
215
}
216
217
/* Add gamma correction. */
218
case UTIL_FORMAT_COLORSPACE_SRGB:
219
result |= R300_TX_FORMAT_GAMMA;
220
break;
221
222
default:
223
switch (format) {
224
/* Same as YUV but without the YUR->RGB conversion. */
225
case PIPE_FORMAT_R8G8_B8G8_UNORM:
226
return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result;
227
case PIPE_FORMAT_G8R8_G8B8_UNORM:
228
return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result;
229
default:;
230
}
231
}
232
233
/* Add swizzling. */
234
/* The RGTC1_SNORM and LATC1_SNORM swizzle is done in the shader. */
235
if (util_format_is_compressed(format) &&
236
dxtc_swizzle &&
237
format != PIPE_FORMAT_RGTC2_UNORM &&
238
format != PIPE_FORMAT_RGTC2_SNORM &&
239
format != PIPE_FORMAT_LATC2_UNORM &&
240
format != PIPE_FORMAT_LATC2_SNORM &&
241
format != PIPE_FORMAT_RGTC1_UNORM &&
242
format != PIPE_FORMAT_RGTC1_SNORM &&
243
format != PIPE_FORMAT_LATC1_UNORM &&
244
format != PIPE_FORMAT_LATC1_SNORM) {
245
result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view,
246
TRUE);
247
} else {
248
result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view,
249
FALSE);
250
}
251
252
/* S3TC formats. */
253
if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
254
switch (format) {
255
case PIPE_FORMAT_DXT1_RGB:
256
case PIPE_FORMAT_DXT1_RGBA:
257
case PIPE_FORMAT_DXT1_SRGB:
258
case PIPE_FORMAT_DXT1_SRGBA:
259
return R300_TX_FORMAT_DXT1 | result;
260
case PIPE_FORMAT_DXT3_RGBA:
261
case PIPE_FORMAT_DXT3_SRGBA:
262
return R300_TX_FORMAT_DXT3 | result;
263
case PIPE_FORMAT_DXT5_RGBA:
264
case PIPE_FORMAT_DXT5_SRGBA:
265
return R300_TX_FORMAT_DXT5 | result;
266
default:
267
return ~0; /* Unsupported/unknown. */
268
}
269
}
270
271
/* RGTC formats. */
272
if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
273
switch (format) {
274
case PIPE_FORMAT_RGTC1_SNORM:
275
case PIPE_FORMAT_LATC1_SNORM:
276
result |= sign_bit[0];
277
FALLTHROUGH;
278
case PIPE_FORMAT_LATC1_UNORM:
279
case PIPE_FORMAT_RGTC1_UNORM:
280
return R500_TX_FORMAT_ATI1N | result;
281
282
case PIPE_FORMAT_RGTC2_SNORM:
283
case PIPE_FORMAT_LATC2_SNORM:
284
result |= sign_bit[1] | sign_bit[0];
285
FALLTHROUGH;
286
case PIPE_FORMAT_RGTC2_UNORM:
287
case PIPE_FORMAT_LATC2_UNORM:
288
return R400_TX_FORMAT_ATI2N | result;
289
290
default:
291
return ~0; /* Unsupported/unknown. */
292
}
293
}
294
295
/* This is truly a special format.
296
* It stores R8G8 and B is computed using sqrt(1 - R^2 - G^2)
297
* in the sampler unit. Also known as D3DFMT_CxV8U8. */
298
if (format == PIPE_FORMAT_R8G8Bx_SNORM) {
299
return R300_TX_FORMAT_CxV8U8 | result;
300
}
301
302
/* Integer and fixed-point 16.16 textures are not supported. */
303
for (i = 0; i < 4; i++) {
304
if (desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED ||
305
((desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED ||
306
desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED) &&
307
(!desc->channel[i].normalized ||
308
desc->channel[i].pure_integer))) {
309
return ~0; /* Unsupported/unknown. */
310
}
311
}
312
313
/* Add sign. */
314
for (i = 0; i < desc->nr_channels; i++) {
315
if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
316
result |= sign_bit[i];
317
}
318
}
319
320
/* See whether the components are of the same size. */
321
for (i = 1; i < desc->nr_channels; i++) {
322
uniform = uniform && desc->channel[0].size == desc->channel[i].size;
323
}
324
325
/* Non-uniform formats. */
326
if (!uniform) {
327
switch (desc->nr_channels) {
328
case 3:
329
if (desc->channel[0].size == 5 &&
330
desc->channel[1].size == 6 &&
331
desc->channel[2].size == 5) {
332
return R300_TX_FORMAT_Z5Y6X5 | result;
333
}
334
if (desc->channel[0].size == 5 &&
335
desc->channel[1].size == 5 &&
336
desc->channel[2].size == 6) {
337
return R300_TX_FORMAT_Z6Y5X5 | result;
338
}
339
if (desc->channel[0].size == 2 &&
340
desc->channel[1].size == 3 &&
341
desc->channel[2].size == 3) {
342
return R300_TX_FORMAT_Z3Y3X2 | result;
343
}
344
return ~0; /* Unsupported/unknown. */
345
346
case 4:
347
if (desc->channel[0].size == 5 &&
348
desc->channel[1].size == 5 &&
349
desc->channel[2].size == 5 &&
350
desc->channel[3].size == 1) {
351
return R300_TX_FORMAT_W1Z5Y5X5 | result;
352
}
353
if (desc->channel[0].size == 10 &&
354
desc->channel[1].size == 10 &&
355
desc->channel[2].size == 10 &&
356
desc->channel[3].size == 2) {
357
return R300_TX_FORMAT_W2Z10Y10X10 | result;
358
}
359
}
360
return ~0; /* Unsupported/unknown. */
361
}
362
363
/* Find the first non-VOID channel. */
364
for (i = 0; i < 4; i++) {
365
if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
366
break;
367
}
368
}
369
370
if (i == 4)
371
return ~0; /* Unsupported/unknown. */
372
373
/* And finally, uniform formats. */
374
switch (desc->channel[i].type) {
375
case UTIL_FORMAT_TYPE_UNSIGNED:
376
case UTIL_FORMAT_TYPE_SIGNED:
377
if (!desc->channel[i].normalized &&
378
desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
379
return ~0;
380
}
381
382
switch (desc->channel[i].size) {
383
case 4:
384
switch (desc->nr_channels) {
385
case 2:
386
return R300_TX_FORMAT_Y4X4 | result;
387
case 4:
388
return R300_TX_FORMAT_W4Z4Y4X4 | result;
389
}
390
return ~0;
391
392
case 8:
393
switch (desc->nr_channels) {
394
case 1:
395
return R300_TX_FORMAT_X8 | result;
396
case 2:
397
return R300_TX_FORMAT_Y8X8 | result;
398
case 4:
399
return R300_TX_FORMAT_W8Z8Y8X8 | result;
400
}
401
return ~0;
402
403
case 16:
404
switch (desc->nr_channels) {
405
case 1:
406
return R300_TX_FORMAT_X16 | result;
407
case 2:
408
return R300_TX_FORMAT_Y16X16 | result;
409
case 4:
410
return R300_TX_FORMAT_W16Z16Y16X16 | result;
411
}
412
}
413
return ~0;
414
415
case UTIL_FORMAT_TYPE_FLOAT:
416
switch (desc->channel[i].size) {
417
case 16:
418
switch (desc->nr_channels) {
419
case 1:
420
return R300_TX_FORMAT_16F | result;
421
case 2:
422
return R300_TX_FORMAT_16F_16F | result;
423
case 4:
424
return R300_TX_FORMAT_16F_16F_16F_16F | result;
425
}
426
return ~0;
427
428
case 32:
429
switch (desc->nr_channels) {
430
case 1:
431
return R300_TX_FORMAT_32F | result;
432
case 2:
433
return R300_TX_FORMAT_32F_32F | result;
434
case 4:
435
return R300_TX_FORMAT_32F_32F_32F_32F | result;
436
}
437
}
438
}
439
440
return ~0; /* Unsupported/unknown. */
441
}
442
443
uint32_t r500_tx_format_msb_bit(enum pipe_format format)
444
{
445
switch (format) {
446
case PIPE_FORMAT_RGTC1_UNORM:
447
case PIPE_FORMAT_RGTC1_SNORM:
448
case PIPE_FORMAT_LATC1_UNORM:
449
case PIPE_FORMAT_LATC1_SNORM:
450
case PIPE_FORMAT_X8Z24_UNORM:
451
case PIPE_FORMAT_S8_UINT_Z24_UNORM:
452
return R500_TXFORMAT_MSB;
453
default:
454
return 0;
455
}
456
}
457
458
/* Buffer formats. */
459
460
/* Colorbuffer formats. This is the unswizzled format of the RB3D block's
461
* output. For the swizzling of the targets, check the shader's format. */
462
static uint32_t r300_translate_colorformat(enum pipe_format format)
463
{
464
format = r300_unbyteswap_array_format(format);
465
466
switch (format) {
467
/* 8-bit buffers. */
468
case PIPE_FORMAT_A8_UNORM:
469
case PIPE_FORMAT_A8_SNORM:
470
case PIPE_FORMAT_I8_UNORM:
471
case PIPE_FORMAT_I8_SNORM:
472
case PIPE_FORMAT_L8_UNORM:
473
case PIPE_FORMAT_L8_SNORM:
474
case PIPE_FORMAT_R8_UNORM:
475
case PIPE_FORMAT_R8_SNORM:
476
return R300_COLOR_FORMAT_I8;
477
478
/* 16-bit buffers. */
479
case PIPE_FORMAT_L8A8_UNORM:
480
case PIPE_FORMAT_L8A8_SNORM:
481
case PIPE_FORMAT_R8G8_UNORM:
482
case PIPE_FORMAT_R8G8_SNORM:
483
case PIPE_FORMAT_R8A8_UNORM:
484
case PIPE_FORMAT_R8A8_SNORM:
485
/* These formats work fine with UV88 if US_OUT_FMT is set correctly. */
486
case PIPE_FORMAT_A16_UNORM:
487
case PIPE_FORMAT_A16_SNORM:
488
case PIPE_FORMAT_A16_FLOAT:
489
case PIPE_FORMAT_L16_UNORM:
490
case PIPE_FORMAT_L16_SNORM:
491
case PIPE_FORMAT_L16_FLOAT:
492
case PIPE_FORMAT_I16_UNORM:
493
case PIPE_FORMAT_I16_SNORM:
494
case PIPE_FORMAT_I16_FLOAT:
495
case PIPE_FORMAT_R16_UNORM:
496
case PIPE_FORMAT_R16_SNORM:
497
case PIPE_FORMAT_R16_FLOAT:
498
return R300_COLOR_FORMAT_UV88;
499
500
case PIPE_FORMAT_B5G6R5_UNORM:
501
return R300_COLOR_FORMAT_RGB565;
502
503
case PIPE_FORMAT_B5G5R5A1_UNORM:
504
case PIPE_FORMAT_B5G5R5X1_UNORM:
505
return R300_COLOR_FORMAT_ARGB1555;
506
507
case PIPE_FORMAT_B4G4R4A4_UNORM:
508
case PIPE_FORMAT_B4G4R4X4_UNORM:
509
return R300_COLOR_FORMAT_ARGB4444;
510
511
/* 32-bit buffers. */
512
case PIPE_FORMAT_B8G8R8A8_UNORM:
513
/*case PIPE_FORMAT_B8G8R8A8_SNORM:*/
514
case PIPE_FORMAT_B8G8R8X8_UNORM:
515
/*case PIPE_FORMAT_B8G8R8X8_SNORM:*/
516
case PIPE_FORMAT_R8G8B8A8_UNORM:
517
case PIPE_FORMAT_R8G8B8A8_SNORM:
518
case PIPE_FORMAT_R8G8B8X8_UNORM:
519
case PIPE_FORMAT_R8G8B8X8_SNORM:
520
/* These formats work fine with ARGB8888 if US_OUT_FMT is set
521
* correctly. */
522
case PIPE_FORMAT_R16G16_UNORM:
523
case PIPE_FORMAT_R16G16_SNORM:
524
case PIPE_FORMAT_R16G16_FLOAT:
525
case PIPE_FORMAT_L16A16_UNORM:
526
case PIPE_FORMAT_L16A16_SNORM:
527
case PIPE_FORMAT_L16A16_FLOAT:
528
case PIPE_FORMAT_R16A16_UNORM:
529
case PIPE_FORMAT_R16A16_SNORM:
530
case PIPE_FORMAT_R16A16_FLOAT:
531
case PIPE_FORMAT_A32_FLOAT:
532
case PIPE_FORMAT_L32_FLOAT:
533
case PIPE_FORMAT_I32_FLOAT:
534
case PIPE_FORMAT_R32_FLOAT:
535
return R300_COLOR_FORMAT_ARGB8888;
536
537
case PIPE_FORMAT_R10G10B10A2_UNORM:
538
case PIPE_FORMAT_R10G10B10X2_SNORM:
539
case PIPE_FORMAT_B10G10R10A2_UNORM:
540
case PIPE_FORMAT_B10G10R10X2_UNORM:
541
return R500_COLOR_FORMAT_ARGB2101010; /* R5xx-only? */
542
543
/* 64-bit buffers. */
544
case PIPE_FORMAT_R16G16B16A16_UNORM:
545
case PIPE_FORMAT_R16G16B16A16_SNORM:
546
case PIPE_FORMAT_R16G16B16A16_FLOAT:
547
case PIPE_FORMAT_R16G16B16X16_UNORM:
548
case PIPE_FORMAT_R16G16B16X16_SNORM:
549
case PIPE_FORMAT_R16G16B16X16_FLOAT:
550
/* These formats work fine with ARGB16161616 if US_OUT_FMT is set
551
* correctly. */
552
case PIPE_FORMAT_R32G32_FLOAT:
553
case PIPE_FORMAT_L32A32_FLOAT:
554
case PIPE_FORMAT_R32A32_FLOAT:
555
return R300_COLOR_FORMAT_ARGB16161616;
556
557
/* 128-bit buffers. */
558
case PIPE_FORMAT_R32G32B32A32_FLOAT:
559
case PIPE_FORMAT_R32G32B32X32_FLOAT:
560
return R300_COLOR_FORMAT_ARGB32323232;
561
562
/* YUV buffers. */
563
case PIPE_FORMAT_UYVY:
564
return R300_COLOR_FORMAT_YVYU;
565
case PIPE_FORMAT_YUYV:
566
return R300_COLOR_FORMAT_VYUY;
567
default:
568
return ~0; /* Unsupported. */
569
}
570
}
571
572
/* Depthbuffer and stencilbuffer. Thankfully, we only support two flavors. */
573
static uint32_t r300_translate_zsformat(enum pipe_format format)
574
{
575
switch (format) {
576
/* 16-bit depth, no stencil */
577
case PIPE_FORMAT_Z16_UNORM:
578
return R300_DEPTHFORMAT_16BIT_INT_Z;
579
/* 24-bit depth, ignored stencil */
580
case PIPE_FORMAT_X8Z24_UNORM:
581
/* 24-bit depth, 8-bit stencil */
582
case PIPE_FORMAT_S8_UINT_Z24_UNORM:
583
return R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
584
default:
585
return ~0; /* Unsupported. */
586
}
587
}
588
589
/* Shader output formats. This is essentially the swizzle from the shader
590
* to the RB3D block.
591
*
592
* Note that formats are stored from C3 to C0. */
593
static uint32_t r300_translate_out_fmt(enum pipe_format format)
594
{
595
uint32_t modifier = 0;
596
unsigned i;
597
const struct util_format_description *desc;
598
boolean uniform_sign;
599
600
format = r300_unbyteswap_array_format(format);
601
desc = util_format_description(format);
602
603
/* Find the first non-VOID channel. */
604
for (i = 0; i < 4; i++) {
605
if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
606
break;
607
}
608
}
609
610
if (i == 4)
611
return ~0; /* Unsupported/unknown. */
612
613
/* Specifies how the shader output is written to the fog unit. */
614
switch (desc->channel[i].type) {
615
case UTIL_FORMAT_TYPE_FLOAT:
616
switch (desc->channel[i].size) {
617
case 32:
618
switch (desc->nr_channels) {
619
case 1:
620
modifier |= R300_US_OUT_FMT_C_32_FP;
621
break;
622
case 2:
623
modifier |= R300_US_OUT_FMT_C2_32_FP;
624
break;
625
case 4:
626
modifier |= R300_US_OUT_FMT_C4_32_FP;
627
break;
628
}
629
break;
630
631
case 16:
632
switch (desc->nr_channels) {
633
case 1:
634
modifier |= R300_US_OUT_FMT_C_16_FP;
635
break;
636
case 2:
637
modifier |= R300_US_OUT_FMT_C2_16_FP;
638
break;
639
case 4:
640
modifier |= R300_US_OUT_FMT_C4_16_FP;
641
break;
642
}
643
break;
644
}
645
break;
646
647
default:
648
switch (desc->channel[i].size) {
649
case 16:
650
switch (desc->nr_channels) {
651
case 1:
652
modifier |= R300_US_OUT_FMT_C_16;
653
break;
654
case 2:
655
modifier |= R300_US_OUT_FMT_C2_16;
656
break;
657
case 4:
658
modifier |= R300_US_OUT_FMT_C4_16;
659
break;
660
}
661
break;
662
663
case 10:
664
modifier |= R300_US_OUT_FMT_C4_10;
665
break;
666
667
default:
668
/* C4_8 seems to be used for the formats whose pixel size
669
* is <= 32 bits. */
670
modifier |= R300_US_OUT_FMT_C4_8;
671
break;
672
}
673
}
674
675
/* Add sign. */
676
uniform_sign = TRUE;
677
for (i = 0; i < desc->nr_channels; i++)
678
if (desc->channel[i].type != UTIL_FORMAT_TYPE_SIGNED)
679
uniform_sign = FALSE;
680
681
if (uniform_sign)
682
modifier |= R300_OUT_SIGN(0xf);
683
684
/* Add swizzles and return. */
685
switch (format) {
686
/*** Special cases (non-standard channel mapping) ***/
687
688
/* X8
689
* COLORFORMAT_I8 stores the Z component (C2). */
690
case PIPE_FORMAT_A8_UNORM:
691
case PIPE_FORMAT_A8_SNORM:
692
return modifier | R300_C2_SEL_A;
693
case PIPE_FORMAT_I8_UNORM:
694
case PIPE_FORMAT_I8_SNORM:
695
case PIPE_FORMAT_L8_UNORM:
696
case PIPE_FORMAT_L8_SNORM:
697
case PIPE_FORMAT_R8_UNORM:
698
case PIPE_FORMAT_R8_SNORM:
699
return modifier | R300_C2_SEL_R;
700
701
/* X8Y8
702
* COLORFORMAT_UV88 stores ZX (C2 and C0). */
703
case PIPE_FORMAT_L8A8_SNORM:
704
case PIPE_FORMAT_L8A8_UNORM:
705
case PIPE_FORMAT_R8A8_SNORM:
706
case PIPE_FORMAT_R8A8_UNORM:
707
return modifier | R300_C0_SEL_A | R300_C2_SEL_R;
708
case PIPE_FORMAT_R8G8_SNORM:
709
case PIPE_FORMAT_R8G8_UNORM:
710
return modifier | R300_C0_SEL_G | R300_C2_SEL_R;
711
712
/* X32Y32
713
* ARGB16161616 stores XZ for RG32F */
714
case PIPE_FORMAT_R32G32_FLOAT:
715
return modifier | R300_C0_SEL_R | R300_C2_SEL_G;
716
717
/*** Generic cases (standard channel mapping) ***/
718
719
/* BGRA outputs. */
720
case PIPE_FORMAT_B5G6R5_UNORM:
721
case PIPE_FORMAT_B5G5R5A1_UNORM:
722
case PIPE_FORMAT_B5G5R5X1_UNORM:
723
case PIPE_FORMAT_B4G4R4A4_UNORM:
724
case PIPE_FORMAT_B4G4R4X4_UNORM:
725
case PIPE_FORMAT_B8G8R8A8_UNORM:
726
/*case PIPE_FORMAT_B8G8R8A8_SNORM:*/
727
case PIPE_FORMAT_B8G8R8X8_UNORM:
728
/*case PIPE_FORMAT_B8G8R8X8_SNORM:*/
729
case PIPE_FORMAT_B10G10R10A2_UNORM:
730
case PIPE_FORMAT_B10G10R10X2_UNORM:
731
return modifier |
732
R300_C0_SEL_B | R300_C1_SEL_G |
733
R300_C2_SEL_R | R300_C3_SEL_A;
734
735
/* ARGB outputs. */
736
case PIPE_FORMAT_A16_UNORM:
737
case PIPE_FORMAT_A16_SNORM:
738
case PIPE_FORMAT_A16_FLOAT:
739
case PIPE_FORMAT_A32_FLOAT:
740
return modifier |
741
R300_C0_SEL_A | R300_C1_SEL_R |
742
R300_C2_SEL_G | R300_C3_SEL_B;
743
744
/* RGBA outputs. */
745
case PIPE_FORMAT_R8G8B8X8_UNORM:
746
case PIPE_FORMAT_R8G8B8X8_SNORM:
747
case PIPE_FORMAT_R8G8B8A8_UNORM:
748
case PIPE_FORMAT_R8G8B8A8_SNORM:
749
case PIPE_FORMAT_R10G10B10A2_UNORM:
750
case PIPE_FORMAT_R10G10B10X2_SNORM:
751
case PIPE_FORMAT_R16_UNORM:
752
case PIPE_FORMAT_R16G16_UNORM:
753
case PIPE_FORMAT_R16G16B16A16_UNORM:
754
case PIPE_FORMAT_R16_SNORM:
755
case PIPE_FORMAT_R16G16_SNORM:
756
case PIPE_FORMAT_R16G16B16A16_SNORM:
757
case PIPE_FORMAT_R16_FLOAT:
758
case PIPE_FORMAT_R16G16_FLOAT:
759
case PIPE_FORMAT_R16G16B16A16_FLOAT:
760
case PIPE_FORMAT_R32_FLOAT:
761
case PIPE_FORMAT_R32G32B32A32_FLOAT:
762
case PIPE_FORMAT_R32G32B32X32_FLOAT:
763
case PIPE_FORMAT_L16_UNORM:
764
case PIPE_FORMAT_L16_SNORM:
765
case PIPE_FORMAT_L16_FLOAT:
766
case PIPE_FORMAT_L32_FLOAT:
767
case PIPE_FORMAT_I16_UNORM:
768
case PIPE_FORMAT_I16_SNORM:
769
case PIPE_FORMAT_I16_FLOAT:
770
case PIPE_FORMAT_I32_FLOAT:
771
case PIPE_FORMAT_R16G16B16X16_UNORM:
772
case PIPE_FORMAT_R16G16B16X16_SNORM:
773
case PIPE_FORMAT_R16G16B16X16_FLOAT:
774
return modifier |
775
R300_C0_SEL_R | R300_C1_SEL_G |
776
R300_C2_SEL_B | R300_C3_SEL_A;
777
778
/* LA outputs. */
779
case PIPE_FORMAT_L16A16_UNORM:
780
case PIPE_FORMAT_L16A16_SNORM:
781
case PIPE_FORMAT_L16A16_FLOAT:
782
case PIPE_FORMAT_R16A16_UNORM:
783
case PIPE_FORMAT_R16A16_SNORM:
784
case PIPE_FORMAT_R16A16_FLOAT:
785
case PIPE_FORMAT_L32A32_FLOAT:
786
case PIPE_FORMAT_R32A32_FLOAT:
787
return modifier |
788
R300_C0_SEL_R | R300_C1_SEL_A;
789
790
default:
791
return ~0; /* Unsupported. */
792
}
793
}
794
795
static uint32_t r300_translate_colormask_swizzle(enum pipe_format format)
796
{
797
format = r300_unbyteswap_array_format(format);
798
799
switch (format) {
800
case PIPE_FORMAT_A8_UNORM:
801
case PIPE_FORMAT_A8_SNORM:
802
case PIPE_FORMAT_A16_UNORM:
803
case PIPE_FORMAT_A16_SNORM:
804
case PIPE_FORMAT_A16_FLOAT:
805
case PIPE_FORMAT_A32_FLOAT:
806
return COLORMASK_AAAA;
807
808
case PIPE_FORMAT_I8_UNORM:
809
case PIPE_FORMAT_I8_SNORM:
810
case PIPE_FORMAT_L8_UNORM:
811
case PIPE_FORMAT_L8_SNORM:
812
case PIPE_FORMAT_R8_UNORM:
813
case PIPE_FORMAT_R8_SNORM:
814
case PIPE_FORMAT_R32_FLOAT:
815
case PIPE_FORMAT_L32_FLOAT:
816
case PIPE_FORMAT_I32_FLOAT:
817
return COLORMASK_RRRR;
818
819
case PIPE_FORMAT_L8A8_SNORM:
820
case PIPE_FORMAT_L8A8_UNORM:
821
case PIPE_FORMAT_R8A8_UNORM:
822
case PIPE_FORMAT_R8A8_SNORM:
823
case PIPE_FORMAT_L16A16_UNORM:
824
case PIPE_FORMAT_L16A16_SNORM:
825
case PIPE_FORMAT_L16A16_FLOAT:
826
case PIPE_FORMAT_R16A16_UNORM:
827
case PIPE_FORMAT_R16A16_SNORM:
828
case PIPE_FORMAT_R16A16_FLOAT:
829
case PIPE_FORMAT_L32A32_FLOAT:
830
case PIPE_FORMAT_R32A32_FLOAT:
831
return COLORMASK_ARRA;
832
833
case PIPE_FORMAT_R8G8_SNORM:
834
case PIPE_FORMAT_R8G8_UNORM:
835
case PIPE_FORMAT_R16G16_UNORM:
836
case PIPE_FORMAT_R16G16_SNORM:
837
case PIPE_FORMAT_R16G16_FLOAT:
838
case PIPE_FORMAT_R32G32_FLOAT:
839
return COLORMASK_GRRG;
840
841
case PIPE_FORMAT_B5G5R5X1_UNORM:
842
case PIPE_FORMAT_B4G4R4X4_UNORM:
843
case PIPE_FORMAT_B8G8R8X8_UNORM:
844
/*case PIPE_FORMAT_B8G8R8X8_SNORM:*/
845
case PIPE_FORMAT_B10G10R10X2_UNORM:
846
return COLORMASK_BGRX;
847
848
case PIPE_FORMAT_B5G6R5_UNORM:
849
case PIPE_FORMAT_B5G5R5A1_UNORM:
850
case PIPE_FORMAT_B4G4R4A4_UNORM:
851
case PIPE_FORMAT_B8G8R8A8_UNORM:
852
/*case PIPE_FORMAT_B8G8R8A8_SNORM:*/
853
case PIPE_FORMAT_B10G10R10A2_UNORM:
854
return COLORMASK_BGRA;
855
856
case PIPE_FORMAT_R8G8B8X8_UNORM:
857
/* RGBX_SNORM formats are broken for an unknown reason */
858
/*case PIPE_FORMAT_R8G8B8X8_SNORM:*/
859
/*case PIPE_FORMAT_R10G10B10X2_SNORM:*/
860
case PIPE_FORMAT_R16G16B16X16_UNORM:
861
/*case PIPE_FORMAT_R16G16B16X16_SNORM:*/
862
case PIPE_FORMAT_R16G16B16X16_FLOAT:
863
case PIPE_FORMAT_R32G32B32X32_FLOAT:
864
return COLORMASK_RGBX;
865
866
case PIPE_FORMAT_R8G8B8A8_UNORM:
867
case PIPE_FORMAT_R8G8B8A8_SNORM:
868
case PIPE_FORMAT_R10G10B10A2_UNORM:
869
case PIPE_FORMAT_R16_UNORM:
870
case PIPE_FORMAT_R16G16B16A16_UNORM:
871
case PIPE_FORMAT_R16_SNORM:
872
case PIPE_FORMAT_R16G16B16A16_SNORM:
873
case PIPE_FORMAT_R16_FLOAT:
874
case PIPE_FORMAT_R16G16B16A16_FLOAT:
875
case PIPE_FORMAT_R32G32B32A32_FLOAT:
876
case PIPE_FORMAT_L16_UNORM:
877
case PIPE_FORMAT_L16_SNORM:
878
case PIPE_FORMAT_L16_FLOAT:
879
case PIPE_FORMAT_I16_UNORM:
880
case PIPE_FORMAT_I16_SNORM:
881
case PIPE_FORMAT_I16_FLOAT:
882
return COLORMASK_RGBA;
883
884
default:
885
return ~0; /* Unsupported. */
886
}
887
}
888
889
boolean r300_is_colorbuffer_format_supported(enum pipe_format format)
890
{
891
return r300_translate_colorformat(format) != ~0 &&
892
r300_translate_out_fmt(format) != ~0 &&
893
r300_translate_colormask_swizzle(format) != ~0;
894
}
895
896
boolean r300_is_zs_format_supported(enum pipe_format format)
897
{
898
return r300_translate_zsformat(format) != ~0;
899
}
900
901
boolean r300_is_sampler_format_supported(enum pipe_format format)
902
{
903
return r300_translate_texformat(format, 0, TRUE, FALSE) != ~0;
904
}
905
906
void r300_texture_setup_format_state(struct r300_screen *screen,
907
struct r300_resource *tex,
908
enum pipe_format format,
909
unsigned level,
910
unsigned width0_override,
911
unsigned height0_override,
912
struct r300_texture_format_state *out)
913
{
914
struct pipe_resource *pt = &tex->b;
915
struct r300_texture_desc *desc = &tex->tex;
916
boolean is_r500 = screen->caps.is_r500;
917
unsigned width, height, depth;
918
unsigned txwidth, txheight, txdepth;
919
920
width = u_minify(width0_override, level);
921
height = u_minify(height0_override, level);
922
depth = u_minify(desc->depth0, level);
923
924
txwidth = (width - 1) & 0x7ff;
925
txheight = (height - 1) & 0x7ff;
926
txdepth = util_logbase2(depth) & 0xf;
927
928
/* Mask out all the fields we change. */
929
out->format0 = 0;
930
out->format1 &= ~R300_TX_FORMAT_TEX_COORD_TYPE_MASK;
931
out->format2 &= R500_TXFORMAT_MSB;
932
out->tile_config = 0;
933
934
/* Set sampler state. */
935
out->format0 =
936
R300_TX_WIDTH(txwidth) |
937
R300_TX_HEIGHT(txheight) |
938
R300_TX_DEPTH(txdepth);
939
940
if (desc->uses_stride_addressing) {
941
unsigned stride =
942
r300_stride_to_width(format, desc->stride_in_bytes[level]);
943
/* rectangles love this */
944
out->format0 |= R300_TX_PITCH_EN;
945
out->format2 = (stride - 1) & 0x1fff;
946
}
947
948
if (pt->target == PIPE_TEXTURE_CUBE) {
949
out->format1 |= R300_TX_FORMAT_CUBIC_MAP;
950
}
951
if (pt->target == PIPE_TEXTURE_3D) {
952
out->format1 |= R300_TX_FORMAT_3D;
953
}
954
955
/* large textures on r500 */
956
if (is_r500)
957
{
958
unsigned us_width = txwidth;
959
unsigned us_height = txheight;
960
unsigned us_depth = txdepth;
961
962
if (width > 2048) {
963
out->format2 |= R500_TXWIDTH_BIT11;
964
}
965
if (height > 2048) {
966
out->format2 |= R500_TXHEIGHT_BIT11;
967
}
968
969
/* The US_FORMAT register fixes an R500 TX addressing bug.
970
* Don't ask why it must be set like this. I don't know it either. */
971
if (width > 2048) {
972
us_width = (0x000007FF + us_width) >> 1;
973
us_depth |= 0x0000000D;
974
}
975
if (height > 2048) {
976
us_height = (0x000007FF + us_height) >> 1;
977
us_depth |= 0x0000000E;
978
}
979
980
out->us_format0 =
981
R300_TX_WIDTH(us_width) |
982
R300_TX_HEIGHT(us_height) |
983
R300_TX_DEPTH(us_depth);
984
}
985
986
out->tile_config = R300_TXO_MACRO_TILE(desc->macrotile[level]) |
987
R300_TXO_MICRO_TILE(desc->microtile) |
988
R300_TXO_ENDIAN(r300_get_endian_swap(format));
989
}
990
991
static void r300_texture_setup_fb_state(struct r300_surface *surf)
992
{
993
struct r300_resource *tex = r300_resource(surf->base.texture);
994
unsigned level = surf->base.u.tex.level;
995
unsigned stride =
996
r300_stride_to_width(surf->base.format, tex->tex.stride_in_bytes[level]);
997
998
/* Set framebuffer state. */
999
if (util_format_is_depth_or_stencil(surf->base.format)) {
1000
surf->pitch =
1001
stride |
1002
R300_DEPTHMACROTILE(tex->tex.macrotile[level]) |
1003
R300_DEPTHMICROTILE(tex->tex.microtile) |
1004
R300_DEPTHENDIAN(r300_get_endian_swap(surf->base.format));
1005
surf->format = r300_translate_zsformat(surf->base.format);
1006
surf->pitch_zmask = tex->tex.zmask_stride_in_pixels[level];
1007
surf->pitch_hiz = tex->tex.hiz_stride_in_pixels[level];
1008
} else {
1009
enum pipe_format format = util_format_linear(surf->base.format);
1010
1011
surf->pitch =
1012
stride |
1013
r300_translate_colorformat(format) |
1014
R300_COLOR_TILE(tex->tex.macrotile[level]) |
1015
R300_COLOR_MICROTILE(tex->tex.microtile) |
1016
R300_COLOR_ENDIAN(r300_get_endian_swap(format));
1017
surf->format = r300_translate_out_fmt(format);
1018
surf->colormask_swizzle =
1019
r300_translate_colormask_swizzle(format);
1020
surf->pitch_cmask = tex->tex.cmask_stride_in_pixels;
1021
}
1022
}
1023
1024
bool r300_resource_get_handle(struct pipe_screen* screen,
1025
struct pipe_context *ctx,
1026
struct pipe_resource *texture,
1027
struct winsys_handle *whandle,
1028
unsigned usage)
1029
{
1030
struct radeon_winsys *rws = r300_screen(screen)->rws;
1031
struct r300_resource* tex = (struct r300_resource*)texture;
1032
1033
if (!tex) {
1034
return false;
1035
}
1036
1037
whandle->stride = tex->tex.stride_in_bytes[0];
1038
whandle->offset = 0;
1039
1040
return rws->buffer_get_handle(rws, tex->buf, whandle);
1041
}
1042
1043
/* The common texture constructor. */
1044
static struct r300_resource*
1045
r300_texture_create_object(struct r300_screen *rscreen,
1046
const struct pipe_resource *base,
1047
enum radeon_bo_layout microtile,
1048
enum radeon_bo_layout macrotile,
1049
unsigned stride_in_bytes_override,
1050
struct pb_buffer *buffer)
1051
{
1052
struct radeon_winsys *rws = rscreen->rws;
1053
struct r300_resource *tex = NULL;
1054
struct radeon_bo_metadata tiling = {};
1055
1056
tex = CALLOC_STRUCT(r300_resource);
1057
if (!tex) {
1058
goto fail;
1059
}
1060
1061
pipe_reference_init(&tex->b.reference, 1);
1062
tex->b.screen = &rscreen->screen;
1063
tex->b.usage = base->usage;
1064
tex->b.bind = base->bind;
1065
tex->b.flags = base->flags;
1066
tex->tex.microtile = microtile;
1067
tex->tex.macrotile[0] = macrotile;
1068
tex->tex.stride_in_bytes_override = stride_in_bytes_override;
1069
tex->domain = (base->flags & R300_RESOURCE_FLAG_TRANSFER ||
1070
base->usage == PIPE_USAGE_STAGING) ? RADEON_DOMAIN_GTT :
1071
base->nr_samples > 1 ? RADEON_DOMAIN_VRAM :
1072
RADEON_DOMAIN_VRAM | RADEON_DOMAIN_GTT;
1073
tex->buf = buffer;
1074
1075
r300_texture_desc_init(rscreen, tex, base);
1076
1077
/* Figure out the ideal placement for the texture.. */
1078
if (tex->domain & RADEON_DOMAIN_VRAM &&
1079
tex->tex.size_in_bytes >= rscreen->info.vram_size) {
1080
tex->domain &= ~RADEON_DOMAIN_VRAM;
1081
tex->domain |= RADEON_DOMAIN_GTT;
1082
}
1083
if (tex->domain & RADEON_DOMAIN_GTT &&
1084
tex->tex.size_in_bytes >= rscreen->info.gart_size) {
1085
tex->domain &= ~RADEON_DOMAIN_GTT;
1086
}
1087
/* Just fail if the texture is too large. */
1088
if (!tex->domain) {
1089
goto fail;
1090
}
1091
1092
/* Create the backing buffer if needed. */
1093
if (!tex->buf) {
1094
/* Only use the first domain for allocation. Multiple domains are not allowed. */
1095
unsigned alloc_domain =
1096
tex->domain & RADEON_DOMAIN_VRAM ? RADEON_DOMAIN_VRAM :
1097
RADEON_DOMAIN_GTT;
1098
1099
tex->buf = rws->buffer_create(rws, tex->tex.size_in_bytes, 2048,
1100
alloc_domain,
1101
RADEON_FLAG_NO_SUBALLOC |
1102
/* Use the reusable pool: */
1103
RADEON_FLAG_NO_INTERPROCESS_SHARING);
1104
1105
if (!tex->buf) {
1106
goto fail;
1107
}
1108
}
1109
1110
if (SCREEN_DBG_ON(rscreen, DBG_MSAA) && base->nr_samples > 1) {
1111
fprintf(stderr, "r300: %ix MSAA %s buffer created\n",
1112
base->nr_samples,
1113
util_format_is_depth_or_stencil(base->format) ? "depth" : "color");
1114
}
1115
1116
tiling.u.legacy.microtile = tex->tex.microtile;
1117
tiling.u.legacy.macrotile = tex->tex.macrotile[0];
1118
tiling.u.legacy.stride = tex->tex.stride_in_bytes[0];
1119
rws->buffer_set_metadata(rws, tex->buf, &tiling, NULL);
1120
1121
return tex;
1122
1123
fail:
1124
FREE(tex);
1125
if (buffer)
1126
pb_reference(&buffer, NULL);
1127
return NULL;
1128
}
1129
1130
/* Create a new texture. */
1131
struct pipe_resource *r300_texture_create(struct pipe_screen *screen,
1132
const struct pipe_resource *base)
1133
{
1134
struct r300_screen *rscreen = r300_screen(screen);
1135
enum radeon_bo_layout microtile, macrotile;
1136
1137
if ((base->flags & R300_RESOURCE_FLAG_TRANSFER) ||
1138
(base->bind & (PIPE_BIND_SCANOUT | PIPE_BIND_LINEAR))) {
1139
microtile = RADEON_LAYOUT_LINEAR;
1140
macrotile = RADEON_LAYOUT_LINEAR;
1141
} else {
1142
/* This will make the texture_create_function select the layout. */
1143
microtile = RADEON_LAYOUT_UNKNOWN;
1144
macrotile = RADEON_LAYOUT_UNKNOWN;
1145
}
1146
1147
return (struct pipe_resource*)
1148
r300_texture_create_object(rscreen, base, microtile, macrotile,
1149
0, NULL);
1150
}
1151
1152
struct pipe_resource *r300_texture_from_handle(struct pipe_screen *screen,
1153
const struct pipe_resource *base,
1154
struct winsys_handle *whandle,
1155
unsigned usage)
1156
{
1157
struct r300_screen *rscreen = r300_screen(screen);
1158
struct radeon_winsys *rws = rscreen->rws;
1159
struct pb_buffer *buffer;
1160
struct radeon_bo_metadata tiling = {};
1161
1162
/* Support only 2D textures without mipmaps */
1163
if ((base->target != PIPE_TEXTURE_2D &&
1164
base->target != PIPE_TEXTURE_RECT) ||
1165
base->depth0 != 1 ||
1166
base->last_level != 0) {
1167
return NULL;
1168
}
1169
1170
buffer = rws->buffer_from_handle(rws, whandle, 0);
1171
if (!buffer)
1172
return NULL;
1173
1174
rws->buffer_get_metadata(rws, buffer, &tiling, NULL);
1175
1176
/* Enforce a microtiled zbuffer. */
1177
if (util_format_is_depth_or_stencil(base->format) &&
1178
tiling.u.legacy.microtile == RADEON_LAYOUT_LINEAR) {
1179
switch (util_format_get_blocksize(base->format)) {
1180
case 4:
1181
tiling.u.legacy.microtile = RADEON_LAYOUT_TILED;
1182
break;
1183
1184
case 2:
1185
tiling.u.legacy.microtile = RADEON_LAYOUT_SQUARETILED;
1186
break;
1187
}
1188
}
1189
1190
return (struct pipe_resource*)
1191
r300_texture_create_object(rscreen, base, tiling.u.legacy.microtile, tiling.u.legacy.macrotile,
1192
whandle->stride, buffer);
1193
}
1194
1195
struct pipe_surface* r300_create_surface_custom(struct pipe_context * ctx,
1196
struct pipe_resource* texture,
1197
const struct pipe_surface *surf_tmpl,
1198
unsigned width0_override,
1199
unsigned height0_override)
1200
{
1201
struct r300_resource* tex = r300_resource(texture);
1202
struct r300_surface* surface = CALLOC_STRUCT(r300_surface);
1203
unsigned level = surf_tmpl->u.tex.level;
1204
1205
assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
1206
1207
if (surface) {
1208
uint32_t offset, tile_height;
1209
1210
pipe_reference_init(&surface->base.reference, 1);
1211
pipe_resource_reference(&surface->base.texture, texture);
1212
surface->base.context = ctx;
1213
surface->base.format = surf_tmpl->format;
1214
surface->base.width = u_minify(width0_override, level);
1215
surface->base.height = u_minify(height0_override, level);
1216
surface->base.u.tex.level = level;
1217
surface->base.u.tex.first_layer = surf_tmpl->u.tex.first_layer;
1218
surface->base.u.tex.last_layer = surf_tmpl->u.tex.last_layer;
1219
1220
surface->buf = tex->buf;
1221
1222
/* Prefer VRAM if there are multiple domains to choose from. */
1223
surface->domain = tex->domain;
1224
if (surface->domain & RADEON_DOMAIN_VRAM)
1225
surface->domain &= ~RADEON_DOMAIN_GTT;
1226
1227
surface->offset = r300_texture_get_offset(tex, level,
1228
surf_tmpl->u.tex.first_layer);
1229
r300_texture_setup_fb_state(surface);
1230
1231
/* Parameters for the CBZB clear. */
1232
surface->cbzb_allowed = tex->tex.cbzb_allowed[level];
1233
surface->cbzb_width = align(surface->base.width, 64);
1234
1235
/* Height must be aligned to the size of a tile. */
1236
tile_height = r300_get_pixel_alignment(surface->base.format,
1237
tex->b.nr_samples,
1238
tex->tex.microtile,
1239
tex->tex.macrotile[level],
1240
DIM_HEIGHT, 0);
1241
1242
surface->cbzb_height = align((surface->base.height + 1) / 2,
1243
tile_height);
1244
1245
/* Offset must be aligned to 2K and must point at the beginning
1246
* of a scanline. */
1247
offset = surface->offset +
1248
tex->tex.stride_in_bytes[level] * surface->cbzb_height;
1249
surface->cbzb_midpoint_offset = offset & ~2047;
1250
1251
surface->cbzb_pitch = surface->pitch & 0x1ffffc;
1252
1253
if (util_format_get_blocksizebits(surface->base.format) == 32)
1254
surface->cbzb_format = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
1255
else
1256
surface->cbzb_format = R300_DEPTHFORMAT_16BIT_INT_Z;
1257
1258
DBG(r300_context(ctx), DBG_CBZB,
1259
"CBZB Allowed: %s, Dim: %ix%i, Misalignment: %i, Micro: %s, Macro: %s\n",
1260
surface->cbzb_allowed ? "YES" : " NO",
1261
surface->cbzb_width, surface->cbzb_height,
1262
offset & 2047,
1263
tex->tex.microtile ? "YES" : " NO",
1264
tex->tex.macrotile[level] ? "YES" : " NO");
1265
}
1266
1267
return &surface->base;
1268
}
1269
1270
struct pipe_surface* r300_create_surface(struct pipe_context * ctx,
1271
struct pipe_resource* texture,
1272
const struct pipe_surface *surf_tmpl)
1273
{
1274
return r300_create_surface_custom(ctx, texture, surf_tmpl,
1275
texture->width0,
1276
texture->height0);
1277
}
1278
1279
void r300_surface_destroy(struct pipe_context *ctx, struct pipe_surface* s)
1280
{
1281
pipe_resource_reference(&s->texture, NULL);
1282
FREE(s);
1283
}
1284
1285