r300_screen.c 25.2 KB
Newer Older
Corbin Simpson's avatar
Corbin Simpson committed
1 2
/*
 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
3
 * Copyright 2010 Marek Olšák <maraeo@gmail.com>
Corbin Simpson's avatar
Corbin Simpson committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * on the rights to use, copy, modify, merge, publish, distribute, sub
 * license, and/or sell copies of the Software, and to permit persons to whom
 * the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
Corbin Simpson's avatar
Corbin Simpson committed
23

24 25
#include "util/format/u_format.h"
#include "util/format/u_format_s3tc.h"
26
#include "util/u_screen.h"
27
#include "util/u_memory.h"
28
#include "util/os_time.h"
29
#include "vl/vl_decoder.h"
30
#include "vl/vl_video_buffer.h"
31 32 33

#include "r300_context.h"
#include "r300_texture.h"
34
#include "r300_screen_buffer.h"
35
#include "r300_state_inlines.h"
36
#include "r300_public.h"
37

38 39
#include "draw/draw_context.h"

40 41 42 43 44 45
/* Return the identifier behind whom the brave coders responsible for this
 * amalgamation of code, sweat, and duct tape, routinely obscure their names.
 *
 * ...I should have just put "Corbin Simpson", but I'm not that cool.
 *
 * (Or egotistical. Yet.) */
Corbin Simpson's avatar
Corbin Simpson committed
46 47
static const char* r300_get_vendor(struct pipe_screen* pscreen)
{
Corbin Simpson's avatar
Corbin Simpson committed
48 49 50
    return "X.Org R300 Project";
}

51 52 53 54 55
static const char* r300_get_device_vendor(struct pipe_screen* pscreen)
{
    return "ATI";
}

56
static const char* chip_families[] = {
57
    "unknown",
58 59 60 61 62
    "ATI R300",
    "ATI R350",
    "ATI RV350",
    "ATI RV370",
    "ATI RV380",
63 64 65
    "ATI RS400",
    "ATI RC410",
    "ATI RS480",
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
    "ATI R420",
    "ATI R423",
    "ATI R430",
    "ATI R480",
    "ATI R481",
    "ATI RV410",
    "ATI RS600",
    "ATI RS690",
    "ATI RS740",
    "ATI RV515",
    "ATI R520",
    "ATI RV530",
    "ATI R580",
    "ATI RV560",
    "ATI RV570"
81 82
};

83 84 85 86 87
static const char* r300_get_family_name(struct r300_screen* r300screen)
{
    return chip_families[r300screen->caps.family];
}

Corbin Simpson's avatar
Corbin Simpson committed
88 89
static const char* r300_get_name(struct pipe_screen* pscreen)
{
90 91
    struct r300_screen* r300screen = r300_screen(pscreen);

92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
    return r300_get_family_name(r300screen);
}

static void r300_disk_cache_create(struct r300_screen* r300screen)
{
    struct mesa_sha1 ctx;
    unsigned char sha1[20];
    char cache_id[20 * 2 + 1];

    _mesa_sha1_init(&ctx);
    if (!disk_cache_get_function_identifier(r300_disk_cache_create,
                                            &ctx))
        return;

    _mesa_sha1_final(&ctx, sha1);
    disk_cache_format_hex_id(cache_id, sha1, 20 * 2);

    r300screen->disk_shader_cache =
                    disk_cache_create(r300_get_family_name(r300screen),
                                      cache_id,
                                      r300screen->debug);
}

static struct disk_cache* r300_get_disk_shader_cache(struct pipe_screen* pscreen)
{
	struct r300_screen* r300screen = r300_screen(pscreen);
	return r300screen->disk_shader_cache;
Corbin Simpson's avatar
Corbin Simpson committed
119 120
}

121
static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
Corbin Simpson's avatar
Corbin Simpson committed
122
{
Corbin Simpson's avatar
Corbin Simpson committed
123
    struct r300_screen* r300screen = r300_screen(pscreen);
124 125
    boolean is_r500 = r300screen->caps.is_r500;

Corbin Simpson's avatar
Corbin Simpson committed
126
    switch (param) {
Marek Olšák's avatar
Marek Olšák committed
127
        /* Supported features (boolean caps). */
Corbin Simpson's avatar
Corbin Simpson committed
128
        case PIPE_CAP_NPOT_TEXTURES:
129
        case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
130
        case PIPE_CAP_MIXED_COLOR_DEPTH_BITS:
Corbin Simpson's avatar
Corbin Simpson committed
131 132 133
        case PIPE_CAP_ANISOTROPIC_FILTER:
        case PIPE_CAP_POINT_SPRITE:
        case PIPE_CAP_OCCLUSION_QUERY:
Corbin Simpson's avatar
Corbin Simpson committed
134
        case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
135
        case PIPE_CAP_TEXTURE_MIRROR_CLAMP_TO_EDGE:
Marek Olšák's avatar
Marek Olšák committed
136
        case PIPE_CAP_BLEND_EQUATION_SEPARATE:
137
        case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
Marek Olšák's avatar
Marek Olšák committed
138 139
        case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
        case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
140
        case PIPE_CAP_CONDITIONAL_RENDER:
141
        case PIPE_CAP_TEXTURE_BARRIER:
142
        case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
143
        case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
144
        case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
145
        case PIPE_CAP_CLIP_HALFZ:
146
        case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
147
            return 1;
Marek Olšák's avatar
Marek Olšák committed
148

149
        case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
150
            return R300_BUFFER_ALIGNMENT;
151

152 153 154
        case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
            return 16;

155
        case PIPE_CAP_GLSL_FEATURE_LEVEL:
156
        case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
157 158
            return 120;

Marek Olšák's avatar
Marek Olšák committed
159
        /* r300 cannot do swizzling of compressed textures. Supported otherwise. */
160
        case PIPE_CAP_TEXTURE_SWIZZLE:
161
            return r300screen->caps.dxtc_swizzle;
Marek Olšák's avatar
Marek Olšák committed
162

163 164 165 166 167
        /* We don't support color clamping on r500, so that we can use color
         * intepolators for generic varyings. */
        case PIPE_CAP_VERTEX_COLOR_CLAMPED:
            return !is_r500;

Marek Olšák's avatar
Marek Olšák committed
168
        /* Supported on r500 only. */
169
        case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
170
        case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
171 172 173
        case PIPE_CAP_FRAGMENT_SHADER_TEXTURE_LOD:
        case PIPE_CAP_FRAGMENT_SHADER_DERIVATIVES:
        case PIPE_CAP_VERTEX_SHADER_SATURATE:
174
            return is_r500 ? 1 : 0;
Marek Olšák's avatar
Marek Olšák committed
175

176
        case PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY:
177 178
            return 0;

179 180
        case PIPE_CAP_MAX_GS_INVOCATIONS:
            return 32;
181 182
       case PIPE_CAP_MAX_SHADER_BUFFER_SIZE:
            return 1 << 27;
183

184
        /* SWTCL-only features. */
185
        case PIPE_CAP_PRIMITIVE_RESTART:
186
        case PIPE_CAP_PRIMITIVE_RESTART_FIXED_INDEX:
187
        case PIPE_CAP_USER_VERTEX_BUFFERS:
188
        case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
189
            return !r300screen->caps.has_tcl;
Marek Olšák's avatar
Marek Olšák committed
190

191 192 193 194 195 196
        /* HWTCL-only features / limitations. */
        case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
        case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
        case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
            return r300screen->caps.has_tcl;

Marek Olšák's avatar
Marek Olšák committed
197
        /* Texturing. */
198 199
        case PIPE_CAP_MAX_TEXTURE_2D_SIZE:
            return is_r500 ? 4096 : 2048;
Marek Olšák's avatar
Marek Olšák committed
200 201 202 203 204 205 206 207
        case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
        case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
            /* 13 == 4096, 12 == 2048 */
            return is_r500 ? 13 : 12;

        /* Render targets. */
        case PIPE_CAP_MAX_RENDER_TARGETS:
            return 4;
208
        case PIPE_CAP_ENDIANNESS:
209
            return PIPE_ENDIAN_LITTLE;
210 211 212

        case PIPE_CAP_MAX_VIEWPORTS:
            return 1;
213

214 215 216
        case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE:
            return 2048;

217 218 219
        case PIPE_CAP_MAX_VARYINGS:
            return 10;

220 221 222 223 224 225 226 227 228 229
        case PIPE_CAP_VENDOR_ID:
                return 0x1002;
        case PIPE_CAP_DEVICE_ID:
                return r300screen->info.pci_id;
        case PIPE_CAP_ACCELERATED:
                return 1;
        case PIPE_CAP_VIDEO_MEMORY:
                return r300screen->info.vram_size >> 20;
        case PIPE_CAP_UMA:
                return 0;
230 231 232 233 234 235 236 237
        case PIPE_CAP_PCI_GROUP:
            return r300screen->info.pci_domain;
        case PIPE_CAP_PCI_BUS:
            return r300screen->info.pci_bus;
        case PIPE_CAP_PCI_DEVICE:
            return r300screen->info.pci_dev;
        case PIPE_CAP_PCI_FUNCTION:
            return r300screen->info.pci_func;
238 239
        default:
            return u_pipe_screen_get_param_defaults(pscreen, param);
240 241
    }
}
242

243 244 245
static int r300_get_shader_param(struct pipe_screen *pscreen,
                                 enum pipe_shader_type shader,
                                 enum pipe_shader_cap param)
246 247 248 249 250
{
   struct r300_screen* r300screen = r300_screen(pscreen);
   boolean is_r400 = r300screen->caps.is_r400;
   boolean is_r500 = r300screen->caps.is_r500;

251
   switch (shader) {
252 253 254 255
    case PIPE_SHADER_FRAGMENT:
        switch (param)
        {
        case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
256
            return is_r500 || is_r400 ? 512 : 96;
257
        case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
258
            return is_r500 || is_r400 ? 512 : 64;
259
        case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
260
            return is_r500 || is_r400 ? 512 : 32;
261
        case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
262
            return is_r500 ? 511 : 4;
263
        case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
264
            return is_r500 ? 64 : 0; /* Actually unlimited on r500. */
265 266
            /* Fragment shader limits. */
        case PIPE_SHADER_CAP_MAX_INPUTS:
267 268 269 270 271 272 273
            /* 2 colors + 8 texcoords are always supported
             * (minus fog and wpos).
             *
             * R500 has the ability to turn 3rd and 4th color into
             * additional texcoords but there is no two-sided color
             * selection then. However the facing bit can be used instead. */
            return 10;
274 275
        case PIPE_SHADER_CAP_MAX_OUTPUTS:
            return 4;
276 277
        case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
            return (is_r500 ? 256 : 32) * sizeof(float[4]);
278
        case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
279
        case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
280 281
            return 1;
        case PIPE_SHADER_CAP_MAX_TEMPS:
282
            return is_r500 ? 128 : is_r400 ? 64 : 32;
Marek Olšák's avatar
Marek Olšák committed
283
        case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
284
        case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
Marek Olšák's avatar
Marek Olšák committed
285
           return r300screen->caps.num_tex_units;
286
        case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
287
        case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
288 289 290 291
        case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
        case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
        case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
        case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
292
        case PIPE_SHADER_CAP_SUBROUTINES:
Marek Olšák's avatar
Marek Olšák committed
293
        case PIPE_SHADER_CAP_INTEGERS:
294
        case PIPE_SHADER_CAP_INT64_ATOMICS:
Jan Vesely's avatar
Jan Vesely committed
295
        case PIPE_SHADER_CAP_FP16:
296 297
        case PIPE_SHADER_CAP_FP16_DERIVATIVES:
        case PIPE_SHADER_CAP_INT16:
298 299
        case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
        case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
300
        case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
301
        case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
302
        case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
303
        case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
304
        case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
305
        case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
306 307
        case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
        case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
308
            return 0;
309 310
        case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
            return 32;
Francisco Jerez's avatar
Francisco Jerez committed
311 312
        case PIPE_SHADER_CAP_PREFERRED_IR:
            return PIPE_SHADER_IR_TGSI;
313 314
        case PIPE_SHADER_CAP_SUPPORTED_IRS:
            return 0;
315 316 317
        }
        break;
    case PIPE_SHADER_VERTEX:
318 319 320
        switch (param)
        {
        case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
321
        case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
322
        case PIPE_SHADER_CAP_SUBROUTINES:
323 324 325 326
            return 0;
        default:;
        }

327 328 329 330
        if (!r300screen->caps.has_tcl) {
            return draw_get_shader_param(shader, param);
        }

331 332 333 334
        switch (param)
        {
        case PIPE_SHADER_CAP_MAX_INSTRUCTIONS:
        case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS:
335
            return is_r500 ? 1024 : 256;
336
        case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH:
337
            return is_r500 ? 4 : 0; /* For loops; not sure about conditionals. */
338
        case PIPE_SHADER_CAP_MAX_INPUTS:
339
            return 16;
340 341
        case PIPE_SHADER_CAP_MAX_OUTPUTS:
            return 10;
342 343
        case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
            return 256 * sizeof(float[4]);
344 345 346
        case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
            return 1;
        case PIPE_SHADER_CAP_MAX_TEMPS:
347
            return 32;
Marek Olšák's avatar
Marek Olšák committed
348
        case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
349
        case PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE:
Marek Olšák's avatar
Marek Olšák committed
350
            return 1;
Marek Olšák's avatar
Marek Olšák committed
351 352
        case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS:
        case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS:
353
        case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED:
354
        case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
355 356 357
        case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR:
        case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR:
        case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR:
358
        case PIPE_SHADER_CAP_SUBROUTINES:
359
        case PIPE_SHADER_CAP_INTEGERS:
Jan Vesely's avatar
Jan Vesely committed
360
        case PIPE_SHADER_CAP_FP16:
361 362
        case PIPE_SHADER_CAP_FP16_DERIVATIVES:
        case PIPE_SHADER_CAP_INT16:
363
        case PIPE_SHADER_CAP_INT64_ATOMICS:
Marek Olšák's avatar
Marek Olšák committed
364
        case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
365
        case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
366 367
        case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED:
        case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED:
368
        case PIPE_SHADER_CAP_TGSI_LDEXP_SUPPORTED:
369
        case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED:
370
        case PIPE_SHADER_CAP_MAX_SHADER_BUFFERS:
371
        case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
372
        case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
373
        case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
374 375
        case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS:
        case PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS:
376
            return 0;
377 378
        case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS_HINT:
            return 32;
Francisco Jerez's avatar
Francisco Jerez committed
379 380
        case PIPE_SHADER_CAP_PREFERRED_IR:
            return PIPE_SHADER_IR_TGSI;
381 382
        case PIPE_SHADER_CAP_SUPPORTED_IRS:
            return 0;
383 384
        }
        break;
385 386
    default:
        ; /* nothing */
Corbin Simpson's avatar
Corbin Simpson committed
387
    }
388
    return 0;
Corbin Simpson's avatar
Corbin Simpson committed
389 390
}

391 392
static float r300_get_paramf(struct pipe_screen* pscreen,
                             enum pipe_capf param)
Corbin Simpson's avatar
Corbin Simpson committed
393
{
394 395
    struct r300_screen* r300screen = r300_screen(pscreen);

Corbin Simpson's avatar
Corbin Simpson committed
396
    switch (param) {
397 398 399 400
        case PIPE_CAPF_MAX_LINE_WIDTH:
        case PIPE_CAPF_MAX_LINE_WIDTH_AA:
        case PIPE_CAPF_MAX_POINT_WIDTH:
        case PIPE_CAPF_MAX_POINT_WIDTH_AA:
401 402
            /* The maximum dimensions of the colorbuffer are our practical
             * rendering limits. 2048 pixels should be enough for anybody. */
403
            if (r300screen->caps.is_r500) {
404
                return 4096.0f;
405
            } else if (r300screen->caps.is_r400) {
406
                return 4021.0f;
407
            } else {
408
                return 2560.0f;
409
            }
410
        case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
411
            return 16.0f;
412
        case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
413
            return 16.0f;
414 415 416 417
        case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE:
        case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE:
        case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY:
            return 0.0f;
Corbin Simpson's avatar
Corbin Simpson committed
418
        default:
419 420
            debug_printf("r300: Warning: Unknown CAP %d in get_paramf.\n",
                         param);
421
            return 0.0f;
Corbin Simpson's avatar
Corbin Simpson committed
422 423 424
    }
}

425 426
static int r300_get_video_param(struct pipe_screen *screen,
				enum pipe_video_profile profile,
427
				enum pipe_video_entrypoint entrypoint,
428 429
				enum pipe_video_cap param)
{
430 431
   switch (param) {
      case PIPE_VIDEO_CAP_SUPPORTED:
432
         return vl_profile_supported(screen, profile, entrypoint);
433 434 435 436 437
      case PIPE_VIDEO_CAP_NPOT_TEXTURES:
         return 0;
      case PIPE_VIDEO_CAP_MAX_WIDTH:
      case PIPE_VIDEO_CAP_MAX_HEIGHT:
         return vl_video_buffer_max_size(screen);
438 439
      case PIPE_VIDEO_CAP_PREFERED_FORMAT:
         return PIPE_FORMAT_NV12;
440 441 442 443 444 445
      case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
         return false;
      case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
         return false;
      case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
         return true;
446 447
      case PIPE_VIDEO_CAP_MAX_LEVEL:
         return vl_level_supported(screen, profile);
448 449 450
      default:
         return 0;
   }
451 452
}

453 454 455 456
/**
 * Whether the format matches:
 *   PIPE_FORMAT_?10?10?10?2_UNORM
 */
457
static inline boolean
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478
util_format_is_rgba1010102_variant(const struct util_format_description *desc)
{
   static const unsigned size[4] = {10, 10, 10, 2};
   unsigned chan;

   if (desc->block.width != 1 ||
       desc->block.height != 1 ||
       desc->block.bits != 32)
      return FALSE;

   for (chan = 0; chan < 4; ++chan) {
      if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED &&
         desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID)
         return FALSE;
      if (desc->channel[chan].size != size[chan])
         return FALSE;
   }

   return TRUE;
}

479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516
static bool r300_is_blending_supported(struct r300_screen *rscreen,
                                       enum pipe_format format)
{
    int c;
    const struct util_format_description *desc =
        util_format_description(format);

    if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
        return false;

    c = util_format_get_first_non_void_channel(format);

    /* RGBA16F */
    if (rscreen->caps.is_r500 &&
        desc->nr_channels == 4 &&
        desc->channel[c].size == 16 &&
        desc->channel[c].type == UTIL_FORMAT_TYPE_FLOAT)
        return true;

    if (desc->channel[c].normalized &&
        desc->channel[c].type == UTIL_FORMAT_TYPE_UNSIGNED &&
        desc->channel[c].size >= 4 &&
        desc->channel[c].size <= 10) {
        /* RGB10_A2, RGBA8, RGB5_A1, RGBA4, RGB565 */
        if (desc->nr_channels >= 3)
            return true;

        if (format == PIPE_FORMAT_R8G8_UNORM)
            return true;

        /* R8, I8, L8, A8 */
        if (desc->nr_channels == 1)
            return true;
    }

    return false;
}

517 518 519 520 521 522
static bool r300_is_format_supported(struct pipe_screen* screen,
                                     enum pipe_format format,
                                     enum pipe_texture_target target,
                                     unsigned sample_count,
                                     unsigned storage_sample_count,
                                     unsigned usage)
Corbin Simpson's avatar
Corbin Simpson committed
523
{
524
    uint32_t retval = 0;
525 526
    boolean is_r500 = r300_screen(screen)->caps.is_r500;
    boolean is_r400 = r300_screen(screen)->caps.is_r400;
527 528 529
    boolean is_color2101010 = format == PIPE_FORMAT_R10G10B10A2_UNORM ||
                              format == PIPE_FORMAT_R10G10B10X2_SNORM ||
                              format == PIPE_FORMAT_B10G10R10A2_UNORM ||
530
                              format == PIPE_FORMAT_B10G10R10X2_UNORM ||
531
                              format == PIPE_FORMAT_R10SG10SB10SA2U_NORM;
532
    boolean is_ati1n = format == PIPE_FORMAT_RGTC1_UNORM ||
Marek Olšák's avatar
Marek Olšák committed
533 534 535
                       format == PIPE_FORMAT_RGTC1_SNORM ||
                       format == PIPE_FORMAT_LATC1_UNORM ||
                       format == PIPE_FORMAT_LATC1_SNORM;
536
    boolean is_ati2n = format == PIPE_FORMAT_RGTC2_UNORM ||
Marek Olšák's avatar
Marek Olšák committed
537 538 539
                       format == PIPE_FORMAT_RGTC2_SNORM ||
                       format == PIPE_FORMAT_LATC2_UNORM ||
                       format == PIPE_FORMAT_LATC2_SNORM;
540 541
    boolean is_half_float = format == PIPE_FORMAT_R16_FLOAT ||
                            format == PIPE_FORMAT_R16G16_FLOAT ||
542
                            format == PIPE_FORMAT_R16G16B16_FLOAT ||
543 544
                            format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
                            format == PIPE_FORMAT_R16G16B16X16_FLOAT;
545
    const struct util_format_description *desc;
546

547 548 549
    if (MAX2(1, sample_count) != MAX2(1, storage_sample_count))
        return false;

550
    /* Check multisampling support. */
Corbin Simpson's avatar
Corbin Simpson committed
551 552 553
    switch (sample_count) {
        case 0:
        case 1:
554
            break;
Corbin Simpson's avatar
Corbin Simpson committed
555 556 557
        case 2:
        case 4:
        case 6:
Marek Olšák's avatar
Marek Olšák committed
558 559 560 561
            /* No texturing and scanout. */
            if (usage & (PIPE_BIND_SAMPLER_VIEW |
                         PIPE_BIND_DISPLAY_TARGET |
                         PIPE_BIND_SCANOUT)) {
562
                return false;
Marek Olšák's avatar
Marek Olšák committed
563
            }
564 565 566 567 568 569 570 571

            desc = util_format_description(format);

            if (is_r500) {
                /* Only allow depth/stencil, RGBA8, RGBA1010102, RGBA16F. */
                if (!util_format_is_depth_or_stencil(format) &&
                    !util_format_is_rgba8_variant(desc) &&
                    !util_format_is_rgba1010102_variant(desc) &&
572 573
                    format != PIPE_FORMAT_R16G16B16A16_FLOAT &&
                    format != PIPE_FORMAT_R16G16B16X16_FLOAT) {
574
                    return false;
575 576 577 578 579
                }
            } else {
                /* Only allow depth/stencil, RGBA8. */
                if (!util_format_is_depth_or_stencil(format) &&
                    !util_format_is_rgba8_variant(desc)) {
580
                    return false;
581
                }
582
            }
Corbin Simpson's avatar
Corbin Simpson committed
583 584
            break;
        default:
585
            return false;
Corbin Simpson's avatar
Corbin Simpson committed
586
    }
587

588
    /* Check sampler format support. */
589
    if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
Marek Olšák's avatar
Marek Olšák committed
590 591 592
        /* these two are broken for an unknown reason */
        format != PIPE_FORMAT_R8G8B8X8_SNORM &&
        format != PIPE_FORMAT_R16G16B16X16_SNORM &&
593 594 595 596
        /* ATI1N is r5xx-only. */
        (is_r500 || !is_ati1n) &&
        /* ATI2N is supported on r4xx-r5xx. */
        (is_r400 || is_r500 || !is_ati2n) &&
597
        r300_is_sampler_format_supported(format)) {
598
        retval |= PIPE_BIND_SAMPLER_VIEW;
599 600
    }

601
    /* Check colorbuffer format support. */
602 603 604
    if ((usage & (PIPE_BIND_RENDER_TARGET |
                  PIPE_BIND_DISPLAY_TARGET |
                  PIPE_BIND_SCANOUT |
605 606
                  PIPE_BIND_SHARED |
                  PIPE_BIND_BLENDABLE)) &&
607
        /* 2101010 cannot be rendered to on non-r5xx. */
608
        (!is_color2101010 || is_r500) &&
609 610
        r300_is_colorbuffer_format_supported(format)) {
        retval |= usage &
611 612 613 614
            (PIPE_BIND_RENDER_TARGET |
             PIPE_BIND_DISPLAY_TARGET |
             PIPE_BIND_SCANOUT |
             PIPE_BIND_SHARED);
615 616 617 618

        if (r300_is_blending_supported(r300_screen(screen), format)) {
            retval |= usage & PIPE_BIND_BLENDABLE;
        }
619
    }
620

621
    /* Check depth-stencil format support. */
622
    if (usage & PIPE_BIND_DEPTH_STENCIL &&
623
        r300_is_zs_format_supported(format)) {
624
        retval |= PIPE_BIND_DEPTH_STENCIL;
Corbin Simpson's avatar
Corbin Simpson committed
625 626
    }

627
    /* Check vertex buffer format support. */
628 629 630 631 632 633 634 635 636 637 638 639 640
    if (usage & PIPE_BIND_VERTEX_BUFFER) {
        if (r300_screen(screen)->caps.has_tcl) {
            /* Half float is supported on >= R400. */
            if ((is_r400 || is_r500 || !is_half_float) &&
                r300_translate_vertex_data_type(format) != R300_INVALID_FORMAT) {
                retval |= PIPE_BIND_VERTEX_BUFFER;
            }
        } else {
            /* SW TCL */
            if (!util_format_is_pure_integer(format)) {
                retval |= PIPE_BIND_VERTEX_BUFFER;
            }
        }
641 642
    }

643
    return retval == usage;
Corbin Simpson's avatar
Corbin Simpson committed
644 645
}

Corbin Simpson's avatar
Corbin Simpson committed
646 647
static void r300_destroy_screen(struct pipe_screen* pscreen)
{
Corbin Simpson's avatar
Corbin Simpson committed
648
    struct r300_screen* r300screen = r300_screen(pscreen);
649
    struct radeon_winsys *rws = radeon_winsys(pscreen);
650

651
    if (rws && !rws->unref(rws))
652 653
      return;

654
    mtx_destroy(&r300screen->cmask_mutex);
655
    slab_destroy_parent(&r300screen->pool_transfers);
656

657 658
    disk_cache_destroy(r300screen->disk_shader_cache);

659 660
    if (rws)
      rws->destroy(rws);
Corbin Simpson's avatar
Corbin Simpson committed
661 662

    FREE(r300screen);
Corbin Simpson's avatar
Corbin Simpson committed
663 664
}

665 666 667 668
static void r300_fence_reference(struct pipe_screen *screen,
                                 struct pipe_fence_handle **ptr,
                                 struct pipe_fence_handle *fence)
{
669 670 671
    struct radeon_winsys *rws = r300_screen(screen)->rws;

    rws->fence_reference(ptr, fence);
672 673
}

674 675 676 677
static bool r300_fence_finish(struct pipe_screen *screen,
                              struct pipe_context *ctx,
                              struct pipe_fence_handle *fence,
                              uint64_t timeout)
678
{
679
    struct radeon_winsys *rws = r300_screen(screen)->rws;
680

681
    return rws->fence_wait(rws, fence, timeout);
682 683
}

684 685
struct pipe_screen* r300_screen_create(struct radeon_winsys *rws,
                                       const struct pipe_screen_config *config)
686
{
687
    struct r300_screen *r300screen = CALLOC_STRUCT(r300_screen);
Corbin Simpson's avatar
Corbin Simpson committed
688

689
    if (!r300screen) {
690
        FREE(r300screen);
Corbin Simpson's avatar
Corbin Simpson committed
691
        return NULL;
692
    }
Corbin Simpson's avatar
Corbin Simpson committed
693

694
    rws->query_info(rws, &r300screen->info);
695

696
    r300_init_debug(r300screen);
697
    r300_parse_chipset(r300screen->info.pci_id, &r300screen->caps);
Corbin Simpson's avatar
Corbin Simpson committed
698

699 700 701 702 703
    if (SCREEN_DBG_ON(r300screen, DBG_NO_ZMASK))
        r300screen->caps.zmask_ram = 0;
    if (SCREEN_DBG_ON(r300screen, DBG_NO_HIZ))
        r300screen->caps.hiz_ram = 0;

704
    r300screen->rws = rws;
Corbin Simpson's avatar
Corbin Simpson committed
705 706 707
    r300screen->screen.destroy = r300_destroy_screen;
    r300screen->screen.get_name = r300_get_name;
    r300screen->screen.get_vendor = r300_get_vendor;
708
    r300screen->screen.get_device_vendor = r300_get_device_vendor;
709
    r300screen->screen.get_disk_shader_cache = r300_get_disk_shader_cache;
Corbin Simpson's avatar
Corbin Simpson committed
710
    r300screen->screen.get_param = r300_get_param;
711
    r300screen->screen.get_shader_param = r300_get_shader_param;
Corbin Simpson's avatar
Corbin Simpson committed
712
    r300screen->screen.get_paramf = r300_get_paramf;
713
    r300screen->screen.get_video_param = r300_get_video_param;
Corbin Simpson's avatar
Corbin Simpson committed
714
    r300screen->screen.is_format_supported = r300_is_format_supported;
715
    r300screen->screen.is_video_format_supported = vl_video_buffer_is_format_supported;
716
    r300screen->screen.context_create = r300_create_context;
717 718 719
    r300screen->screen.fence_reference = r300_fence_reference;
    r300screen->screen.fence_finish = r300_fence_finish;

720
    r300_init_screen_resource_functions(r300screen);
721

722 723
    r300_disk_cache_create(r300screen);

724 725
    slab_create_parent(&r300screen->pool_transfers, sizeof(struct pipe_transfer), 64);

726
    (void) mtx_init(&r300screen->cmask_mutex, mtx_plain);
727

728
    return &r300screen->screen;
729
}