Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 1
/*
2
 * Copyright 2008 Corbin Simpson 
3
 * Copyright 2010 Marek Olšák 
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
#include "util/u_format.h"
25
#include "util/u_format_s3tc.h"
26
#include "util/u_memory.h"
27
#include "os/os_time.h"
28
#include "vl/vl_decoder.h"
29
#include "vl/vl_video_buffer.h"
30
 
31
#include "r300_context.h"
32
#include "r300_texture.h"
33
#include "r300_screen_buffer.h"
34
#include "r300_state_inlines.h"
35
#include "r300_public.h"
36
 
37
#include "draw/draw_context.h"
38
 
39
/* Return the identifier behind whom the brave coders responsible for this
40
 * amalgamation of code, sweat, and duct tape, routinely obscure their names.
41
 *
42
 * ...I should have just put "Corbin Simpson", but I'm not that cool.
43
 *
44
 * (Or egotistical. Yet.) */
45
static const char* r300_get_vendor(struct pipe_screen* pscreen)
46
{
47
    return "X.Org R300 Project";
48
}
49
 
50
static const char* r300_get_device_vendor(struct pipe_screen* pscreen)
51
{
52
    return "ATI";
53
}
54
 
55
static const char* chip_families[] = {
56
    "unknown",
57
    "ATI R300",
58
    "ATI R350",
59
    "ATI RV350",
60
    "ATI RV370",
61
    "ATI RV380",
62
    "ATI RS400",
63
    "ATI RC410",
64
    "ATI RS480",
65
    "ATI R420",
66
    "ATI R423",
67
    "ATI R430",
68
    "ATI R480",
69
    "ATI R481",
70
    "ATI RV410",
71
    "ATI RS600",
72
    "ATI RS690",
73
    "ATI RS740",
74
    "ATI RV515",
75
    "ATI R520",
76
    "ATI RV530",
77
    "ATI R580",
78
    "ATI RV560",
79
    "ATI RV570"
80
};
81
 
82
static const char* r300_get_name(struct pipe_screen* pscreen)
83
{
84
    struct r300_screen* r300screen = r300_screen(pscreen);
85
 
86
    return chip_families[r300screen->caps.family];
87
}
88
 
89
static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
90
{
91
    struct r300_screen* r300screen = r300_screen(pscreen);
92
    boolean is_r500 = r300screen->caps.is_r500;
93
 
94
    switch (param) {
95
        /* Supported features (boolean caps). */
96
        case PIPE_CAP_NPOT_TEXTURES:
97
        case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
98
        case PIPE_CAP_TWO_SIDED_STENCIL:
99
        case PIPE_CAP_ANISOTROPIC_FILTER:
100
        case PIPE_CAP_POINT_SPRITE:
101
        case PIPE_CAP_OCCLUSION_QUERY:
102
        case PIPE_CAP_TEXTURE_SHADOW_MAP:
103
        case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
104
        case PIPE_CAP_BLEND_EQUATION_SEPARATE:
105
        case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
106
        case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
107
        case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
108
        case PIPE_CAP_CONDITIONAL_RENDER:
109
        case PIPE_CAP_TEXTURE_BARRIER:
110
        case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
111
        case PIPE_CAP_USER_INDEX_BUFFERS:
112
        case PIPE_CAP_USER_CONSTANT_BUFFERS:
113
        case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
114
        case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
115
        case PIPE_CAP_CLIP_HALFZ:
116
            return 1;
117
 
118
        case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
119
            return R300_BUFFER_ALIGNMENT;
120
 
121
        case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
122
            return 16;
123
 
124
        case PIPE_CAP_GLSL_FEATURE_LEVEL:
125
            return 120;
126
 
127
        /* r300 cannot do swizzling of compressed textures. Supported otherwise. */
128
        case PIPE_CAP_TEXTURE_SWIZZLE:
129
            return util_format_s3tc_enabled ? r300screen->caps.dxtc_swizzle : 1;
130
 
131
        /* We don't support color clamping on r500, so that we can use color
132
         * intepolators for generic varyings. */
133
        case PIPE_CAP_VERTEX_COLOR_CLAMPED:
134
            return !is_r500;
135
 
136
        /* Supported on r500 only. */
137
        case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
138
        case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
139
        case PIPE_CAP_SM3:
140
            return is_r500 ? 1 : 0;
141
 
142
        /* Unsupported features. */
143
        case PIPE_CAP_QUERY_TIME_ELAPSED:
144
        case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
145
        case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
146
        case PIPE_CAP_INDEP_BLEND_ENABLE:
147
        case PIPE_CAP_INDEP_BLEND_FUNC:
148
        case PIPE_CAP_DEPTH_CLIP_DISABLE:
149
        case PIPE_CAP_SHADER_STENCIL_EXPORT:
150
        case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
151
        case PIPE_CAP_TGSI_INSTANCEID:
152
        case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
153
        case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
154
        case PIPE_CAP_SEAMLESS_CUBE_MAP:
155
        case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
156
        case PIPE_CAP_MIN_TEXEL_OFFSET:
157
        case PIPE_CAP_MAX_TEXEL_OFFSET:
158
        case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET:
159
        case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
160
        case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
161
        case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
162
        case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
163
        case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES:
164
        case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS:
165
        case PIPE_CAP_MAX_VERTEX_STREAMS:
166
        case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
167
        case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
168
        case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
169
        case PIPE_CAP_COMPUTE:
170
        case PIPE_CAP_START_INSTANCE:
171
        case PIPE_CAP_QUERY_TIMESTAMP:
172
        case PIPE_CAP_TEXTURE_MULTISAMPLE:
173
        case PIPE_CAP_CUBE_MAP_ARRAY:
174
        case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
175
        case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
176
        case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
177
        case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
178
        case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
179
        case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
180
        case PIPE_CAP_TEXTURE_GATHER_SM5:
181
        case PIPE_CAP_TEXTURE_QUERY_LOD:
182
        case PIPE_CAP_FAKE_SW_MSAA:
183
        case PIPE_CAP_SAMPLE_SHADING:
184
        case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
185
        case PIPE_CAP_DRAW_INDIRECT:
186
        case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
187
        case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
188
        case PIPE_CAP_SAMPLER_VIEW_TARGET:
189
        case PIPE_CAP_VERTEXID_NOBASE:
190
        case PIPE_CAP_POLYGON_OFFSET_CLAMP:
191
        case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
192
        case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
193
        case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
194
            return 0;
195
 
196
        /* SWTCL-only features. */
197
        case PIPE_CAP_PRIMITIVE_RESTART:
198
        case PIPE_CAP_USER_VERTEX_BUFFERS:
199
        case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
200
            return !r300screen->caps.has_tcl;
201
 
202
        /* HWTCL-only features / limitations. */
203
        case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
204
        case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
205
        case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
206
            return r300screen->caps.has_tcl;
207
	case PIPE_CAP_TGSI_TEXCOORD:
208
            return 0;
209
 
210
        /* Texturing. */
211
        case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
212
        case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
213
        case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
214
            /* 13 == 4096, 12 == 2048 */
215
            return is_r500 ? 13 : 12;
216
 
217
        /* Render targets. */
218
        case PIPE_CAP_MAX_RENDER_TARGETS:
219
            return 4;
220
	case PIPE_CAP_ENDIANNESS:
221
            return PIPE_ENDIAN_LITTLE;
222
 
223
        case PIPE_CAP_MAX_VIEWPORTS:
224
            return 1;
225
 
226
        case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
227
            return 2048;
228
 
229
        case PIPE_CAP_VENDOR_ID:
230
                return 0x1002;
231
        case PIPE_CAP_DEVICE_ID:
232
                return r300screen->info.pci_id;
233
        case PIPE_CAP_ACCELERATED:
234
                return 1;
235
        case PIPE_CAP_VIDEO_MEMORY:
236
                return r300screen->info.vram_size >> 20;
237
        case PIPE_CAP_UMA:
238
                return 0;
239
    }
240
    return 0;
241
}
242
 
243
static int r300_get_shader_param(struct pipe_screen *pscreen, unsigned shader, enum pipe_shader_cap param)
244
{
245
   struct r300_screen* r300screen = r300_screen(pscreen);
246
   boolean is_r400 = r300screen->caps.is_r400;
247
   boolean is_r500 = r300screen->caps.is_r500;
248
 
249
   switch (shader) {
250
    case PIPE_SHADER_FRAGMENT:
251
        switch (param)
252
        {
253
        case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
254
            return is_r500 || is_r400 ? 512 : 96;
255
        case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
256
            return is_r500 || is_r400 ? 512 : 64;
257
        case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
258
            return is_r500 || is_r400 ? 512 : 32;
259
        case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
260
            return is_r500 ? 511 : 4;
261
        case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
262
            return is_r500 ? 64 : 0; /* Actually unlimited on r500. */
263
            /* Fragment shader limits. */
264
        case PIPE_SHADER_CAP_MAX_INPUTS:
265
            /* 2 colors + 8 texcoords are always supported
266
             * (minus fog and wpos).
267
             *
268
             * R500 has the ability to turn 3rd and 4th color into
269
             * additional texcoords but there is no two-sided color
270
             * selection then. However the facing bit can be used instead. */
271
            return 10;
272
        case PIPE_SHADER_CAP_MAX_OUTPUTS:
273
            return 4;
274
        case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
275
            return (is_r500 ? 256 : 32) * sizeof(float[4]);
276
        case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
277
            return 1;
278
        case PIPE_SHADER_CAP_MAX_TEMPS:
279
            return is_r500 ? 128 : is_r400 ? 64 : 32;
280
        case PIPE_SHADER_CAP_MAX_PREDS:
281
            return 0; /* unused */
282
        case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
283
        case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
284
           return r300screen->caps.num_tex_units;
285
        case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
286
        case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
287
        case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
288
        case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
289
        case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
290
        case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
291
        case PIPE_SHADER_CAP_SUBROUTINES:
292
        case PIPE_SHADER_CAP_INTEGERS:
293
        case PIPE_SHADER_CAP_DOUBLES:
294
        case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
295
        case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
296
        case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
297
            return 0;
298
        case PIPE_SHADER_CAP_PREFERRED_IR:
299
            return PIPE_SHADER_IR_TGSI;
300
        }
301
        break;
302
    case PIPE_SHADER_VERTEX:
303
        switch (param)
304
        {
305
        case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
306
        case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
307
        case PIPE_SHADER_CAP_SUBROUTINES:
308
            return 0;
309
        default:;
310
        }
311
 
312
        if (!r300screen->caps.has_tcl) {
313
            return draw_get_shader_param(shader, param);
314
        }
315
 
316
        switch (param)
317
        {
318
        case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
319
        case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
320
            return is_r500 ? 1024 : 256;
321
        case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
322
            return is_r500 ? 4 : 0; /* For loops; not sure about conditionals. */
323
        case PIPE_SHADER_CAP_MAX_INPUTS:
324
            return 16;
325
        case PIPE_SHADER_CAP_MAX_OUTPUTS:
326
            return 10;
327
        case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
328
            return 256 * sizeof(float[4]);
329
        case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
330
            return 1;
331
        case PIPE_SHADER_CAP_MAX_TEMPS:
332
            return 32;
333
        case PIPE_SHADER_CAP_MAX_PREDS:
334
            return 0; /* unused */
335
        case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
336
            return 1;
337
        case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
338
        case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
339
        case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
340
        case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
341
        case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
342
        case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
343
        case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
344
        case PIPE_SHADER_CAP_SUBROUTINES:
345
        case PIPE_SHADER_CAP_INTEGERS:
346
        case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
347
        case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
348
        case PIPE_SHADER_CAP_DOUBLES:
349
        case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
350
        case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
351
        case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
352
            return 0;
353
        case PIPE_SHADER_CAP_PREFERRED_IR:
354
            return PIPE_SHADER_IR_TGSI;
355
        }
356
        break;
357
    }
358
    return 0;
359
}
360
 
361
static float r300_get_paramf(struct pipe_screen* pscreen,
362
                             enum pipe_capf param)
363
{
364
    struct r300_screen* r300screen = r300_screen(pscreen);
365
 
366
    switch (param) {
367
        case PIPE_CAPF_MAX_LINE_WIDTH:
368
        case PIPE_CAPF_MAX_LINE_WIDTH_AA:
369
        case PIPE_CAPF_MAX_POINT_WIDTH:
370
        case PIPE_CAPF_MAX_POINT_WIDTH_AA:
371
            /* The maximum dimensions of the colorbuffer are our practical
372
             * rendering limits. 2048 pixels should be enough for anybody. */
373
            if (r300screen->caps.is_r500) {
374
                return 4096.0f;
375
            } else if (r300screen->caps.is_r400) {
376
                return 4021.0f;
377
            } else {
378
                return 2560.0f;
379
            }
380
        case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
381
            return 16.0f;
382
        case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
383
            return 16.0f;
384
        case PIPE_CAPF_GUARD_BAND_LEFT:
385
        case PIPE_CAPF_GUARD_BAND_TOP:
386
        case PIPE_CAPF_GUARD_BAND_RIGHT:
387
        case PIPE_CAPF_GUARD_BAND_BOTTOM:
388
            return 0.0f;
389
        default:
390
            debug_printf("r300: Warning: Unknown CAP %d in get_paramf.\n",
391
                         param);
392
            return 0.0f;
393
    }
394
}
395
 
396
static int r300_get_video_param(struct pipe_screen *screen,
397
				enum pipe_video_profile profile,
398
				enum pipe_video_entrypoint entrypoint,
399
				enum pipe_video_cap param)
400
{
401
   switch (param) {
402
      case PIPE_VIDEO_CAP_SUPPORTED:
403
         return vl_profile_supported(screen, profile, entrypoint);
404
      case PIPE_VIDEO_CAP_NPOT_TEXTURES:
405
         return 0;
406
      case PIPE_VIDEO_CAP_MAX_WIDTH:
407
      case PIPE_VIDEO_CAP_MAX_HEIGHT:
408
         return vl_video_buffer_max_size(screen);
409
      case PIPE_VIDEO_CAP_PREFERED_FORMAT:
410
         return PIPE_FORMAT_NV12;
411
      case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
412
         return false;
413
      case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
414
         return false;
415
      case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
416
         return true;
417
      case PIPE_VIDEO_CAP_MAX_LEVEL:
418
         return vl_level_supported(screen, profile);
419
      default:
420
         return 0;
421
   }
422
}
423
 
424
/**
425
 * Whether the format matches:
426
 *   PIPE_FORMAT_?10?10?10?2_UNORM
427
 */
428
static INLINE boolean
429
util_format_is_rgba1010102_variant(const struct util_format_description *desc)
430
{
431
   static const unsigned size[4] = {10, 10, 10, 2};
432
   unsigned chan;
433
 
434
   if (desc->block.width != 1 ||
435
       desc->block.height != 1 ||
436
       desc->block.bits != 32)
437
      return FALSE;
438
 
439
   for (chan = 0; chan < 4; ++chan) {
440
      if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED &&
441
         desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID)
442
         return FALSE;
443
      if (desc->channel[chan].size != size[chan])
444
         return FALSE;
445
   }
446
 
447
   return TRUE;
448
}
449
 
450
static bool r300_is_blending_supported(struct r300_screen *rscreen,
451
                                       enum pipe_format format)
452
{
453
    int c;
454
    const struct util_format_description *desc =
455
        util_format_description(format);
456
 
457
    if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
458
        return false;
459
 
460
    c = util_format_get_first_non_void_channel(format);
461
 
462
    /* RGBA16F */
463
    if (rscreen->caps.is_r500 &&
464
        desc->nr_channels == 4 &&
465
        desc->channel[c].size == 16 &&
466
        desc->channel[c].type == UTIL_FORMAT_TYPE_FLOAT)
467
        return true;
468
 
469
    if (desc->channel[c].normalized &&
470
        desc->channel[c].type == UTIL_FORMAT_TYPE_UNSIGNED &&
471
        desc->channel[c].size >= 4 &&
472
        desc->channel[c].size <= 10) {
473
        /* RGB10_A2, RGBA8, RGB5_A1, RGBA4, RGB565 */
474
        if (desc->nr_channels >= 3)
475
            return true;
476
 
477
        if (format == PIPE_FORMAT_R8G8_UNORM)
478
            return true;
479
 
480
        /* R8, I8, L8, A8 */
481
        if (desc->nr_channels == 1)
482
            return true;
483
    }
484
 
485
    return false;
486
}
487
 
488
static boolean r300_is_format_supported(struct pipe_screen* screen,
489
                                        enum pipe_format format,
490
                                        enum pipe_texture_target target,
491
                                        unsigned sample_count,
492
                                        unsigned usage)
493
{
494
    uint32_t retval = 0;
495
    boolean drm_2_8_0 = r300_screen(screen)->info.drm_minor >= 8;
496
    boolean is_r500 = r300_screen(screen)->caps.is_r500;
497
    boolean is_r400 = r300_screen(screen)->caps.is_r400;
498
    boolean is_color2101010 = format == PIPE_FORMAT_R10G10B10A2_UNORM ||
499
                              format == PIPE_FORMAT_R10G10B10X2_SNORM ||
500
                              format == PIPE_FORMAT_B10G10R10A2_UNORM ||
501
                              format == PIPE_FORMAT_B10G10R10X2_UNORM ||
502
                              format == PIPE_FORMAT_R10SG10SB10SA2U_NORM;
503
    boolean is_ati1n = format == PIPE_FORMAT_RGTC1_UNORM ||
504
                       format == PIPE_FORMAT_RGTC1_SNORM ||
505
                       format == PIPE_FORMAT_LATC1_UNORM ||
506
                       format == PIPE_FORMAT_LATC1_SNORM;
507
    boolean is_ati2n = format == PIPE_FORMAT_RGTC2_UNORM ||
508
                       format == PIPE_FORMAT_RGTC2_SNORM ||
509
                       format == PIPE_FORMAT_LATC2_UNORM ||
510
                       format == PIPE_FORMAT_LATC2_SNORM;
511
    boolean is_x16f_xy16f = format == PIPE_FORMAT_R16_FLOAT ||
512
                            format == PIPE_FORMAT_R16G16_FLOAT ||
513
                            format == PIPE_FORMAT_A16_FLOAT ||
514
                            format == PIPE_FORMAT_L16_FLOAT ||
515
                            format == PIPE_FORMAT_L16A16_FLOAT ||
516
                            format == PIPE_FORMAT_R16A16_FLOAT ||
517
                            format == PIPE_FORMAT_I16_FLOAT;
518
    boolean is_half_float = format == PIPE_FORMAT_R16_FLOAT ||
519
                            format == PIPE_FORMAT_R16G16_FLOAT ||
520
                            format == PIPE_FORMAT_R16G16B16_FLOAT ||
521
                            format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
522
                            format == PIPE_FORMAT_R16G16B16X16_FLOAT;
523
    const struct util_format_description *desc;
524
 
525
    if (!util_format_is_supported(format, usage))
526
       return FALSE;
527
 
528
    /* Check multisampling support. */
529
    switch (sample_count) {
530
        case 0:
531
        case 1:
532
            break;
533
        case 2:
534
        case 4:
535
        case 6:
536
            /* We need DRM 2.8.0. */
537
            if (!drm_2_8_0) {
538
                return FALSE;
539
            }
540
            /* No texturing and scanout. */
541
            if (usage & (PIPE_BIND_SAMPLER_VIEW |
542
                         PIPE_BIND_DISPLAY_TARGET |
543
                         PIPE_BIND_SCANOUT)) {
544
                return FALSE;
545
            }
546
 
547
            desc = util_format_description(format);
548
 
549
            if (is_r500) {
550
                /* Only allow depth/stencil, RGBA8, RGBA1010102, RGBA16F. */
551
                if (!util_format_is_depth_or_stencil(format) &&
552
                    !util_format_is_rgba8_variant(desc) &&
553
                    !util_format_is_rgba1010102_variant(desc) &&
554
                    format != PIPE_FORMAT_R16G16B16A16_FLOAT &&
555
                    format != PIPE_FORMAT_R16G16B16X16_FLOAT) {
556
                    return FALSE;
557
                }
558
            } else {
559
                /* Only allow depth/stencil, RGBA8. */
560
                if (!util_format_is_depth_or_stencil(format) &&
561
                    !util_format_is_rgba8_variant(desc)) {
562
                    return FALSE;
563
                }
564
            }
565
            break;
566
        default:
567
            return FALSE;
568
    }
569
 
570
    /* Check sampler format support. */
571
    if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
572
        /* these two are broken for an unknown reason */
573
        format != PIPE_FORMAT_R8G8B8X8_SNORM &&
574
        format != PIPE_FORMAT_R16G16B16X16_SNORM &&
575
        /* ATI1N is r5xx-only. */
576
        (is_r500 || !is_ati1n) &&
577
        /* ATI2N is supported on r4xx-r5xx. */
578
        (is_r400 || is_r500 || !is_ati2n) &&
579
        /* R16F and RG16F texture support was added in as late as DRM 2.8.0 */
580
        (drm_2_8_0 || !is_x16f_xy16f) &&
581
        r300_is_sampler_format_supported(format)) {
582
        retval |= PIPE_BIND_SAMPLER_VIEW;
583
    }
584
 
585
    /* Check colorbuffer format support. */
586
    if ((usage & (PIPE_BIND_RENDER_TARGET |
587
                  PIPE_BIND_DISPLAY_TARGET |
588
                  PIPE_BIND_SCANOUT |
589
                  PIPE_BIND_SHARED |
590
                  PIPE_BIND_BLENDABLE)) &&
591
        /* 2101010 cannot be rendered to on non-r5xx. */
592
        (!is_color2101010 || (is_r500 && drm_2_8_0)) &&
593
        r300_is_colorbuffer_format_supported(format)) {
594
        retval |= usage &
595
            (PIPE_BIND_RENDER_TARGET |
596
             PIPE_BIND_DISPLAY_TARGET |
597
             PIPE_BIND_SCANOUT |
598
             PIPE_BIND_SHARED);
599
 
600
        if (r300_is_blending_supported(r300_screen(screen), format)) {
601
            retval |= usage & PIPE_BIND_BLENDABLE;
602
        }
603
    }
604
 
605
    /* Check depth-stencil format support. */
606
    if (usage & PIPE_BIND_DEPTH_STENCIL &&
607
        r300_is_zs_format_supported(format)) {
608
        retval |= PIPE_BIND_DEPTH_STENCIL;
609
    }
610
 
611
    /* Check vertex buffer format support. */
612
    if (usage & PIPE_BIND_VERTEX_BUFFER) {
613
        if (r300_screen(screen)->caps.has_tcl) {
614
            /* Half float is supported on >= R400. */
615
            if ((is_r400 || is_r500 || !is_half_float) &&
616
                r300_translate_vertex_data_type(format) != R300_INVALID_FORMAT) {
617
                retval |= PIPE_BIND_VERTEX_BUFFER;
618
            }
619
        } else {
620
            /* SW TCL */
621
            if (!util_format_is_pure_integer(format)) {
622
                retval |= PIPE_BIND_VERTEX_BUFFER;
623
            }
624
        }
625
    }
626
 
627
    /* Transfers are always supported. */
628
    if (usage & PIPE_BIND_TRANSFER_READ)
629
        retval |= PIPE_BIND_TRANSFER_READ;
630
    if (usage & PIPE_BIND_TRANSFER_WRITE)
631
        retval |= PIPE_BIND_TRANSFER_WRITE;
632
 
633
    return retval == usage;
634
}
635
 
636
static void r300_destroy_screen(struct pipe_screen* pscreen)
637
{
638
    struct r300_screen* r300screen = r300_screen(pscreen);
639
    struct radeon_winsys *rws = radeon_winsys(pscreen);
640
 
641
    if (rws && !rws->unref(rws))
642
      return;
643
 
644
    pipe_mutex_destroy(r300screen->cmask_mutex);
645
 
646
    if (rws)
647
      rws->destroy(rws);
648
 
649
    FREE(r300screen);
650
}
651
 
652
static void r300_fence_reference(struct pipe_screen *screen,
653
                                 struct pipe_fence_handle **ptr,
654
                                 struct pipe_fence_handle *fence)
655
{
656
    struct radeon_winsys *rws = r300_screen(screen)->rws;
657
 
658
    rws->fence_reference(ptr, fence);
659
}
660
 
661
static boolean r300_fence_signalled(struct pipe_screen *screen,
662
                                    struct pipe_fence_handle *fence)
663
{
664
    struct radeon_winsys *rws = r300_screen(screen)->rws;
665
 
666
    return rws->fence_wait(rws, fence, 0);
667
}
668
 
669
static boolean r300_fence_finish(struct pipe_screen *screen,
670
                                 struct pipe_fence_handle *fence,
671
                                 uint64_t timeout)
672
{
673
    struct radeon_winsys *rws = r300_screen(screen)->rws;
674
 
675
    return rws->fence_wait(rws, fence, timeout);
676
}
677
 
678
struct pipe_screen* r300_screen_create(struct radeon_winsys *rws)
679
{
680
    struct r300_screen *r300screen = CALLOC_STRUCT(r300_screen);
681
 
682
    if (!r300screen) {
683
        FREE(r300screen);
684
        return NULL;
685
    }
686
 
687
    rws->query_info(rws, &r300screen->info);
688
 
689
    r300_init_debug(r300screen);
690
    r300_parse_chipset(r300screen->info.pci_id, &r300screen->caps);
691
 
692
    if (SCREEN_DBG_ON(r300screen, DBG_NO_ZMASK))
693
        r300screen->caps.zmask_ram = 0;
694
    if (SCREEN_DBG_ON(r300screen, DBG_NO_HIZ))
695
        r300screen->caps.hiz_ram = 0;
696
 
697
    if (r300screen->info.drm_minor < 8)
698
        r300screen->caps.has_us_format = FALSE;
699
 
700
    r300screen->rws = rws;
701
    r300screen->screen.destroy = r300_destroy_screen;
702
    r300screen->screen.get_name = r300_get_name;
703
    r300screen->screen.get_vendor = r300_get_vendor;
704
    r300screen->screen.get_device_vendor = r300_get_device_vendor;
705
    r300screen->screen.get_param = r300_get_param;
706
    r300screen->screen.get_shader_param = r300_get_shader_param;
707
    r300screen->screen.get_paramf = r300_get_paramf;
708
    r300screen->screen.get_video_param = r300_get_video_param;
709
    r300screen->screen.is_format_supported = r300_is_format_supported;
710
    r300screen->screen.is_video_format_supported = vl_video_buffer_is_format_supported;
711
    r300screen->screen.context_create = r300_create_context;
712
    r300screen->screen.fence_reference = r300_fence_reference;
713
    r300screen->screen.fence_signalled = r300_fence_signalled;
714
    r300screen->screen.fence_finish = r300_fence_finish;
715
 
716
    r300_init_screen_resource_functions(r300screen);
717
 
718
    util_format_s3tc_init();
719
    pipe_mutex_init(r300screen->cmask_mutex);
720
 
721
    return &r300screen->screen;
722
}