r600_pipe.c revision 0d29fb017bce0968240ae875af4b3702c2cd46ef
1/* 2 * Copyright 2010 Jerome Glisse <glisse@freedesktop.org> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. 22 */ 23#include "r600_pipe.h" 24#include "r600_public.h" 25 26#include <errno.h> 27#include "pipe/p_shader_tokens.h" 28#include "util/u_blitter.h" 29#include "util/u_format_s3tc.h" 30#include "util/u_simple_shaders.h" 31#include "vl/vl_decoder.h" 32#include "vl/vl_video_buffer.h" 33#include "os/os_time.h" 34 35/* 36 * pipe_context 37 */ 38static struct r600_fence *r600_create_fence(struct r600_context *rctx) 39{ 40 struct r600_screen *rscreen = rctx->screen; 41 struct r600_fence *fence = NULL; 42 43 pipe_mutex_lock(rscreen->fences.mutex); 44 45 if (!rscreen->fences.bo) { 46 /* Create the shared buffer object */ 47 rscreen->fences.bo = (struct r600_resource*) 48 pipe_buffer_create(&rscreen->screen, PIPE_BIND_CUSTOM, 49 PIPE_USAGE_STAGING, 4096); 50 if (!rscreen->fences.bo) { 51 R600_ERR("r600: failed to create bo for fence objects\n"); 52 goto out; 53 } 54 rscreen->fences.data = rctx->ws->buffer_map(rscreen->fences.bo->buf, 55 rctx->cs, 56 PIPE_TRANSFER_READ_WRITE); 57 } 58 59 if (!LIST_IS_EMPTY(&rscreen->fences.pool)) { 60 struct r600_fence *entry; 61 62 /* Try to find a freed fence that has been signalled */ 63 LIST_FOR_EACH_ENTRY(entry, &rscreen->fences.pool, head) { 64 if (rscreen->fences.data[entry->index] != 0) { 65 LIST_DELINIT(&entry->head); 66 fence = entry; 67 break; 68 } 69 } 70 } 71 72 if (!fence) { 73 /* Allocate a new fence */ 74 struct r600_fence_block *block; 75 unsigned index; 76 77 if ((rscreen->fences.next_index + 1) >= 1024) { 78 R600_ERR("r600: too many concurrent fences\n"); 79 goto out; 80 } 81 82 index = rscreen->fences.next_index++; 83 84 if (!(index % FENCE_BLOCK_SIZE)) { 85 /* Allocate a new block */ 86 block = CALLOC_STRUCT(r600_fence_block); 87 if (block == NULL) 88 goto out; 89 90 LIST_ADD(&block->head, &rscreen->fences.blocks); 91 } else { 92 block = LIST_ENTRY(struct r600_fence_block, rscreen->fences.blocks.next, head); 93 } 94 95 fence = &block->fences[index % FENCE_BLOCK_SIZE]; 96 fence->index = index; 97 } 98 99 pipe_reference_init(&fence->reference, 1); 100 101 rscreen->fences.data[fence->index] = 0; 102 r600_context_emit_fence(rctx, rscreen->fences.bo, fence->index, 1); 103 104 /* Create a dummy BO so that fence_finish without a timeout can sleep waiting for completion */ 105 fence->sleep_bo = (struct r600_resource*) 106 pipe_buffer_create(&rctx->screen->screen, PIPE_BIND_CUSTOM, 107 PIPE_USAGE_STAGING, 1); 108 /* Add the fence as a dummy relocation. */ 109 r600_context_bo_reloc(rctx, fence->sleep_bo, RADEON_USAGE_READWRITE); 110 111out: 112 pipe_mutex_unlock(rscreen->fences.mutex); 113 return fence; 114} 115 116 117void r600_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence, 118 unsigned flags) 119{ 120 struct r600_context *rctx = (struct r600_context *)ctx; 121 struct r600_fence **rfence = (struct r600_fence**)fence; 122 struct pipe_query *render_cond = NULL; 123 unsigned render_cond_mode = 0; 124 125 if (rfence) 126 *rfence = r600_create_fence(rctx); 127 128 /* Disable render condition. */ 129 if (rctx->current_render_cond) { 130 render_cond = rctx->current_render_cond; 131 render_cond_mode = rctx->current_render_cond_mode; 132 ctx->render_condition(ctx, NULL, 0); 133 } 134 135 r600_context_flush(rctx, flags); 136 137 /* Re-enable render condition. */ 138 if (render_cond) { 139 ctx->render_condition(ctx, render_cond, render_cond_mode); 140 } 141} 142 143static void r600_flush_from_st(struct pipe_context *ctx, 144 struct pipe_fence_handle **fence) 145{ 146 r600_flush(ctx, fence, 0); 147} 148 149static void r600_flush_from_winsys(void *ctx, unsigned flags) 150{ 151 r600_flush((struct pipe_context*)ctx, NULL, flags); 152} 153 154static void r600_update_num_contexts(struct r600_screen *rscreen, int diff) 155{ 156 pipe_mutex_lock(rscreen->mutex_num_contexts); 157 if (diff > 0) { 158 rscreen->num_contexts++; 159 160 if (rscreen->num_contexts > 1) 161 util_slab_set_thread_safety(&rscreen->pool_buffers, 162 UTIL_SLAB_MULTITHREADED); 163 } else { 164 rscreen->num_contexts--; 165 166 if (rscreen->num_contexts <= 1) 167 util_slab_set_thread_safety(&rscreen->pool_buffers, 168 UTIL_SLAB_SINGLETHREADED); 169 } 170 pipe_mutex_unlock(rscreen->mutex_num_contexts); 171} 172 173static void r600_destroy_context(struct pipe_context *context) 174{ 175 struct r600_context *rctx = (struct r600_context *)context; 176 177 if (rctx->dummy_pixel_shader) { 178 rctx->context.delete_fs_state(&rctx->context, rctx->dummy_pixel_shader); 179 } 180 if (rctx->custom_dsa_flush) { 181 rctx->context.delete_depth_stencil_alpha_state(&rctx->context, rctx->custom_dsa_flush); 182 } 183 util_unreference_framebuffer_state(&rctx->framebuffer); 184 185 r600_context_fini(rctx); 186 187 if (rctx->blitter) { 188 util_blitter_destroy(rctx->blitter); 189 } 190 for (int i = 0; i < R600_PIPE_NSTATES; i++) { 191 free(rctx->states[i]); 192 } 193 194 if (rctx->vbuf_mgr) { 195 u_vbuf_destroy(rctx->vbuf_mgr); 196 } 197 util_slab_destroy(&rctx->pool_transfers); 198 199 r600_update_num_contexts(rctx->screen, -1); 200 201 r600_release_command_buffer(&rctx->start_cs_cmd); 202 203 if (rctx->cs) { 204 rctx->ws->cs_destroy(rctx->cs); 205 } 206 207 FREE(rctx->range); 208 FREE(rctx); 209} 210 211static struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv) 212{ 213 struct r600_context *rctx = CALLOC_STRUCT(r600_context); 214 struct r600_screen* rscreen = (struct r600_screen *)screen; 215 216 if (rctx == NULL) 217 return NULL; 218 219 util_slab_create(&rctx->pool_transfers, 220 sizeof(struct pipe_transfer), 64, 221 UTIL_SLAB_SINGLETHREADED); 222 223 r600_update_num_contexts(rscreen, 1); 224 225 rctx->context.screen = screen; 226 rctx->context.priv = priv; 227 rctx->context.destroy = r600_destroy_context; 228 rctx->context.flush = r600_flush_from_st; 229 230 /* Easy accessing of screen/winsys. */ 231 rctx->screen = rscreen; 232 rctx->ws = rscreen->ws; 233 rctx->family = rscreen->family; 234 rctx->chip_class = rscreen->chip_class; 235 236 LIST_INITHEAD(&rctx->dirty_states); 237 LIST_INITHEAD(&rctx->active_timer_queries); 238 LIST_INITHEAD(&rctx->active_nontimer_queries); 239 LIST_INITHEAD(&rctx->dirty); 240 LIST_INITHEAD(&rctx->resource_dirty); 241 LIST_INITHEAD(&rctx->enable_list); 242 243 rctx->range = CALLOC(NUM_RANGES, sizeof(struct r600_range)); 244 if (!rctx->range) 245 goto fail; 246 247 r600_init_blit_functions(rctx); 248 r600_init_query_functions(rctx); 249 r600_init_context_resource_functions(rctx); 250 r600_init_surface_functions(rctx); 251 rctx->context.draw_vbo = r600_draw_vbo; 252 253 rctx->context.create_video_decoder = vl_create_decoder; 254 rctx->context.create_video_buffer = vl_video_buffer_create; 255 256 r600_init_common_atoms(rctx); 257 258 switch (rctx->chip_class) { 259 case R600: 260 case R700: 261 r600_init_state_functions(rctx); 262 r600_init_atom_start_cs(rctx); 263 if (r600_context_init(rctx)) 264 goto fail; 265 rctx->custom_dsa_flush = r600_create_db_flush_dsa(rctx); 266 rctx->has_vertex_cache = !(rctx->family == CHIP_RV610 || 267 rctx->family == CHIP_RV620 || 268 rctx->family == CHIP_RS780 || 269 rctx->family == CHIP_RS880 || 270 rctx->family == CHIP_RV710); 271 break; 272 case EVERGREEN: 273 case CAYMAN: 274 evergreen_init_state_functions(rctx); 275 evergreen_init_atom_start_cs(rctx); 276 if (evergreen_context_init(rctx)) 277 goto fail; 278 rctx->custom_dsa_flush = evergreen_create_db_flush_dsa(rctx); 279 rctx->has_vertex_cache = !(rctx->family == CHIP_CEDAR || 280 rctx->family == CHIP_PALM || 281 rctx->family == CHIP_SUMO || 282 rctx->family == CHIP_SUMO2 || 283 rctx->family == CHIP_CAICOS || 284 rctx->family == CHIP_CAYMAN || 285 rctx->family == CHIP_ARUBA); 286 break; 287 default: 288 R600_ERR("Unsupported chip class %d.\n", rctx->chip_class); 289 goto fail; 290 } 291 292 rctx->cs = rctx->ws->cs_create(rctx->ws); 293 rctx->ws->cs_set_flush_callback(rctx->cs, r600_flush_from_winsys, rctx); 294 r600_emit_atom(rctx, &rctx->start_cs_cmd.atom); 295 296 rctx->vbuf_mgr = u_vbuf_create(&rctx->context, 1024 * 1024, 256, 297 PIPE_BIND_VERTEX_BUFFER | 298 PIPE_BIND_INDEX_BUFFER | 299 PIPE_BIND_CONSTANT_BUFFER, 300 U_VERTEX_FETCH_DWORD_ALIGNED); 301 if (!rctx->vbuf_mgr) 302 goto fail; 303 rctx->vbuf_mgr->caps.format_fixed32 = 0; 304 305 rctx->blitter = util_blitter_create(&rctx->context); 306 if (rctx->blitter == NULL) 307 goto fail; 308 309 r600_get_backend_mask(rctx); /* this emits commands and must be last */ 310 311 if (rctx->chip_class == R600) 312 r600_set_max_scissor(rctx); 313 314 rctx->dummy_pixel_shader = 315 util_make_fragment_cloneinput_shader(&rctx->context, 0, 316 TGSI_SEMANTIC_GENERIC, 317 TGSI_INTERPOLATE_CONSTANT); 318 rctx->context.bind_fs_state(&rctx->context, rctx->dummy_pixel_shader); 319 320 return &rctx->context; 321 322fail: 323 r600_destroy_context(&rctx->context); 324 return NULL; 325} 326 327/* 328 * pipe_screen 329 */ 330static const char* r600_get_vendor(struct pipe_screen* pscreen) 331{ 332 return "X.Org"; 333} 334 335static const char *r600_get_family_name(enum radeon_family family) 336{ 337 switch(family) { 338 case CHIP_R600: return "AMD R600"; 339 case CHIP_RV610: return "AMD RV610"; 340 case CHIP_RV630: return "AMD RV630"; 341 case CHIP_RV670: return "AMD RV670"; 342 case CHIP_RV620: return "AMD RV620"; 343 case CHIP_RV635: return "AMD RV635"; 344 case CHIP_RS780: return "AMD RS780"; 345 case CHIP_RS880: return "AMD RS880"; 346 case CHIP_RV770: return "AMD RV770"; 347 case CHIP_RV730: return "AMD RV730"; 348 case CHIP_RV710: return "AMD RV710"; 349 case CHIP_RV740: return "AMD RV740"; 350 case CHIP_CEDAR: return "AMD CEDAR"; 351 case CHIP_REDWOOD: return "AMD REDWOOD"; 352 case CHIP_JUNIPER: return "AMD JUNIPER"; 353 case CHIP_CYPRESS: return "AMD CYPRESS"; 354 case CHIP_HEMLOCK: return "AMD HEMLOCK"; 355 case CHIP_PALM: return "AMD PALM"; 356 case CHIP_SUMO: return "AMD SUMO"; 357 case CHIP_SUMO2: return "AMD SUMO2"; 358 case CHIP_BARTS: return "AMD BARTS"; 359 case CHIP_TURKS: return "AMD TURKS"; 360 case CHIP_CAICOS: return "AMD CAICOS"; 361 case CHIP_CAYMAN: return "AMD CAYMAN"; 362 case CHIP_ARUBA: return "AMD ARUBA"; 363 default: return "AMD unknown"; 364 } 365} 366 367static const char* r600_get_name(struct pipe_screen* pscreen) 368{ 369 struct r600_screen *rscreen = (struct r600_screen *)pscreen; 370 371 return r600_get_family_name(rscreen->family); 372} 373 374static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) 375{ 376 struct r600_screen *rscreen = (struct r600_screen *)pscreen; 377 enum radeon_family family = rscreen->family; 378 379 switch (param) { 380 /* Supported features (boolean caps). */ 381 case PIPE_CAP_NPOT_TEXTURES: 382 case PIPE_CAP_TWO_SIDED_STENCIL: 383 case PIPE_CAP_ANISOTROPIC_FILTER: 384 case PIPE_CAP_POINT_SPRITE: 385 case PIPE_CAP_OCCLUSION_QUERY: 386 case PIPE_CAP_TEXTURE_SHADOW_MAP: 387 case PIPE_CAP_TEXTURE_MIRROR_CLAMP: 388 case PIPE_CAP_BLEND_EQUATION_SEPARATE: 389 case PIPE_CAP_TEXTURE_SWIZZLE: 390 case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: 391 case PIPE_CAP_DEPTH_CLIP_DISABLE: 392 case PIPE_CAP_SHADER_STENCIL_EXPORT: 393 case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: 394 case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: 395 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: 396 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: 397 case PIPE_CAP_SM3: 398 case PIPE_CAP_SEAMLESS_CUBE_MAP: 399 case PIPE_CAP_PRIMITIVE_RESTART: 400 case PIPE_CAP_CONDITIONAL_RENDER: 401 case PIPE_CAP_TEXTURE_BARRIER: 402 case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: 403 case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: 404 case PIPE_CAP_TGSI_INSTANCEID: 405 return 1; 406 407 case PIPE_CAP_GLSL_FEATURE_LEVEL: 408 return debug_get_bool_option("R600_GLSL130", FALSE) ? 130 : 120; 409 410 /* Supported except the original R600. */ 411 case PIPE_CAP_INDEP_BLEND_ENABLE: 412 case PIPE_CAP_INDEP_BLEND_FUNC: 413 /* R600 doesn't support per-MRT blends */ 414 return family == CHIP_R600 ? 0 : 1; 415 416 /* Supported on Evergreen. */ 417 case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: 418 return family >= CHIP_CEDAR ? 1 : 0; 419 420 /* Unsupported features. */ 421 case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: 422 case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: 423 case PIPE_CAP_SCALED_RESOLVE: 424 case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS: 425 case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: 426 case PIPE_CAP_FRAGMENT_COLOR_CLAMPED: 427 case PIPE_CAP_VERTEX_COLOR_CLAMPED: 428 return 0; 429 430 /* Stream output. */ 431 case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: 432 return rscreen->info.r600_has_streamout ? 4 : 0; 433 case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: 434 return rscreen->info.r600_has_streamout ? 1 : 0; 435 case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: 436 case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: 437 return 16*4; 438 439 /* Texturing. */ 440 case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: 441 case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: 442 case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: 443 if (family >= CHIP_CEDAR) 444 return 15; 445 else 446 return 14; 447 case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: 448 return rscreen->info.drm_minor >= 9 ? 449 (family >= CHIP_CEDAR ? 16384 : 8192) : 0; 450 case PIPE_CAP_MAX_COMBINED_SAMPLERS: 451 return 32; 452 453 /* Render targets. */ 454 case PIPE_CAP_MAX_RENDER_TARGETS: 455 /* XXX some r6xx are buggy and can only do 4 */ 456 return 8; 457 458 /* Timer queries, present when the clock frequency is non zero. */ 459 case PIPE_CAP_TIMER_QUERY: 460 return rscreen->info.r600_clock_crystal_freq != 0; 461 462 case PIPE_CAP_MIN_TEXEL_OFFSET: 463 return -8; 464 465 case PIPE_CAP_MAX_TEXEL_OFFSET: 466 return 7; 467 468 case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: 469 return 0; 470 } 471 return 0; 472} 473 474static float r600_get_paramf(struct pipe_screen* pscreen, 475 enum pipe_capf param) 476{ 477 struct r600_screen *rscreen = (struct r600_screen *)pscreen; 478 enum radeon_family family = rscreen->family; 479 480 switch (param) { 481 case PIPE_CAPF_MAX_LINE_WIDTH: 482 case PIPE_CAPF_MAX_LINE_WIDTH_AA: 483 case PIPE_CAPF_MAX_POINT_WIDTH: 484 case PIPE_CAPF_MAX_POINT_WIDTH_AA: 485 if (family >= CHIP_CEDAR) 486 return 16384.0f; 487 else 488 return 8192.0f; 489 case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 490 return 16.0f; 491 case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 492 return 16.0f; 493 case PIPE_CAPF_GUARD_BAND_LEFT: 494 case PIPE_CAPF_GUARD_BAND_TOP: 495 case PIPE_CAPF_GUARD_BAND_RIGHT: 496 case PIPE_CAPF_GUARD_BAND_BOTTOM: 497 return 0.0f; 498 } 499 return 0.0f; 500} 501 502static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, enum pipe_shader_cap param) 503{ 504 switch(shader) 505 { 506 case PIPE_SHADER_FRAGMENT: 507 case PIPE_SHADER_VERTEX: 508 break; 509 case PIPE_SHADER_GEOMETRY: 510 /* XXX: support and enable geometry programs */ 511 return 0; 512 default: 513 /* XXX: support tessellation on Evergreen */ 514 return 0; 515 } 516 517 /* XXX: all these should be fixed, since r600 surely supports much more! */ 518 switch (param) { 519 case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: 520 case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: 521 case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: 522 case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: 523 return 16384; 524 case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: 525 return 8; /* XXX */ 526 case PIPE_SHADER_CAP_MAX_INPUTS: 527 if(shader == PIPE_SHADER_FRAGMENT) 528 return 34; 529 else 530 return 32; 531 case PIPE_SHADER_CAP_MAX_TEMPS: 532 return 256; /* Max native temporaries. */ 533 case PIPE_SHADER_CAP_MAX_ADDRS: 534 /* XXX Isn't this equal to TEMPS? */ 535 return 1; /* Max native address registers */ 536 case PIPE_SHADER_CAP_MAX_CONSTS: 537 return R600_MAX_CONST_BUFFER_SIZE; 538 case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: 539 return R600_MAX_CONST_BUFFERS-1; 540 case PIPE_SHADER_CAP_MAX_PREDS: 541 return 0; /* nothing uses this */ 542 case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: 543 return 1; 544 case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: 545 case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: 546 case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: 547 case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: 548 return 1; 549 case PIPE_SHADER_CAP_SUBROUTINES: 550 return 0; 551 case PIPE_SHADER_CAP_INTEGERS: 552 return 0; 553 case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: 554 return 16; 555 } 556 return 0; 557} 558 559static int r600_get_video_param(struct pipe_screen *screen, 560 enum pipe_video_profile profile, 561 enum pipe_video_cap param) 562{ 563 switch (param) { 564 case PIPE_VIDEO_CAP_SUPPORTED: 565 return vl_profile_supported(screen, profile); 566 case PIPE_VIDEO_CAP_NPOT_TEXTURES: 567 return 1; 568 case PIPE_VIDEO_CAP_MAX_WIDTH: 569 case PIPE_VIDEO_CAP_MAX_HEIGHT: 570 return vl_video_buffer_max_size(screen); 571 case PIPE_VIDEO_CAP_PREFERED_FORMAT: 572 return PIPE_FORMAT_NV12; 573 case PIPE_VIDEO_CAP_PREFERS_INTERLACED: 574 return false; 575 case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED: 576 return false; 577 case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE: 578 return true; 579 default: 580 return 0; 581 } 582} 583 584static void r600_destroy_screen(struct pipe_screen* pscreen) 585{ 586 struct r600_screen *rscreen = (struct r600_screen *)pscreen; 587 588 if (rscreen == NULL) 589 return; 590 591 if (rscreen->fences.bo) { 592 struct r600_fence_block *entry, *tmp; 593 594 LIST_FOR_EACH_ENTRY_SAFE(entry, tmp, &rscreen->fences.blocks, head) { 595 LIST_DEL(&entry->head); 596 FREE(entry); 597 } 598 599 rscreen->ws->buffer_unmap(rscreen->fences.bo->buf); 600 pipe_resource_reference((struct pipe_resource**)&rscreen->fences.bo, NULL); 601 } 602 pipe_mutex_destroy(rscreen->fences.mutex); 603 604 rscreen->ws->destroy(rscreen->ws); 605 606 util_slab_destroy(&rscreen->pool_buffers); 607 pipe_mutex_destroy(rscreen->mutex_num_contexts); 608 FREE(rscreen); 609} 610 611static void r600_fence_reference(struct pipe_screen *pscreen, 612 struct pipe_fence_handle **ptr, 613 struct pipe_fence_handle *fence) 614{ 615 struct r600_fence **oldf = (struct r600_fence**)ptr; 616 struct r600_fence *newf = (struct r600_fence*)fence; 617 618 if (pipe_reference(&(*oldf)->reference, &newf->reference)) { 619 struct r600_screen *rscreen = (struct r600_screen *)pscreen; 620 pipe_mutex_lock(rscreen->fences.mutex); 621 pipe_resource_reference((struct pipe_resource**)&(*oldf)->sleep_bo, NULL); 622 LIST_ADDTAIL(&(*oldf)->head, &rscreen->fences.pool); 623 pipe_mutex_unlock(rscreen->fences.mutex); 624 } 625 626 *ptr = fence; 627} 628 629static boolean r600_fence_signalled(struct pipe_screen *pscreen, 630 struct pipe_fence_handle *fence) 631{ 632 struct r600_screen *rscreen = (struct r600_screen *)pscreen; 633 struct r600_fence *rfence = (struct r600_fence*)fence; 634 635 return rscreen->fences.data[rfence->index]; 636} 637 638static boolean r600_fence_finish(struct pipe_screen *pscreen, 639 struct pipe_fence_handle *fence, 640 uint64_t timeout) 641{ 642 struct r600_screen *rscreen = (struct r600_screen *)pscreen; 643 struct r600_fence *rfence = (struct r600_fence*)fence; 644 int64_t start_time = 0; 645 unsigned spins = 0; 646 647 if (timeout != PIPE_TIMEOUT_INFINITE) { 648 start_time = os_time_get(); 649 650 /* Convert to microseconds. */ 651 timeout /= 1000; 652 } 653 654 while (rscreen->fences.data[rfence->index] == 0) { 655 /* Special-case infinite timeout - wait for the dummy BO to become idle */ 656 if (timeout == PIPE_TIMEOUT_INFINITE) { 657 rscreen->ws->buffer_wait(rfence->sleep_bo->buf, RADEON_USAGE_READWRITE); 658 break; 659 } 660 661 /* The dummy BO will be busy until the CS including the fence has completed, or 662 * the GPU is reset. Don't bother continuing to spin when the BO is idle. */ 663 if (!rscreen->ws->buffer_is_busy(rfence->sleep_bo->buf, RADEON_USAGE_READWRITE)) 664 break; 665 666 if (++spins % 256) 667 continue; 668#ifdef PIPE_OS_UNIX 669 sched_yield(); 670#else 671 os_time_sleep(10); 672#endif 673 if (timeout != PIPE_TIMEOUT_INFINITE && 674 os_time_get() - start_time >= timeout) { 675 break; 676 } 677 } 678 679 return rscreen->fences.data[rfence->index] != 0; 680} 681 682static int r600_interpret_tiling(struct r600_screen *rscreen, uint32_t tiling_config) 683{ 684 switch ((tiling_config & 0xe) >> 1) { 685 case 0: 686 rscreen->tiling_info.num_channels = 1; 687 break; 688 case 1: 689 rscreen->tiling_info.num_channels = 2; 690 break; 691 case 2: 692 rscreen->tiling_info.num_channels = 4; 693 break; 694 case 3: 695 rscreen->tiling_info.num_channels = 8; 696 break; 697 default: 698 return -EINVAL; 699 } 700 701 switch ((tiling_config & 0x30) >> 4) { 702 case 0: 703 rscreen->tiling_info.num_banks = 4; 704 break; 705 case 1: 706 rscreen->tiling_info.num_banks = 8; 707 break; 708 default: 709 return -EINVAL; 710 711 } 712 switch ((tiling_config & 0xc0) >> 6) { 713 case 0: 714 rscreen->tiling_info.group_bytes = 256; 715 break; 716 case 1: 717 rscreen->tiling_info.group_bytes = 512; 718 break; 719 default: 720 return -EINVAL; 721 } 722 return 0; 723} 724 725static int evergreen_interpret_tiling(struct r600_screen *rscreen, uint32_t tiling_config) 726{ 727 switch (tiling_config & 0xf) { 728 case 0: 729 rscreen->tiling_info.num_channels = 1; 730 break; 731 case 1: 732 rscreen->tiling_info.num_channels = 2; 733 break; 734 case 2: 735 rscreen->tiling_info.num_channels = 4; 736 break; 737 case 3: 738 rscreen->tiling_info.num_channels = 8; 739 break; 740 default: 741 return -EINVAL; 742 } 743 744 switch ((tiling_config & 0xf0) >> 4) { 745 case 0: 746 rscreen->tiling_info.num_banks = 4; 747 break; 748 case 1: 749 rscreen->tiling_info.num_banks = 8; 750 break; 751 case 2: 752 rscreen->tiling_info.num_banks = 16; 753 break; 754 default: 755 return -EINVAL; 756 } 757 758 switch ((tiling_config & 0xf00) >> 8) { 759 case 0: 760 rscreen->tiling_info.group_bytes = 256; 761 break; 762 case 1: 763 rscreen->tiling_info.group_bytes = 512; 764 break; 765 default: 766 return -EINVAL; 767 } 768 return 0; 769} 770 771static int r600_init_tiling(struct r600_screen *rscreen) 772{ 773 uint32_t tiling_config = rscreen->info.r600_tiling_config; 774 775 /* set default group bytes, overridden by tiling info ioctl */ 776 if (rscreen->chip_class <= R700) { 777 rscreen->tiling_info.group_bytes = 256; 778 } else { 779 rscreen->tiling_info.group_bytes = 512; 780 } 781 782 if (!tiling_config) 783 return 0; 784 785 if (rscreen->chip_class <= R700) { 786 return r600_interpret_tiling(rscreen, tiling_config); 787 } else { 788 return evergreen_interpret_tiling(rscreen, tiling_config); 789 } 790} 791 792static unsigned radeon_family_from_device(unsigned device) 793{ 794 switch (device) { 795#define CHIPSET(pciid, name, family) case pciid: return CHIP_##family; 796#include "pci_ids/r600_pci_ids.h" 797#undef CHIPSET 798 default: 799 return CHIP_UNKNOWN; 800 } 801} 802 803struct pipe_screen *r600_screen_create(struct radeon_winsys *ws) 804{ 805 struct r600_screen *rscreen = CALLOC_STRUCT(r600_screen); 806 if (rscreen == NULL) { 807 return NULL; 808 } 809 810 rscreen->ws = ws; 811 ws->query_info(ws, &rscreen->info); 812 813 rscreen->family = radeon_family_from_device(rscreen->info.pci_id); 814 if (rscreen->family == CHIP_UNKNOWN) { 815 fprintf(stderr, "r600: Unknown chipset 0x%04X\n", rscreen->info.pci_id); 816 FREE(rscreen); 817 return NULL; 818 } 819 820 /* setup class */ 821 if (rscreen->family >= CHIP_CAYMAN) { 822 rscreen->chip_class = CAYMAN; 823 } else if (rscreen->family >= CHIP_CEDAR) { 824 rscreen->chip_class = EVERGREEN; 825 } else if (rscreen->family >= CHIP_RV770) { 826 rscreen->chip_class = R700; 827 } else { 828 rscreen->chip_class = R600; 829 } 830 831 /* XXX streamout is said to be broken on r700 and cayman */ 832 if ((rscreen->chip_class == R700 || 833 rscreen->chip_class == CAYMAN) && 834 !debug_get_bool_option("R600_STREAMOUT", FALSE)) { 835 rscreen->info.r600_has_streamout = false; 836 } 837 838 if (r600_init_tiling(rscreen)) { 839 FREE(rscreen); 840 return NULL; 841 } 842 843 rscreen->screen.destroy = r600_destroy_screen; 844 rscreen->screen.get_name = r600_get_name; 845 rscreen->screen.get_vendor = r600_get_vendor; 846 rscreen->screen.get_param = r600_get_param; 847 rscreen->screen.get_shader_param = r600_get_shader_param; 848 rscreen->screen.get_paramf = r600_get_paramf; 849 rscreen->screen.get_video_param = r600_get_video_param; 850 if (rscreen->chip_class >= EVERGREEN) { 851 rscreen->screen.is_format_supported = evergreen_is_format_supported; 852 } else { 853 rscreen->screen.is_format_supported = r600_is_format_supported; 854 } 855 rscreen->screen.is_video_format_supported = vl_video_buffer_is_format_supported; 856 rscreen->screen.context_create = r600_create_context; 857 rscreen->screen.fence_reference = r600_fence_reference; 858 rscreen->screen.fence_signalled = r600_fence_signalled; 859 rscreen->screen.fence_finish = r600_fence_finish; 860 r600_init_screen_resource_functions(&rscreen->screen); 861 862 util_format_s3tc_init(); 863 864 util_slab_create(&rscreen->pool_buffers, 865 sizeof(struct r600_resource), 64, 866 UTIL_SLAB_SINGLETHREADED); 867 868 pipe_mutex_init(rscreen->mutex_num_contexts); 869 870 rscreen->fences.bo = NULL; 871 rscreen->fences.data = NULL; 872 rscreen->fences.next_index = 0; 873 LIST_INITHEAD(&rscreen->fences.pool); 874 LIST_INITHEAD(&rscreen->fences.blocks); 875 pipe_mutex_init(rscreen->fences.mutex); 876 877 rscreen->use_surface_alloc = debug_get_bool_option("R600_SURF", TRUE); 878 879 return &rscreen->screen; 880} 881