~ubuntu-branches/ubuntu/natty/mesa/natty-proposed

« back to all changes in this revision

Viewing changes to src/gallium/drivers/r300/r300_texture.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Hooker, Robert Hooker, Christopher James Halse Rogers
  • Date: 2010-09-14 08:55:40 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100914085540-m4fpl0hdjlfd4jgz
Tags: 7.9~git20100909-0ubuntu1
[ Robert Hooker ]
* New upstream git snapshot up to commit 94118fe2d4b1e5 (LP: #631413)
* New features include ATI HD5xxx series support in r600, and a vastly
  improved glsl compiler.
* Remove pre-generated .pc's, use the ones generated at build time
  instead.
* Remove all references to mesa-utils now that its no longer shipped
  with the mesa source.
* Disable the experimental ARB_fragment_shader option by default on
  i915, it exposes incomplete functionality that breaks KDE compositing
  among other things. It can be enabled via driconf still. (LP: #628930).

[ Christopher James Halse Rogers ]
* debian/patches/04_osmesa_version.diff:
  - Refresh for new upstream
* Bugs fixed in this release:
  - Fixes severe rendering corruption in Unity on radeon (LP: #628727,
    LP: #596292, LP: #599741, LP: #630315, LP: #613694, LP: #599741).
  - Also fixes rendering in gnome-shell (LP: #578619).
  - Flickering in OpenGL apps on radeon (LP: #626943, LP: #610541).
  - Provides preliminary support for new intel chips (LP: #601052).
* debian/rules:
  - Update configure flags to match upstream reshuffling.
  - Explicitly remove gallium DRI drivers that we don't want to ship.
* Update debian/gbp.conf for this Maverick-specific packaging
* libegl1-mesa-dri-x11,kms: There are no longer separate kms or x11 drivers
  for EGL, libegl1-mesa-drivers now contains a single driver that provides
  both backends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22
22
 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
23
23
 
24
 
#include "pipe/p_screen.h"
 
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
#include "r300_winsys.h"
25
33
 
26
34
#include "util/u_format.h"
 
35
#include "util/u_format_s3tc.h"
27
36
#include "util/u_math.h"
28
37
#include "util/u_memory.h"
29
 
 
30
 
#include "r300_context.h"
31
 
#include "r300_texture.h"
32
 
#include "r300_screen.h"
33
 
#include "r300_state_inlines.h"
34
 
 
35
 
#include "radeon_winsys.h"
36
 
 
37
 
#define TILE_WIDTH 0
38
 
#define TILE_HEIGHT 1
39
 
 
40
 
static const unsigned microblock_table[5][3][2] = {
41
 
    /*linear  tiled   square-tiled */
42
 
    {{32, 1}, {8, 4}, {0, 0}}, /*   8 bits per pixel */
43
 
    {{16, 1}, {8, 2}, {4, 4}}, /*  16 bits per pixel */
44
 
    {{ 8, 1}, {4, 2}, {0, 0}}, /*  32 bits per pixel */
45
 
    {{ 4, 1}, {0, 0}, {2, 2}}, /*  64 bits per pixel */
46
 
    {{ 2, 1}, {0, 0}, {0, 0}}  /* 128 bits per pixel */
47
 
};
 
38
#include "util/u_mm.h"
 
39
 
 
40
#include "pipe/p_screen.h"
 
41
 
 
42
unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
 
43
                                   const unsigned char *swizzle_view)
 
44
{
 
45
    unsigned i;
 
46
    unsigned char swizzle[4];
 
47
    unsigned result = 0;
 
48
    const uint32_t swizzle_shift[4] = {
 
49
        R300_TX_FORMAT_R_SHIFT,
 
50
        R300_TX_FORMAT_G_SHIFT,
 
51
        R300_TX_FORMAT_B_SHIFT,
 
52
        R300_TX_FORMAT_A_SHIFT
 
53
    };
 
54
    const uint32_t swizzle_bit[4] = {
 
55
        R300_TX_FORMAT_X,
 
56
        R300_TX_FORMAT_Y,
 
57
        R300_TX_FORMAT_Z,
 
58
        R300_TX_FORMAT_W
 
59
    };
 
60
 
 
61
    if (swizzle_view) {
 
62
        /* Combine two sets of swizzles. */
 
63
        for (i = 0; i < 4; i++) {
 
64
            swizzle[i] = swizzle_view[i] <= UTIL_FORMAT_SWIZZLE_W ?
 
65
                         swizzle_format[swizzle_view[i]] : swizzle_view[i];
 
66
        }
 
67
    } else {
 
68
        memcpy(swizzle, swizzle_format, 4);
 
69
    }
 
70
 
 
71
    /* Get swizzle. */
 
72
    for (i = 0; i < 4; i++) {
 
73
        switch (swizzle[i]) {
 
74
            case UTIL_FORMAT_SWIZZLE_Y:
 
75
                result |= swizzle_bit[1] << swizzle_shift[i];
 
76
                break;
 
77
            case UTIL_FORMAT_SWIZZLE_Z:
 
78
                result |= swizzle_bit[2] << swizzle_shift[i];
 
79
                break;
 
80
            case UTIL_FORMAT_SWIZZLE_W:
 
81
                result |= swizzle_bit[3] << swizzle_shift[i];
 
82
                break;
 
83
            case UTIL_FORMAT_SWIZZLE_0:
 
84
                result |= R300_TX_FORMAT_ZERO << swizzle_shift[i];
 
85
                break;
 
86
            case UTIL_FORMAT_SWIZZLE_1:
 
87
                result |= R300_TX_FORMAT_ONE << swizzle_shift[i];
 
88
                break;
 
89
            default: /* UTIL_FORMAT_SWIZZLE_X */
 
90
                result |= swizzle_bit[0] << swizzle_shift[i];
 
91
        }
 
92
    }
 
93
    return result;
 
94
}
48
95
 
49
96
/* Translate a pipe_format into a useful texture format for sampling.
50
97
 *
58
105
 *
59
106
 * The FORMAT specifies how the texture sampler will treat the texture, and
60
107
 * makes available X, Y, Z, W, ZERO, and ONE for swizzling. */
61
 
static uint32_t r300_translate_texformat(enum pipe_format format)
 
108
uint32_t r300_translate_texformat(enum pipe_format format,
 
109
                                  const unsigned char *swizzle_view,
 
110
                                  boolean is_r500)
62
111
{
63
112
    uint32_t result = 0;
64
113
    const struct util_format_description *desc;
65
 
    unsigned components = 0, i;
 
114
    unsigned i;
66
115
    boolean uniform = TRUE;
67
 
    const uint32_t swizzle_shift[4] = {
68
 
        R300_TX_FORMAT_R_SHIFT,
69
 
        R300_TX_FORMAT_G_SHIFT,
70
 
        R300_TX_FORMAT_B_SHIFT,
71
 
        R300_TX_FORMAT_A_SHIFT
72
 
    };
73
 
    const uint32_t swizzle[4] = {
74
 
        R300_TX_FORMAT_X,
75
 
        R300_TX_FORMAT_Y,
76
 
        R300_TX_FORMAT_Z,
77
 
        R300_TX_FORMAT_W
78
 
    };
79
116
    const uint32_t sign_bit[4] = {
80
117
        R300_TX_FORMAT_SIGNED_X,
81
118
        R300_TX_FORMAT_SIGNED_Y,
87
124
 
88
125
    /* Colorspace (return non-RGB formats directly). */
89
126
    switch (desc->colorspace) {
90
 
        /* Depth stencil formats. */
 
127
        /* Depth stencil formats.
 
128
         * Swizzles are added in r300_merge_textures_and_samplers. */
91
129
        case UTIL_FORMAT_COLORSPACE_ZS:
92
130
            switch (format) {
93
131
                case PIPE_FORMAT_Z16_UNORM:
94
 
                    return R300_EASY_TX_FORMAT(X, X, X, X, X16);
 
132
                    return R300_TX_FORMAT_X16;
95
133
                case PIPE_FORMAT_X8Z24_UNORM:
96
 
                case PIPE_FORMAT_S8Z24_UNORM:
97
 
                    return R300_EASY_TX_FORMAT(X, X, X, X, W24_FP);
 
134
                case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
 
135
                    if (is_r500)
 
136
                        return R500_TX_FORMAT_Y8X24;
 
137
                    else
 
138
                        return R300_TX_FORMAT_Y16X16;
98
139
                default:
99
140
                    return ~0; /* Unsupported. */
100
141
            }
117
158
            result |= R300_TX_FORMAT_GAMMA;
118
159
            break;
119
160
 
120
 
        default:;
 
161
        default:
 
162
            switch (format) {
 
163
                /* Same as YUV but without the YUR->RGB conversion. */
 
164
                case PIPE_FORMAT_R8G8_B8G8_UNORM:
 
165
                    return R300_EASY_TX_FORMAT(X, Y, Z, ONE, YVYU422) | result;
 
166
                case PIPE_FORMAT_G8R8_G8B8_UNORM:
 
167
                    return R300_EASY_TX_FORMAT(X, Y, Z, ONE, VYUY422) | result;
 
168
                default:;
 
169
            }
121
170
    }
122
171
 
123
 
    /* Add swizzle. */
124
 
    for (i = 0; i < 4; i++) {
125
 
        switch (desc->swizzle[i]) {
126
 
            case UTIL_FORMAT_SWIZZLE_X:
127
 
            case UTIL_FORMAT_SWIZZLE_NONE:
128
 
                result |= swizzle[0] << swizzle_shift[i];
129
 
                break;
130
 
            case UTIL_FORMAT_SWIZZLE_Y:
131
 
                result |= swizzle[1] << swizzle_shift[i];
132
 
                break;
133
 
            case UTIL_FORMAT_SWIZZLE_Z:
134
 
                result |= swizzle[2] << swizzle_shift[i];
135
 
                break;
136
 
            case UTIL_FORMAT_SWIZZLE_W:
137
 
                result |= swizzle[3] << swizzle_shift[i];
138
 
                break;
139
 
            case UTIL_FORMAT_SWIZZLE_0:
140
 
                result |= R300_TX_FORMAT_ZERO << swizzle_shift[i];
141
 
                break;
142
 
            case UTIL_FORMAT_SWIZZLE_1:
143
 
                result |= R300_TX_FORMAT_ONE << swizzle_shift[i];
144
 
                break;
145
 
            default:
146
 
                return ~0; /* Unsupported. */
 
172
    result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view);
 
173
 
 
174
    /* S3TC formats. */
 
175
    if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
 
176
        if (!util_format_s3tc_enabled) {
 
177
            return ~0; /* Unsupported. */
147
178
        }
148
 
    }
149
179
 
150
 
    /* Compressed formats. */
151
 
    if (desc->layout == UTIL_FORMAT_LAYOUT_COMPRESSED) {
152
180
        switch (format) {
153
181
            case PIPE_FORMAT_DXT1_RGB:
154
182
            case PIPE_FORMAT_DXT1_RGBA:
166
194
        }
167
195
    }
168
196
 
169
 
    /* Get the number of components. */
170
 
    for (i = 0; i < 4; i++) {
171
 
        if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
172
 
            ++components;
173
 
        }
174
 
    }
175
 
 
176
197
    /* Add sign. */
177
 
    for (i = 0; i < components; i++) {
 
198
    for (i = 0; i < desc->nr_channels; i++) {
178
199
        if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
179
200
            result |= sign_bit[i];
180
201
        }
181
202
    }
182
203
 
 
204
    /* This is truly a special format.
 
205
     * It stores R8G8 and B is computed using sqrt(1 - R^2 - G^2)
 
206
     * in the sampler unit. Also known as D3DFMT_CxV8U8. */
 
207
    if (format == PIPE_FORMAT_R8G8Bx_SNORM) {
 
208
        return R300_TX_FORMAT_CxV8U8 | result;
 
209
    }
 
210
 
 
211
    /* RGTC formats. */
 
212
    if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
 
213
        switch (format) {
 
214
            case PIPE_FORMAT_RGTC1_UNORM:
 
215
            case PIPE_FORMAT_RGTC1_SNORM:
 
216
                return R500_TX_FORMAT_ATI1N | result;
 
217
            case PIPE_FORMAT_RGTC2_UNORM:
 
218
            case PIPE_FORMAT_RGTC2_SNORM:
 
219
                return R400_TX_FORMAT_ATI2N | result;
 
220
            default:
 
221
                return ~0; /* Unsupported/unknown. */
 
222
        }
 
223
    }
 
224
 
183
225
    /* See whether the components are of the same size. */
184
 
    for (i = 1; i < components; i++) {
 
226
    for (i = 1; i < desc->nr_channels; i++) {
185
227
        uniform = uniform && desc->channel[0].size == desc->channel[i].size;
186
228
    }
187
229
 
188
230
    /* Non-uniform formats. */
189
231
    if (!uniform) {
190
 
        switch (components) {
 
232
        switch (desc->nr_channels) {
191
233
            case 3:
192
234
                if (desc->channel[0].size == 5 &&
193
235
                    desc->channel[1].size == 6 &&
229
271
 
230
272
            switch (desc->channel[0].size) {
231
273
                case 4:
232
 
                    switch (components) {
 
274
                    switch (desc->nr_channels) {
233
275
                        case 2:
234
276
                            return R300_TX_FORMAT_Y4X4 | result;
235
277
                        case 4:
238
280
                    return ~0;
239
281
 
240
282
                case 8:
241
 
                    switch (components) {
 
283
                    switch (desc->nr_channels) {
242
284
                        case 1:
243
285
                            return R300_TX_FORMAT_X8 | result;
244
286
                        case 2:
249
291
                    return ~0;
250
292
 
251
293
                case 16:
252
 
                    switch (components) {
 
294
                    switch (desc->nr_channels) {
253
295
                        case 1:
254
296
                            return R300_TX_FORMAT_X16 | result;
255
297
                        case 2:
260
302
            }
261
303
            return ~0;
262
304
 
263
 
/* XXX Enable float textures here. */
264
 
#if 0
265
305
        case UTIL_FORMAT_TYPE_FLOAT:
266
306
            switch (desc->channel[0].size) {
267
307
                case 16:
268
 
                    switch (components) {
 
308
                    switch (desc->nr_channels) {
269
309
                        case 1:
270
310
                            return R300_TX_FORMAT_16F | result;
271
311
                        case 2:
276
316
                    return ~0;
277
317
 
278
318
                case 32:
279
 
                    switch (components) {
 
319
                    switch (desc->nr_channels) {
280
320
                        case 1:
281
321
                            return R300_TX_FORMAT_32F | result;
282
322
                        case 2:
285
325
                            return R300_TX_FORMAT_32F_32F_32F_32F | result;
286
326
                    }
287
327
            }
288
 
#endif
289
328
    }
290
329
 
291
330
    return ~0; /* Unsupported/unknown. */
292
331
}
293
332
 
 
333
uint32_t r500_tx_format_msb_bit(enum pipe_format format)
 
334
{
 
335
    switch (format) {
 
336
        case PIPE_FORMAT_RGTC1_UNORM:
 
337
        case PIPE_FORMAT_RGTC1_SNORM:
 
338
        case PIPE_FORMAT_X8Z24_UNORM:
 
339
        case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
 
340
            return R500_TXFORMAT_MSB;
 
341
        default:
 
342
            return 0;
 
343
    }
 
344
}
 
345
 
294
346
/* Buffer formats. */
295
347
 
296
348
/* Colorbuffer formats. This is the unswizzled format of the RB3D block's
302
354
        case PIPE_FORMAT_A8_UNORM:
303
355
        case PIPE_FORMAT_I8_UNORM:
304
356
        case PIPE_FORMAT_L8_UNORM:
305
 
        case PIPE_FORMAT_L8_SRGB:
306
357
        case PIPE_FORMAT_R8_UNORM:
307
358
        case PIPE_FORMAT_R8_SNORM:
308
359
            return R300_COLOR_FORMAT_I8;
310
361
        /* 16-bit buffers. */
311
362
        case PIPE_FORMAT_B5G6R5_UNORM:
312
363
            return R300_COLOR_FORMAT_RGB565;
 
364
 
313
365
        case PIPE_FORMAT_B5G5R5A1_UNORM:
 
366
        case PIPE_FORMAT_B5G5R5X1_UNORM:
314
367
            return R300_COLOR_FORMAT_ARGB1555;
 
368
 
315
369
        case PIPE_FORMAT_B4G4R4A4_UNORM:
 
370
        case PIPE_FORMAT_B4G4R4X4_UNORM:
316
371
            return R300_COLOR_FORMAT_ARGB4444;
317
372
 
318
373
        /* 32-bit buffers. */
319
374
        case PIPE_FORMAT_B8G8R8A8_UNORM:
320
 
        case PIPE_FORMAT_B8G8R8A8_SRGB:
321
375
        case PIPE_FORMAT_B8G8R8X8_UNORM:
322
 
        case PIPE_FORMAT_B8G8R8X8_SRGB:
323
376
        case PIPE_FORMAT_A8R8G8B8_UNORM:
324
 
        case PIPE_FORMAT_A8R8G8B8_SRGB:
325
377
        case PIPE_FORMAT_X8R8G8B8_UNORM:
326
 
        case PIPE_FORMAT_X8R8G8B8_SRGB:
327
378
        case PIPE_FORMAT_A8B8G8R8_UNORM:
328
379
        case PIPE_FORMAT_R8G8B8A8_SNORM:
329
 
        case PIPE_FORMAT_A8B8G8R8_SRGB:
330
380
        case PIPE_FORMAT_X8B8G8R8_UNORM:
331
 
        case PIPE_FORMAT_X8B8G8R8_SRGB:
 
381
        case PIPE_FORMAT_R8G8B8X8_UNORM:
332
382
        case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
333
383
            return R300_COLOR_FORMAT_ARGB8888;
 
384
 
334
385
        case PIPE_FORMAT_R10G10B10A2_UNORM:
 
386
        case PIPE_FORMAT_R10G10B10X2_SNORM:
 
387
        case PIPE_FORMAT_B10G10R10A2_UNORM:
 
388
        case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
335
389
            return R500_COLOR_FORMAT_ARGB2101010;  /* R5xx-only? */
336
390
 
337
391
        /* 64-bit buffers. */
338
392
        case PIPE_FORMAT_R16G16B16A16_UNORM:
339
393
        case PIPE_FORMAT_R16G16B16A16_SNORM:
340
 
        //case PIPE_FORMAT_R16G16B16A16_FLOAT: /* not in pipe_format */
 
394
        case PIPE_FORMAT_R16G16B16A16_FLOAT:
341
395
            return R300_COLOR_FORMAT_ARGB16161616;
342
396
 
343
 
/* XXX Enable float textures here. */
344
 
#if 0
345
397
        /* 128-bit buffers. */
346
398
        case PIPE_FORMAT_R32G32B32A32_FLOAT:
347
399
            return R300_COLOR_FORMAT_ARGB32323232;
348
 
#endif
349
400
 
350
401
        /* YUV buffers. */
351
402
        case PIPE_FORMAT_UYVY:
367
418
        /* 24-bit depth, ignored stencil */
368
419
        case PIPE_FORMAT_X8Z24_UNORM:
369
420
        /* 24-bit depth, 8-bit stencil */
370
 
        case PIPE_FORMAT_S8Z24_UNORM:
 
421
        case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
371
422
            return R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
372
423
        default:
373
424
            return ~0; /* Unsupported. */
393
444
    desc = util_format_description(format);
394
445
 
395
446
    /* Specifies how the shader output is written to the fog unit. */
396
 
    if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
397
 
        /* The gamma correction causes precision loss so we need
398
 
         * higher precision to maintain reasonable quality.
399
 
         * It has nothing to do with the colorbuffer format. */
400
 
        modifier |= R300_US_OUT_FMT_C4_10_GAMMA;
401
 
    } else if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) {
 
447
    if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) {
402
448
        if (desc->channel[0].size == 32) {
403
449
            modifier |= R300_US_OUT_FMT_C4_32_FP;
404
450
        } else {
428
474
            return modifier | R300_C2_SEL_A;
429
475
        case PIPE_FORMAT_I8_UNORM:
430
476
        case PIPE_FORMAT_L8_UNORM:
431
 
        case PIPE_FORMAT_L8_SRGB:
432
477
        case PIPE_FORMAT_R8_UNORM:
433
478
        case PIPE_FORMAT_R8_SNORM:
434
479
            return modifier | R300_C2_SEL_R;
435
480
 
436
 
        /* ARGB 32-bit outputs. */
 
481
        /* BGRA outputs. */
437
482
        case PIPE_FORMAT_B5G6R5_UNORM:
438
483
        case PIPE_FORMAT_B5G5R5A1_UNORM:
 
484
        case PIPE_FORMAT_B5G5R5X1_UNORM:
439
485
        case PIPE_FORMAT_B4G4R4A4_UNORM:
 
486
        case PIPE_FORMAT_B4G4R4X4_UNORM:
440
487
        case PIPE_FORMAT_B8G8R8A8_UNORM:
441
 
        case PIPE_FORMAT_B8G8R8A8_SRGB:
442
488
        case PIPE_FORMAT_B8G8R8X8_UNORM:
443
 
        case PIPE_FORMAT_B8G8R8X8_SRGB:
 
489
        case PIPE_FORMAT_B10G10R10A2_UNORM:
444
490
            return modifier |
445
491
                R300_C0_SEL_B | R300_C1_SEL_G |
446
492
                R300_C2_SEL_R | R300_C3_SEL_A;
447
493
 
448
 
        /* BGRA 32-bit outputs. */
 
494
        /* ARGB outputs. */
449
495
        case PIPE_FORMAT_A8R8G8B8_UNORM:
450
 
        case PIPE_FORMAT_A8R8G8B8_SRGB:
451
496
        case PIPE_FORMAT_X8R8G8B8_UNORM:
452
 
        case PIPE_FORMAT_X8R8G8B8_SRGB:
453
497
            return modifier |
454
498
                R300_C0_SEL_A | R300_C1_SEL_R |
455
499
                R300_C2_SEL_G | R300_C3_SEL_B;
456
500
 
457
 
        /* RGBA 32-bit outputs. */
 
501
        /* ABGR outputs. */
458
502
        case PIPE_FORMAT_A8B8G8R8_UNORM:
459
 
        case PIPE_FORMAT_R8G8B8A8_SNORM:
460
 
        case PIPE_FORMAT_A8B8G8R8_SRGB:
461
503
        case PIPE_FORMAT_X8B8G8R8_UNORM:
462
 
        case PIPE_FORMAT_X8B8G8R8_SRGB:
463
504
            return modifier |
464
505
                R300_C0_SEL_A | R300_C1_SEL_B |
465
506
                R300_C2_SEL_G | R300_C3_SEL_R;
466
507
 
467
 
        /* ABGR 32-bit outputs. */
 
508
        /* RGBA outputs. */
 
509
        case PIPE_FORMAT_R8G8B8X8_UNORM:
 
510
        case PIPE_FORMAT_R8G8B8A8_SNORM:
468
511
        case PIPE_FORMAT_R8SG8SB8UX8U_NORM:
469
512
        case PIPE_FORMAT_R10G10B10A2_UNORM:
470
 
        /* RGBA high precision outputs (same swizzles as ABGR low precision) */
 
513
        case PIPE_FORMAT_R10G10B10X2_SNORM:
 
514
        case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
471
515
        case PIPE_FORMAT_R16G16B16A16_UNORM:
472
516
        case PIPE_FORMAT_R16G16B16A16_SNORM:
473
 
        //case PIPE_FORMAT_R16G16B16A16_FLOAT: /* not in pipe_format */
 
517
        case PIPE_FORMAT_R16G16B16A16_FLOAT:
474
518
        case PIPE_FORMAT_R32G32B32A32_FLOAT:
475
519
            return modifier |
476
520
                R300_C0_SEL_R | R300_C1_SEL_G |
494
538
 
495
539
boolean r300_is_sampler_format_supported(enum pipe_format format)
496
540
{
497
 
    return r300_translate_texformat(format) != ~0;
 
541
    return r300_translate_texformat(format, 0, TRUE) != ~0;
498
542
}
499
543
 
500
 
static void r300_setup_texture_state(struct r300_screen* screen, struct r300_texture* tex)
 
544
void r300_texture_setup_format_state(struct r300_screen *screen,
 
545
                                     struct r300_texture_desc *desc,
 
546
                                     unsigned level,
 
547
                                     struct r300_texture_format_state *out)
501
548
{
502
 
    struct r300_texture_format_state* state = &tex->state;
503
 
    struct pipe_texture *pt = &tex->tex;
504
 
    unsigned i;
505
 
    boolean is_r500 = screen->caps->is_r500;
 
549
    struct pipe_resource *pt = &desc->b.b;
 
550
    boolean is_r500 = screen->caps.is_r500;
 
551
 
 
552
    /* Mask out all the fields we change. */
 
553
    out->format0 = 0;
 
554
    out->format1 &= ~R300_TX_FORMAT_TEX_COORD_TYPE_MASK;
 
555
    out->format2 &= R500_TXFORMAT_MSB;
 
556
    out->tile_config = 0;
506
557
 
507
558
    /* Set sampler state. */
508
 
    state->format0 = R300_TX_WIDTH((pt->width0 - 1) & 0x7ff) |
509
 
                     R300_TX_HEIGHT((pt->height0 - 1) & 0x7ff);
 
559
    out->format0 = R300_TX_WIDTH((u_minify(pt->width0, level) - 1) & 0x7ff) |
 
560
                   R300_TX_HEIGHT((u_minify(pt->height0, level) - 1) & 0x7ff);
510
561
 
511
 
    if (tex->is_npot) {
 
562
    if (desc->uses_stride_addressing) {
512
563
        /* rectangles love this */
513
 
        state->format0 |= R300_TX_PITCH_EN;
514
 
        state->format2 = (tex->pitch[0] - 1) & 0x1fff;
 
564
        out->format0 |= R300_TX_PITCH_EN;
 
565
        out->format2 = (desc->stride_in_pixels[level] - 1) & 0x1fff;
515
566
    } else {
516
 
        /* power of two textures (3D, mipmaps, and no pitch) */
517
 
        state->format0 |= R300_TX_DEPTH(util_logbase2(pt->depth0) & 0xf);
 
567
        /* Power of two textures (3D, mipmaps, and no pitch),
 
568
         * also NPOT textures with a width being POT. */
 
569
        out->format0 |=
 
570
            R300_TX_DEPTH(util_logbase2(u_minify(pt->depth0, level)) & 0xf);
518
571
    }
519
572
 
520
 
    state->format1 = r300_translate_texformat(pt->format);
521
573
    if (pt->target == PIPE_TEXTURE_CUBE) {
522
 
        state->format1 |= R300_TX_FORMAT_CUBIC_MAP;
 
574
        out->format1 |= R300_TX_FORMAT_CUBIC_MAP;
523
575
    }
524
576
    if (pt->target == PIPE_TEXTURE_3D) {
525
 
        state->format1 |= R300_TX_FORMAT_3D;
 
577
        out->format1 |= R300_TX_FORMAT_3D;
526
578
    }
527
579
 
528
580
    /* large textures on r500 */
529
581
    if (is_r500)
530
582
    {
531
583
        if (pt->width0 > 2048) {
532
 
            state->format2 |= R500_TXWIDTH_BIT11;
 
584
            out->format2 |= R500_TXWIDTH_BIT11;
533
585
        }
534
586
        if (pt->height0 > 2048) {
535
 
            state->format2 |= R500_TXHEIGHT_BIT11;
 
587
            out->format2 |= R500_TXHEIGHT_BIT11;
536
588
        }
537
589
    }
538
590
 
539
 
    SCREEN_DBG(screen, DBG_TEX, "r300: Set texture state (%dx%d, %d levels)\n",
540
 
               pt->width0, pt->height0, pt->last_level);
 
591
    out->tile_config = R300_TXO_MACRO_TILE(desc->macrotile[level]) |
 
592
                       R300_TXO_MICRO_TILE(desc->microtile);
 
593
}
 
594
 
 
595
static void r300_texture_setup_fb_state(struct r300_screen* screen,
 
596
                                        struct r300_texture* tex)
 
597
{
 
598
    unsigned i;
541
599
 
542
600
    /* Set framebuffer state. */
543
 
    if (util_format_is_depth_or_stencil(tex->tex.format)) {
544
 
        for (i = 0; i <= tex->tex.last_level; i++) {
545
 
            tex->fb_state.depthpitch[i] =
546
 
                tex->pitch[i] |
547
 
                R300_DEPTHMACROTILE(tex->mip_macrotile[i]) |
548
 
                R300_DEPTHMICROTILE(tex->microtile);
 
601
    if (util_format_is_depth_or_stencil(tex->desc.b.b.format)) {
 
602
        for (i = 0; i <= tex->desc.b.b.last_level; i++) {
 
603
            tex->fb_state.pitch[i] =
 
604
                tex->desc.stride_in_pixels[i] |
 
605
                R300_DEPTHMACROTILE(tex->desc.macrotile[i]) |
 
606
                R300_DEPTHMICROTILE(tex->desc.microtile);
549
607
        }
550
 
        tex->fb_state.zb_format = r300_translate_zsformat(tex->tex.format);
 
608
        tex->fb_state.format = r300_translate_zsformat(tex->desc.b.b.format);
551
609
    } else {
552
 
        for (i = 0; i <= tex->tex.last_level; i++) {
553
 
            tex->fb_state.colorpitch[i] =
554
 
                tex->pitch[i] |
555
 
                r300_translate_colorformat(tex->tex.format) |
556
 
                R300_COLOR_TILE(tex->mip_macrotile[i]) |
557
 
                R300_COLOR_MICROTILE(tex->microtile);
 
610
        for (i = 0; i <= tex->desc.b.b.last_level; i++) {
 
611
            tex->fb_state.pitch[i] =
 
612
                tex->desc.stride_in_pixels[i] |
 
613
                r300_translate_colorformat(tex->desc.b.b.format) |
 
614
                R300_COLOR_TILE(tex->desc.macrotile[i]) |
 
615
                R300_COLOR_MICROTILE(tex->desc.microtile);
558
616
        }
559
 
        tex->fb_state.us_out_fmt = r300_translate_out_fmt(tex->tex.format);
 
617
        tex->fb_state.format = r300_translate_out_fmt(tex->desc.b.b.format);
560
618
    }
561
619
}
562
620
 
563
621
void r300_texture_reinterpret_format(struct pipe_screen *screen,
564
 
                                     struct pipe_texture *tex,
 
622
                                     struct pipe_resource *tex,
565
623
                                     enum pipe_format new_format)
566
624
{
567
625
    struct r300_screen *r300screen = r300_screen(screen);
568
626
 
569
 
    SCREEN_DBG(r300screen, DBG_TEX, "r300: Reinterpreting format: %s -> %s\n",
570
 
               util_format_name(tex->format), util_format_name(new_format));
 
627
    SCREEN_DBG(r300screen, DBG_TEX,
 
628
        "r300: texture_reinterpret_format: %s -> %s\n",
 
629
        util_format_short_name(tex->format),
 
630
        util_format_short_name(new_format));
571
631
 
572
632
    tex->format = new_format;
573
633
 
574
 
    r300_setup_texture_state(r300_screen(screen), (struct r300_texture*)tex);
575
 
}
576
 
 
577
 
unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level,
578
 
                                 unsigned zslice, unsigned face)
579
 
{
580
 
    unsigned offset = tex->offset[level];
581
 
 
582
 
    switch (tex->tex.target) {
583
 
        case PIPE_TEXTURE_3D:
584
 
            assert(face == 0);
585
 
            return offset + zslice * tex->layer_size[level];
586
 
 
587
 
        case PIPE_TEXTURE_CUBE:
588
 
            assert(zslice == 0);
589
 
            return offset + face * tex->layer_size[level];
590
 
 
591
 
        default:
592
 
            assert(zslice == 0 && face == 0);
593
 
            return offset;
594
 
    }
595
 
}
596
 
 
597
 
/**
598
 
 * Return the width (dim==TILE_WIDTH) or height (dim==TILE_HEIGHT) of one tile
599
 
 * of the given texture.
600
 
 */
601
 
static unsigned r300_texture_get_tile_size(struct r300_texture* tex,
602
 
                                           int dim, boolean macrotile)
603
 
{
604
 
    unsigned pixsize, tile_size;
605
 
 
606
 
    pixsize = util_format_get_blocksize(tex->tex.format);
607
 
    tile_size = microblock_table[util_logbase2(pixsize)][tex->microtile][dim];
608
 
 
609
 
    if (macrotile) {
610
 
        tile_size *= 8;
611
 
    }
612
 
 
613
 
    assert(tile_size);
614
 
    return tile_size;
615
 
}
616
 
 
617
 
/* Return true if macrotiling should be enabled on the miplevel. */
618
 
static boolean r300_texture_macro_switch(struct r300_texture *tex,
619
 
                                         unsigned level,
620
 
                                         boolean rv350_mode)
621
 
{
622
 
    unsigned tile_width, width;
623
 
 
624
 
    tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH, TRUE);
625
 
    width = u_minify(tex->tex.width0, level);
626
 
 
627
 
    /* See TX_FILTER1_n.MACRO_SWITCH. */
628
 
    if (rv350_mode) {
629
 
        return width >= tile_width;
630
 
    } else {
631
 
        return width > tile_width;
632
 
    }
633
 
}
634
 
 
635
 
/**
636
 
 * Return the stride, in bytes, of the texture images of the given texture
637
 
 * at the given level.
638
 
 */
639
 
unsigned r300_texture_get_stride(struct r300_screen* screen,
640
 
                                 struct r300_texture* tex, unsigned level)
641
 
{
642
 
    unsigned tile_width, width;
643
 
 
644
 
    if (tex->stride_override)
645
 
        return tex->stride_override;
646
 
 
647
 
    /* Check the level. */
648
 
    if (level > tex->tex.last_level) {
649
 
        SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n",
650
 
                   __FUNCTION__, level, tex->tex.last_level);
651
 
        return 0;
652
 
    }
653
 
 
654
 
    width = u_minify(tex->tex.width0, level);
655
 
 
656
 
    if (!util_format_is_compressed(tex->tex.format)) {
657
 
        tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH,
658
 
                                                tex->mip_macrotile[level]);
659
 
        width = align(width, tile_width);
660
 
 
661
 
        return util_format_get_stride(tex->tex.format, width);
662
 
    } else {
663
 
        return align(util_format_get_stride(tex->tex.format, width), 32);
664
 
    }
665
 
}
666
 
 
667
 
static unsigned r300_texture_get_nblocksy(struct r300_texture* tex,
668
 
                                          unsigned level)
669
 
{
670
 
    unsigned height, tile_height;
671
 
 
672
 
    height = u_minify(tex->tex.height0, level);
673
 
 
674
 
    if (!util_format_is_compressed(tex->tex.format)) {
675
 
        tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT,
676
 
                                                 tex->mip_macrotile[level]);
677
 
        height = align(height, tile_height);
678
 
    }
679
 
 
680
 
    return util_format_get_nblocksy(tex->tex.format, height);
681
 
}
682
 
 
683
 
static void r300_setup_miptree(struct r300_screen* screen,
684
 
                               struct r300_texture* tex)
685
 
{
686
 
    struct pipe_texture* base = &tex->tex;
687
 
    unsigned stride, size, layer_size, nblocksy, i;
688
 
    boolean rv350_mode = screen->caps->family >= CHIP_FAMILY_RV350;
689
 
 
690
 
    SCREEN_DBG(screen, DBG_TEX, "r300: Making miptree for texture, format %s\n",
691
 
               util_format_name(base->format));
692
 
 
693
 
    for (i = 0; i <= base->last_level; i++) {
694
 
        /* Let's see if this miplevel can be macrotiled. */
695
 
        tex->mip_macrotile[i] = (tex->macrotile == R300_BUFFER_TILED &&
696
 
                                 r300_texture_macro_switch(tex, i, rv350_mode)) ?
697
 
                                 R300_BUFFER_TILED : R300_BUFFER_LINEAR;
698
 
 
699
 
        stride = r300_texture_get_stride(screen, tex, i);
700
 
        nblocksy = r300_texture_get_nblocksy(tex, i);
701
 
        layer_size = stride * nblocksy;
702
 
 
703
 
        if (base->target == PIPE_TEXTURE_CUBE)
704
 
            size = layer_size * 6;
705
 
        else
706
 
            size = layer_size * u_minify(base->depth0, i);
707
 
 
708
 
        tex->offset[i] = tex->size;
709
 
        tex->size = tex->offset[i] + size;
710
 
        tex->layer_size[i] = layer_size;
711
 
        tex->pitch[i] = stride / util_format_get_blocksize(base->format);
712
 
 
713
 
        SCREEN_DBG(screen, DBG_TEX, "r300: Texture miptree: Level %d "
714
 
                "(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n",
715
 
                i, u_minify(base->width0, i), u_minify(base->height0, i),
716
 
                u_minify(base->depth0, i), stride, tex->size,
717
 
                tex->mip_macrotile[i] ? "TRUE" : "FALSE");
718
 
    }
719
 
}
720
 
 
721
 
static void r300_setup_flags(struct r300_texture* tex)
722
 
{
723
 
    tex->is_npot = !util_is_power_of_two(tex->tex.width0) ||
724
 
                   !util_is_power_of_two(tex->tex.height0);
 
634
    r300_texture_setup_fb_state(r300_screen(screen), r300_texture(tex));
 
635
}
 
636
 
 
637
static unsigned r300_texture_is_referenced(struct pipe_context *context,
 
638
                                         struct pipe_resource *texture,
 
639
                                         unsigned face, unsigned level)
 
640
{
 
641
    struct r300_context *r300 = r300_context(context);
 
642
    struct r300_texture *rtex = (struct r300_texture *)texture;
 
643
 
 
644
    if (r300->rws->cs_is_buffer_referenced(r300->cs,
 
645
                                           rtex->buffer, R300_REF_CS))
 
646
        return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
 
647
 
 
648
    return PIPE_UNREFERENCED;
 
649
}
 
650
 
 
651
static void r300_texture_destroy(struct pipe_screen *screen,
 
652
                                 struct pipe_resource* texture)
 
653
{
 
654
    struct r300_texture* tex = (struct r300_texture*)texture;
 
655
    struct r300_winsys_screen *rws = (struct r300_winsys_screen *)texture->screen->winsys;
 
656
    int i;
 
657
 
 
658
    rws->buffer_reference(rws, &tex->buffer, NULL);
 
659
    for (i = 0; i < R300_MAX_TEXTURE_LEVELS; i++) {
 
660
        if (tex->hiz_mem[i])
 
661
            u_mmFreeMem(tex->hiz_mem[i]);
 
662
        if (tex->zmask_mem[i])
 
663
            u_mmFreeMem(tex->zmask_mem[i]);
 
664
    }
 
665
 
 
666
    FREE(tex);
 
667
}
 
668
 
 
669
static boolean r300_texture_get_handle(struct pipe_screen* screen,
 
670
                                       struct pipe_resource *texture,
 
671
                                       struct winsys_handle *whandle)
 
672
{
 
673
    struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
 
674
    struct r300_texture* tex = (struct r300_texture*)texture;
 
675
 
 
676
    if (!tex) {
 
677
        return FALSE;
 
678
    }
 
679
 
 
680
    return rws->buffer_get_handle(rws, tex->buffer,
 
681
                                  tex->desc.stride_in_bytes[0], whandle);
 
682
}
 
683
 
 
684
struct u_resource_vtbl r300_texture_vtbl =
 
685
{
 
686
   r300_texture_get_handle,           /* get_handle */
 
687
   r300_texture_destroy,              /* resource_destroy */
 
688
   r300_texture_is_referenced,        /* is_resource_referenced */
 
689
   r300_texture_get_transfer,         /* get_transfer */
 
690
   r300_texture_transfer_destroy,     /* transfer_destroy */
 
691
   r300_texture_transfer_map,         /* transfer_map */
 
692
   u_default_transfer_flush_region,   /* transfer_flush_region */
 
693
   r300_texture_transfer_unmap,       /* transfer_unmap */
 
694
   u_default_transfer_inline_write    /* transfer_inline_write */
 
695
};
 
696
 
 
697
/* The common texture constructor. */
 
698
static struct r300_texture*
 
699
r300_texture_create_object(struct r300_screen *rscreen,
 
700
                           const struct pipe_resource *base,
 
701
                           enum r300_buffer_tiling microtile,
 
702
                           enum r300_buffer_tiling macrotile,
 
703
                           unsigned stride_in_bytes_override,
 
704
                           unsigned max_buffer_size,
 
705
                           struct r300_winsys_buffer *buffer)
 
706
{
 
707
    struct r300_winsys_screen *rws = rscreen->rws;
 
708
    struct r300_texture *tex = CALLOC_STRUCT(r300_texture);
 
709
    if (!tex) {
 
710
        if (buffer)
 
711
            rws->buffer_reference(rws, &buffer, NULL);
 
712
        return NULL;
 
713
    }
 
714
 
 
715
    /* Initialize the descriptor. */
 
716
    if (!r300_texture_desc_init(rscreen, &tex->desc, base,
 
717
                                microtile, macrotile,
 
718
                                stride_in_bytes_override,
 
719
                                max_buffer_size)) {
 
720
        if (buffer)
 
721
            rws->buffer_reference(rws, &buffer, NULL);
 
722
        FREE(tex);
 
723
        return NULL;
 
724
    }
 
725
    /* Initialize the hardware state. */
 
726
    r300_texture_setup_format_state(rscreen, &tex->desc, 0, &tex->tx_format);
 
727
    r300_texture_setup_fb_state(rscreen, tex);
 
728
 
 
729
    tex->desc.b.vtbl = &r300_texture_vtbl;
 
730
    pipe_reference_init(&tex->desc.b.b.reference, 1);
 
731
    tex->domain = base->flags & R300_RESOURCE_FLAG_TRANSFER ?
 
732
                  R300_DOMAIN_GTT :
 
733
                  R300_DOMAIN_VRAM | R300_DOMAIN_GTT;
 
734
    tex->buffer = buffer;
 
735
 
 
736
    /* Create the backing buffer if needed. */
 
737
    if (!tex->buffer) {
 
738
        tex->buffer = rws->buffer_create(rws, tex->desc.size_in_bytes, 2048,
 
739
                                         base->bind, base->usage, tex->domain);
 
740
 
 
741
        if (!tex->buffer) {
 
742
            FREE(tex);
 
743
            return NULL;
 
744
        }
 
745
    }
 
746
 
 
747
    rws->buffer_set_tiling(rws, tex->buffer,
 
748
            tex->desc.microtile, tex->desc.macrotile[0],
 
749
            tex->desc.stride_in_bytes[0]);
 
750
 
 
751
    return tex;
725
752
}
726
753
 
727
754
/* Create a new texture. */
728
 
static struct pipe_texture*
729
 
    r300_texture_create(struct pipe_screen* screen,
730
 
                        const struct pipe_texture* template)
731
 
{
732
 
    struct r300_texture* tex = CALLOC_STRUCT(r300_texture);
733
 
    struct r300_screen* rscreen = r300_screen(screen);
734
 
    struct radeon_winsys* winsys = (struct radeon_winsys*)screen->winsys;
735
 
 
736
 
    if (!tex) {
737
 
        return NULL;
738
 
    }
739
 
 
740
 
    tex->tex = *template;
741
 
    pipe_reference_init(&tex->tex.reference, 1);
742
 
    tex->tex.screen = screen;
743
 
 
744
 
    r300_setup_flags(tex);
745
 
    r300_setup_miptree(rscreen, tex);
746
 
    r300_setup_texture_state(rscreen, tex);
747
 
 
748
 
    tex->buffer = screen->buffer_create(screen, 2048,
749
 
                                        PIPE_BUFFER_USAGE_PIXEL,
750
 
                                        tex->size);
751
 
    winsys->buffer_set_tiling(winsys, tex->buffer,
752
 
                              tex->pitch[0],
753
 
                              tex->microtile != R300_BUFFER_LINEAR,
754
 
                              tex->macrotile != R300_BUFFER_LINEAR);
755
 
 
756
 
    if (!tex->buffer) {
757
 
        FREE(tex);
758
 
        return NULL;
759
 
    }
760
 
 
761
 
    return (struct pipe_texture*)tex;
762
 
}
763
 
 
764
 
static void r300_texture_destroy(struct pipe_texture* texture)
765
 
{
766
 
    struct r300_texture* tex = (struct r300_texture*)texture;
767
 
 
768
 
    pipe_buffer_reference(&tex->buffer, NULL);
769
 
 
770
 
    FREE(tex);
771
 
}
772
 
 
773
 
static struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen,
774
 
                                                 struct pipe_texture* texture,
775
 
                                                 unsigned face,
776
 
                                                 unsigned level,
777
 
                                                 unsigned zslice,
778
 
                                                 unsigned flags)
779
 
{
780
 
    struct r300_texture* tex = (struct r300_texture*)texture;
781
 
    struct pipe_surface* surface = CALLOC_STRUCT(pipe_surface);
782
 
    unsigned offset;
783
 
 
784
 
    offset = r300_texture_get_offset(tex, level, zslice, face);
785
 
 
786
 
    if (surface) {
787
 
        pipe_reference_init(&surface->reference, 1);
788
 
        pipe_texture_reference(&surface->texture, texture);
789
 
        surface->format = texture->format;
790
 
        surface->width = u_minify(texture->width0, level);
791
 
        surface->height = u_minify(texture->height0, level);
792
 
        surface->offset = offset;
793
 
        surface->usage = flags;
794
 
        surface->zslice = zslice;
795
 
        surface->texture = texture;
796
 
        surface->face = face;
797
 
        surface->level = level;
798
 
    }
799
 
 
800
 
    return surface;
801
 
}
802
 
 
803
 
static void r300_tex_surface_destroy(struct pipe_surface* s)
804
 
{
805
 
    pipe_texture_reference(&s->texture, NULL);
806
 
    FREE(s);
807
 
}
808
 
 
809
 
static struct pipe_texture*
810
 
    r300_texture_blanket(struct pipe_screen* screen,
811
 
                         const struct pipe_texture* base,
812
 
                         const unsigned* stride,
813
 
                         struct pipe_buffer* buffer)
814
 
{
815
 
    struct r300_texture* tex;
816
 
    struct r300_screen* rscreen = r300_screen(screen);
 
755
struct pipe_resource *r300_texture_create(struct pipe_screen *screen,
 
756
                                          const struct pipe_resource *base)
 
757
{
 
758
    struct r300_screen *rscreen = r300_screen(screen);
 
759
    enum r300_buffer_tiling microtile, macrotile;
 
760
 
 
761
    if ((base->flags & R300_RESOURCE_FLAG_TRANSFER) ||
 
762
        (base->bind & PIPE_BIND_SCANOUT)) {
 
763
        microtile = R300_BUFFER_LINEAR;
 
764
        macrotile = R300_BUFFER_LINEAR;
 
765
    } else {
 
766
        microtile = R300_BUFFER_SELECT_LAYOUT;
 
767
        macrotile = R300_BUFFER_SELECT_LAYOUT;
 
768
    }
 
769
 
 
770
    return (struct pipe_resource*)
 
771
           r300_texture_create_object(rscreen, base, microtile, macrotile,
 
772
                                      0, 0, NULL);
 
773
}
 
774
 
 
775
struct pipe_resource *r300_texture_from_handle(struct pipe_screen *screen,
 
776
                                               const struct pipe_resource *base,
 
777
                                               struct winsys_handle *whandle)
 
778
{
 
779
    struct r300_winsys_screen *rws = (struct r300_winsys_screen*)screen->winsys;
 
780
    struct r300_screen *rscreen = r300_screen(screen);
 
781
    struct r300_winsys_buffer *buffer;
 
782
    enum r300_buffer_tiling microtile, macrotile;
 
783
    unsigned stride, size;
817
784
 
818
785
    /* Support only 2D textures without mipmaps */
819
 
    if (base->target != PIPE_TEXTURE_2D ||
 
786
    if ((base->target != PIPE_TEXTURE_2D &&
 
787
          base->target != PIPE_TEXTURE_RECT) ||
820
788
        base->depth0 != 1 ||
821
789
        base->last_level != 0) {
822
790
        return NULL;
823
791
    }
824
792
 
825
 
    tex = CALLOC_STRUCT(r300_texture);
826
 
    if (!tex) {
827
 
        return NULL;
828
 
    }
829
 
 
830
 
    tex->tex = *base;
831
 
    pipe_reference_init(&tex->tex.reference, 1);
832
 
    tex->tex.screen = screen;
833
 
 
834
 
    tex->stride_override = *stride;
835
 
    tex->pitch[0] = *stride / util_format_get_blocksize(base->format);
836
 
 
837
 
    r300_setup_flags(tex);
838
 
    r300_setup_texture_state(rscreen, tex);
839
 
 
840
 
    pipe_buffer_reference(&tex->buffer, buffer);
841
 
 
842
 
    return (struct pipe_texture*)tex;
843
 
}
844
 
 
845
 
static struct pipe_video_surface *
846
 
r300_video_surface_create(struct pipe_screen *screen,
847
 
                          enum pipe_video_chroma_format chroma_format,
848
 
                          unsigned width, unsigned height)
849
 
{
850
 
    struct r300_video_surface *r300_vsfc;
851
 
    struct pipe_texture template;
852
 
 
853
 
    assert(screen);
854
 
    assert(width && height);
855
 
 
856
 
    r300_vsfc = CALLOC_STRUCT(r300_video_surface);
857
 
    if (!r300_vsfc)
858
 
       return NULL;
859
 
 
860
 
    pipe_reference_init(&r300_vsfc->base.reference, 1);
861
 
    r300_vsfc->base.screen = screen;
862
 
    r300_vsfc->base.chroma_format = chroma_format;
863
 
    r300_vsfc->base.width = width;
864
 
    r300_vsfc->base.height = height;
865
 
 
866
 
    memset(&template, 0, sizeof(struct pipe_texture));
867
 
    template.target = PIPE_TEXTURE_2D;
868
 
    template.format = PIPE_FORMAT_B8G8R8X8_UNORM;
869
 
    template.last_level = 0;
870
 
    template.width0 = util_next_power_of_two(width);
871
 
    template.height0 = util_next_power_of_two(height);
872
 
    template.depth0 = 1;
873
 
    template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER |
874
 
                         PIPE_TEXTURE_USAGE_RENDER_TARGET;
875
 
 
876
 
    r300_vsfc->tex = screen->texture_create(screen, &template);
877
 
    if (!r300_vsfc->tex)
878
 
    {
879
 
        FREE(r300_vsfc);
880
 
        return NULL;
881
 
    }
882
 
 
883
 
    return &r300_vsfc->base;
884
 
}
885
 
 
886
 
static void r300_video_surface_destroy(struct pipe_video_surface *vsfc)
887
 
{
888
 
    struct r300_video_surface *r300_vsfc = r300_video_surface(vsfc);
889
 
    pipe_texture_reference(&r300_vsfc->tex, NULL);
890
 
    FREE(r300_vsfc);
891
 
}
892
 
 
893
 
void r300_init_screen_texture_functions(struct pipe_screen* screen)
894
 
{
895
 
    screen->texture_create = r300_texture_create;
896
 
    screen->texture_destroy = r300_texture_destroy;
897
 
    screen->get_tex_surface = r300_get_tex_surface;
898
 
    screen->tex_surface_destroy = r300_tex_surface_destroy;
899
 
    screen->texture_blanket = r300_texture_blanket;
900
 
 
901
 
    screen->video_surface_create = r300_video_surface_create;
902
 
    screen->video_surface_destroy= r300_video_surface_destroy;
903
 
}
904
 
 
905
 
boolean r300_get_texture_buffer(struct pipe_screen* screen,
906
 
                                struct pipe_texture* texture,
907
 
                                struct pipe_buffer** buffer,
908
 
                                unsigned* stride)
909
 
{
910
 
    struct r300_texture* tex = (struct r300_texture*)texture;
911
 
    if (!tex) {
912
 
        return FALSE;
913
 
    }
914
 
 
915
 
    pipe_buffer_reference(buffer, tex->buffer);
916
 
 
917
 
    if (stride) {
918
 
        *stride = r300_texture_get_stride(r300_screen(screen), tex, 0);
919
 
    }
920
 
 
921
 
    return TRUE;
 
793
    buffer = rws->buffer_from_handle(rws, whandle, &stride, &size);
 
794
    if (!buffer)
 
795
        return NULL;
 
796
 
 
797
    rws->buffer_get_tiling(rws, buffer, &microtile, &macrotile);
 
798
 
 
799
    /* Enforce a microtiled zbuffer. */
 
800
    if (util_format_is_depth_or_stencil(base->format) &&
 
801
        microtile == R300_BUFFER_LINEAR) {
 
802
        switch (util_format_get_blocksize(base->format)) {
 
803
            case 4:
 
804
                microtile = R300_BUFFER_TILED;
 
805
                break;
 
806
 
 
807
            case 2:
 
808
                if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT))
 
809
                    microtile = R300_BUFFER_SQUARETILED;
 
810
                break;
 
811
        }
 
812
    }
 
813
 
 
814
    return (struct pipe_resource*)
 
815
           r300_texture_create_object(rscreen, base, microtile, macrotile,
 
816
                                      stride, size, buffer);
 
817
}
 
818
 
 
819
/* Not required to implement u_resource_vtbl, consider moving to another file:
 
820
 */
 
821
struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen,
 
822
                                          struct pipe_resource* texture,
 
823
                                          unsigned face,
 
824
                                          unsigned level,
 
825
                                          unsigned zslice,
 
826
                                          unsigned flags)
 
827
{
 
828
    struct r300_texture* tex = r300_texture(texture);
 
829
    struct r300_surface* surface = CALLOC_STRUCT(r300_surface);
 
830
 
 
831
    if (surface) {
 
832
        uint32_t offset, tile_height;
 
833
 
 
834
        pipe_reference_init(&surface->base.reference, 1);
 
835
        pipe_resource_reference(&surface->base.texture, texture);
 
836
        surface->base.format = texture->format;
 
837
        surface->base.width = u_minify(texture->width0, level);
 
838
        surface->base.height = u_minify(texture->height0, level);
 
839
        surface->base.usage = flags;
 
840
        surface->base.zslice = zslice;
 
841
        surface->base.face = face;
 
842
        surface->base.level = level;
 
843
 
 
844
        surface->buffer = tex->buffer;
 
845
 
 
846
        /* Prefer VRAM if there are multiple domains to choose from. */
 
847
        surface->domain = tex->domain;
 
848
        if (surface->domain & R300_DOMAIN_VRAM)
 
849
            surface->domain &= ~R300_DOMAIN_GTT;
 
850
 
 
851
        surface->offset = r300_texture_get_offset(&tex->desc,
 
852
                                                  level, zslice, face);
 
853
        surface->pitch = tex->fb_state.pitch[level];
 
854
        surface->format = tex->fb_state.format;
 
855
 
 
856
        /* Parameters for the CBZB clear. */
 
857
        surface->cbzb_allowed = tex->desc.cbzb_allowed[level];
 
858
        surface->cbzb_width = align(surface->base.width, 64);
 
859
 
 
860
        /* Height must be aligned to the size of a tile. */
 
861
        tile_height = r300_get_pixel_alignment(tex->desc.b.b.format,
 
862
                                               tex->desc.b.b.nr_samples,
 
863
                                               tex->desc.microtile,
 
864
                                               tex->desc.macrotile[level],
 
865
                                               DIM_HEIGHT);
 
866
 
 
867
        surface->cbzb_height = align((surface->base.height + 1) / 2,
 
868
                                     tile_height);
 
869
 
 
870
        /* Offset must be aligned to 2K and must point at the beginning
 
871
         * of a scanline. */
 
872
        offset = surface->offset +
 
873
                 tex->desc.stride_in_bytes[level] * surface->cbzb_height;
 
874
        surface->cbzb_midpoint_offset = offset & ~2047;
 
875
 
 
876
        surface->cbzb_pitch = surface->pitch & 0x1ffffc;
 
877
 
 
878
        if (util_format_get_blocksizebits(surface->base.format) == 32)
 
879
            surface->cbzb_format = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
 
880
        else
 
881
            surface->cbzb_format = R300_DEPTHFORMAT_16BIT_INT_Z;
 
882
 
 
883
        SCREEN_DBG(r300_screen(screen), DBG_CBZB,
 
884
                   "CBZB Dim: %ix%i, Misalignment: %i, Macro: %s\n",
 
885
                   surface->cbzb_width, surface->cbzb_height,
 
886
                   offset & 2047,
 
887
                   tex->desc.macrotile[level] ? "YES" : " NO");
 
888
    }
 
889
 
 
890
    return &surface->base;
 
891
}
 
892
 
 
893
/* Not required to implement u_resource_vtbl, consider moving to another file:
 
894
 */
 
895
void r300_tex_surface_destroy(struct pipe_surface* s)
 
896
{
 
897
    pipe_resource_reference(&s->texture, NULL);
 
898
    FREE(s);
922
899
}