1 /* 2 * Copyright 2009 Corbin Simpson <MostAwesomeDude (at) gmail.com> 3 * Copyright 2009 Joakim Sindholt <opensource (at) zhasha.com> 4 * Copyright 2011 Marek Olk <maraeo (at) gmail.com> 5 * Copyright 2015 Advanced Micro Devices, Inc. 6 * All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining 9 * a copy of this software and associated documentation files (the 10 * "Software"), to deal in the Software without restriction, including 11 * without limitation the rights to use, copy, modify, merge, publish, 12 * distribute, sub license, and/or sell copies of the Software, and to 13 * permit persons to whom the Software is furnished to do so, subject to 14 * the following conditions: 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS 20 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 23 * USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * The above copyright notice and this permission notice (including the 26 * next paragraph) shall be included in all copies or substantial portions 27 * of the Software. 28 */ 29 /* 30 * Authors: 31 * Marek Olk <maraeo (at) gmail.com> 32 */ 33 34 #include "amdgpu_cs.h" 35 #include "amdgpu_public.h" 36 37 #include "util/u_hash_table.h" 38 #include <amdgpu_drm.h> 39 #include <xf86drm.h> 40 #include <stdio.h> 41 #include <sys/stat.h> 42 #include "amd/common/amdgpu_id.h" 43 44 #define CIK_TILE_MODE_COLOR_2D 14 45 46 #define CIK__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f) 47 #define CIK__PIPE_CONFIG__ADDR_SURF_P2 0 48 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16 4 49 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16 5 50 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32 6 51 #define CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32 7 52 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8 53 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9 54 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10 55 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11 56 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12 57 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13 58 #define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14 59 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16 16 60 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16 17 61 62 #ifndef AMDGPU_INFO_NUM_EVICTIONS 63 #define AMDGPU_INFO_NUM_EVICTIONS 0x18 64 #endif 65 66 static struct util_hash_table *dev_tab = NULL; 67 pipe_static_mutex(dev_tab_mutex); 68 69 static unsigned cik_get_num_tile_pipes(struct amdgpu_gpu_info *info) 70 { 71 unsigned mode2d = info->gb_tile_mode[CIK_TILE_MODE_COLOR_2D]; 72 73 switch (CIK__GB_TILE_MODE__PIPE_CONFIG(mode2d)) { 74 case CIK__PIPE_CONFIG__ADDR_SURF_P2: 75 return 2; 76 case CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16: 77 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16: 78 case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32: 79 case CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32: 80 return 4; 81 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16: 82 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16: 83 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16: 84 case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16: 85 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16: 86 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32: 87 case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32: 88 return 8; 89 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16: 90 case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16: 91 return 16; 92 default: 93 fprintf(stderr, "Invalid CIK pipe configuration, assuming P2\n"); 94 assert(!"this should never occur"); 95 return 2; 96 } 97 } 98 99 /* Helper function to do the ioctls needed for setup and init. */ 100 static bool do_winsys_init(struct amdgpu_winsys *ws, int fd) 101 { 102 struct amdgpu_buffer_size_alignments alignment_info = {}; 103 struct amdgpu_heap_info vram, gtt; 104 struct drm_amdgpu_info_hw_ip dma = {}, uvd = {}, vce = {}; 105 uint32_t vce_version = 0, vce_feature = 0, uvd_version = 0, uvd_feature = 0; 106 uint32_t unused_feature; 107 int r, i, j; 108 drmDevicePtr devinfo; 109 110 /* Get PCI info. */ 111 r = drmGetDevice(fd, &devinfo); 112 if (r) { 113 fprintf(stderr, "amdgpu: drmGetDevice failed.\n"); 114 goto fail; 115 } 116 ws->info.pci_domain = devinfo->businfo.pci->domain; 117 ws->info.pci_bus = devinfo->businfo.pci->bus; 118 ws->info.pci_dev = devinfo->businfo.pci->dev; 119 ws->info.pci_func = devinfo->businfo.pci->func; 120 drmFreeDevice(&devinfo); 121 122 /* Query hardware and driver information. */ 123 r = amdgpu_query_gpu_info(ws->dev, &ws->amdinfo); 124 if (r) { 125 fprintf(stderr, "amdgpu: amdgpu_query_gpu_info failed.\n"); 126 goto fail; 127 } 128 129 r = amdgpu_query_buffer_size_alignment(ws->dev, &alignment_info); 130 if (r) { 131 fprintf(stderr, "amdgpu: amdgpu_query_buffer_size_alignment failed.\n"); 132 goto fail; 133 } 134 135 r = amdgpu_query_heap_info(ws->dev, AMDGPU_GEM_DOMAIN_VRAM, 0, &vram); 136 if (r) { 137 fprintf(stderr, "amdgpu: amdgpu_query_heap_info(vram) failed.\n"); 138 goto fail; 139 } 140 141 r = amdgpu_query_heap_info(ws->dev, AMDGPU_GEM_DOMAIN_GTT, 0, >t); 142 if (r) { 143 fprintf(stderr, "amdgpu: amdgpu_query_heap_info(gtt) failed.\n"); 144 goto fail; 145 } 146 147 r = amdgpu_query_hw_ip_info(ws->dev, AMDGPU_HW_IP_DMA, 0, &dma); 148 if (r) { 149 fprintf(stderr, "amdgpu: amdgpu_query_hw_ip_info(dma) failed.\n"); 150 goto fail; 151 } 152 153 r = amdgpu_query_hw_ip_info(ws->dev, AMDGPU_HW_IP_UVD, 0, &uvd); 154 if (r) { 155 fprintf(stderr, "amdgpu: amdgpu_query_hw_ip_info(uvd) failed.\n"); 156 goto fail; 157 } 158 159 r = amdgpu_query_firmware_version(ws->dev, AMDGPU_INFO_FW_GFX_ME, 0, 0, 160 &ws->info.me_fw_version, &unused_feature); 161 if (r) { 162 fprintf(stderr, "amdgpu: amdgpu_query_firmware_version(me) failed.\n"); 163 goto fail; 164 } 165 166 r = amdgpu_query_firmware_version(ws->dev, AMDGPU_INFO_FW_GFX_PFP, 0, 0, 167 &ws->info.pfp_fw_version, &unused_feature); 168 if (r) { 169 fprintf(stderr, "amdgpu: amdgpu_query_firmware_version(pfp) failed.\n"); 170 goto fail; 171 } 172 173 r = amdgpu_query_firmware_version(ws->dev, AMDGPU_INFO_FW_GFX_CE, 0, 0, 174 &ws->info.ce_fw_version, &unused_feature); 175 if (r) { 176 fprintf(stderr, "amdgpu: amdgpu_query_firmware_version(ce) failed.\n"); 177 goto fail; 178 } 179 180 r = amdgpu_query_firmware_version(ws->dev, AMDGPU_INFO_FW_UVD, 0, 0, 181 &uvd_version, &uvd_feature); 182 if (r) { 183 fprintf(stderr, "amdgpu: amdgpu_query_firmware_version(uvd) failed.\n"); 184 goto fail; 185 } 186 187 r = amdgpu_query_hw_ip_info(ws->dev, AMDGPU_HW_IP_VCE, 0, &vce); 188 if (r) { 189 fprintf(stderr, "amdgpu: amdgpu_query_hw_ip_info(vce) failed.\n"); 190 goto fail; 191 } 192 193 r = amdgpu_query_firmware_version(ws->dev, AMDGPU_INFO_FW_VCE, 0, 0, 194 &vce_version, &vce_feature); 195 if (r) { 196 fprintf(stderr, "amdgpu: amdgpu_query_firmware_version(vce) failed.\n"); 197 goto fail; 198 } 199 200 /* Set chip identification. */ 201 ws->info.pci_id = ws->amdinfo.asic_id; /* TODO: is this correct? */ 202 ws->info.vce_harvest_config = ws->amdinfo.vce_harvest_config; 203 204 switch (ws->info.pci_id) { 205 #define CHIPSET(pci_id, name, cfamily) case pci_id: ws->info.family = CHIP_##cfamily; break; 206 #include "pci_ids/radeonsi_pci_ids.h" 207 #undef CHIPSET 208 209 default: 210 fprintf(stderr, "amdgpu: Invalid PCI ID.\n"); 211 goto fail; 212 } 213 214 if (ws->info.family >= CHIP_TONGA) 215 ws->info.chip_class = VI; 216 else if (ws->info.family >= CHIP_BONAIRE) 217 ws->info.chip_class = CIK; 218 else if (ws->info.family >= CHIP_TAHITI) 219 ws->info.chip_class = SI; 220 else { 221 fprintf(stderr, "amdgpu: Unknown family.\n"); 222 goto fail; 223 } 224 225 /* LLVM 3.6.1 is required for VI. */ 226 if (ws->info.chip_class >= VI && 227 HAVE_LLVM == 0x0306 && MESA_LLVM_VERSION_PATCH < 1) { 228 fprintf(stderr, "amdgpu: LLVM 3.6.1 is required, got LLVM %i.%i.%i\n", 229 HAVE_LLVM >> 8, HAVE_LLVM & 255, MESA_LLVM_VERSION_PATCH); 230 goto fail; 231 } 232 233 /* family and rev_id are for addrlib */ 234 switch (ws->info.family) { 235 case CHIP_TAHITI: 236 ws->family = FAMILY_SI; 237 ws->rev_id = SI_TAHITI_P_A0; 238 break; 239 case CHIP_PITCAIRN: 240 ws->family = FAMILY_SI; 241 ws->rev_id = SI_PITCAIRN_PM_A0; 242 break; 243 case CHIP_VERDE: 244 ws->family = FAMILY_SI; 245 ws->rev_id = SI_CAPEVERDE_M_A0; 246 break; 247 case CHIP_OLAND: 248 ws->family = FAMILY_SI; 249 ws->rev_id = SI_OLAND_M_A0; 250 break; 251 case CHIP_HAINAN: 252 ws->family = FAMILY_SI; 253 ws->rev_id = SI_HAINAN_V_A0; 254 break; 255 case CHIP_BONAIRE: 256 ws->family = FAMILY_CI; 257 ws->rev_id = CI_BONAIRE_M_A0; 258 break; 259 case CHIP_KAVERI: 260 ws->family = FAMILY_KV; 261 ws->rev_id = KV_SPECTRE_A0; 262 break; 263 case CHIP_KABINI: 264 ws->family = FAMILY_KV; 265 ws->rev_id = KB_KALINDI_A0; 266 break; 267 case CHIP_HAWAII: 268 ws->family = FAMILY_CI; 269 ws->rev_id = CI_HAWAII_P_A0; 270 break; 271 case CHIP_MULLINS: 272 ws->family = FAMILY_KV; 273 ws->rev_id = ML_GODAVARI_A0; 274 break; 275 case CHIP_TONGA: 276 ws->family = FAMILY_VI; 277 ws->rev_id = VI_TONGA_P_A0; 278 break; 279 case CHIP_ICELAND: 280 ws->family = FAMILY_VI; 281 ws->rev_id = VI_ICELAND_M_A0; 282 break; 283 case CHIP_CARRIZO: 284 ws->family = FAMILY_CZ; 285 ws->rev_id = CARRIZO_A0; 286 break; 287 case CHIP_STONEY: 288 ws->family = FAMILY_CZ; 289 ws->rev_id = STONEY_A0; 290 break; 291 case CHIP_FIJI: 292 ws->family = FAMILY_VI; 293 ws->rev_id = VI_FIJI_P_A0; 294 break; 295 case CHIP_POLARIS10: 296 ws->family = FAMILY_VI; 297 ws->rev_id = VI_POLARIS10_P_A0; 298 break; 299 case CHIP_POLARIS11: 300 ws->family = FAMILY_VI; 301 ws->rev_id = VI_POLARIS11_M_A0; 302 break; 303 case CHIP_POLARIS12: 304 ws->family = FAMILY_VI; 305 ws->rev_id = VI_POLARIS12_V_A0; 306 break; 307 default: 308 fprintf(stderr, "amdgpu: Unknown family.\n"); 309 goto fail; 310 } 311 312 ws->addrlib = amdgpu_addr_create(ws); 313 if (!ws->addrlib) { 314 fprintf(stderr, "amdgpu: Cannot create addrlib.\n"); 315 goto fail; 316 } 317 318 /* Set which chips have dedicated VRAM. */ 319 ws->info.has_dedicated_vram = 320 !(ws->amdinfo.ids_flags & AMDGPU_IDS_FLAGS_FUSION); 321 322 /* Set hardware information. */ 323 ws->info.gart_size = gtt.heap_size; 324 ws->info.vram_size = vram.heap_size; 325 /* The kernel can split large buffers in VRAM but not in GTT, so large 326 * allocations can fail or cause buffer movement failures in the kernel. 327 */ 328 ws->info.max_alloc_size = MIN2(ws->info.vram_size * 0.9, ws->info.gart_size * 0.7); 329 /* convert the shader clock from KHz to MHz */ 330 ws->info.max_shader_clock = ws->amdinfo.max_engine_clk / 1000; 331 ws->info.max_se = ws->amdinfo.num_shader_engines; 332 ws->info.max_sh_per_se = ws->amdinfo.num_shader_arrays_per_engine; 333 ws->info.has_uvd = uvd.available_rings != 0; 334 ws->info.uvd_fw_version = 335 uvd.available_rings ? uvd_version : 0; 336 ws->info.vce_fw_version = 337 vce.available_rings ? vce_version : 0; 338 ws->info.has_userptr = true; 339 ws->info.num_render_backends = ws->amdinfo.rb_pipes; 340 ws->info.clock_crystal_freq = ws->amdinfo.gpu_counter_freq; 341 ws->info.num_tile_pipes = cik_get_num_tile_pipes(&ws->amdinfo); 342 ws->info.pipe_interleave_bytes = 256 << ((ws->amdinfo.gb_addr_cfg >> 4) & 0x7); 343 ws->info.has_virtual_memory = true; 344 ws->info.has_sdma = dma.available_rings != 0; 345 346 /* Get the number of good compute units. */ 347 ws->info.num_good_compute_units = 0; 348 for (i = 0; i < ws->info.max_se; i++) 349 for (j = 0; j < ws->info.max_sh_per_se; j++) 350 ws->info.num_good_compute_units += 351 util_bitcount(ws->amdinfo.cu_bitmap[i][j]); 352 353 memcpy(ws->info.si_tile_mode_array, ws->amdinfo.gb_tile_mode, 354 sizeof(ws->amdinfo.gb_tile_mode)); 355 ws->info.enabled_rb_mask = ws->amdinfo.enabled_rb_pipes_mask; 356 357 memcpy(ws->info.cik_macrotile_mode_array, ws->amdinfo.gb_macro_tile_mode, 358 sizeof(ws->amdinfo.gb_macro_tile_mode)); 359 360 ws->info.gart_page_size = alignment_info.size_remote; 361 362 if (ws->info.chip_class == SI) 363 ws->info.gfx_ib_pad_with_type2 = TRUE; 364 365 ws->check_vm = strstr(debug_get_option("R600_DEBUG", ""), "check_vm") != NULL; 366 367 return true; 368 369 fail: 370 if (ws->addrlib) 371 AddrDestroy(ws->addrlib); 372 amdgpu_device_deinitialize(ws->dev); 373 ws->dev = NULL; 374 return false; 375 } 376 377 static void do_winsys_deinit(struct amdgpu_winsys *ws) 378 { 379 AddrDestroy(ws->addrlib); 380 amdgpu_device_deinitialize(ws->dev); 381 } 382 383 static void amdgpu_winsys_destroy(struct radeon_winsys *rws) 384 { 385 struct amdgpu_winsys *ws = (struct amdgpu_winsys*)rws; 386 387 if (util_queue_is_initialized(&ws->cs_queue)) 388 util_queue_destroy(&ws->cs_queue); 389 390 pipe_mutex_destroy(ws->bo_fence_lock); 391 pb_slabs_deinit(&ws->bo_slabs); 392 pb_cache_deinit(&ws->bo_cache); 393 pipe_mutex_destroy(ws->global_bo_list_lock); 394 do_winsys_deinit(ws); 395 FREE(rws); 396 } 397 398 static void amdgpu_winsys_query_info(struct radeon_winsys *rws, 399 struct radeon_info *info) 400 { 401 *info = ((struct amdgpu_winsys *)rws)->info; 402 } 403 404 static bool amdgpu_cs_request_feature(struct radeon_winsys_cs *rcs, 405 enum radeon_feature_id fid, 406 bool enable) 407 { 408 return false; 409 } 410 411 static uint64_t amdgpu_query_value(struct radeon_winsys *rws, 412 enum radeon_value_id value) 413 { 414 struct amdgpu_winsys *ws = (struct amdgpu_winsys*)rws; 415 struct amdgpu_heap_info heap; 416 uint64_t retval = 0; 417 418 switch (value) { 419 case RADEON_REQUESTED_VRAM_MEMORY: 420 return ws->allocated_vram; 421 case RADEON_REQUESTED_GTT_MEMORY: 422 return ws->allocated_gtt; 423 case RADEON_MAPPED_VRAM: 424 return ws->mapped_vram; 425 case RADEON_MAPPED_GTT: 426 return ws->mapped_gtt; 427 case RADEON_BUFFER_WAIT_TIME_NS: 428 return ws->buffer_wait_time; 429 case RADEON_TIMESTAMP: 430 amdgpu_query_info(ws->dev, AMDGPU_INFO_TIMESTAMP, 8, &retval); 431 return retval; 432 case RADEON_NUM_GFX_IBS: 433 return ws->num_gfx_IBs; 434 case RADEON_NUM_SDMA_IBS: 435 return ws->num_sdma_IBs; 436 case RADEON_NUM_BYTES_MOVED: 437 amdgpu_query_info(ws->dev, AMDGPU_INFO_NUM_BYTES_MOVED, 8, &retval); 438 return retval; 439 case RADEON_NUM_EVICTIONS: 440 amdgpu_query_info(ws->dev, AMDGPU_INFO_NUM_EVICTIONS, 8, &retval); 441 return retval; 442 case RADEON_VRAM_USAGE: 443 amdgpu_query_heap_info(ws->dev, AMDGPU_GEM_DOMAIN_VRAM, 0, &heap); 444 return heap.heap_usage; 445 case RADEON_GTT_USAGE: 446 amdgpu_query_heap_info(ws->dev, AMDGPU_GEM_DOMAIN_GTT, 0, &heap); 447 return heap.heap_usage; 448 case RADEON_GPU_TEMPERATURE: 449 case RADEON_CURRENT_SCLK: 450 case RADEON_CURRENT_MCLK: 451 return 0; 452 case RADEON_GPU_RESET_COUNTER: 453 assert(0); 454 return 0; 455 } 456 return 0; 457 } 458 459 static bool amdgpu_read_registers(struct radeon_winsys *rws, 460 unsigned reg_offset, 461 unsigned num_registers, uint32_t *out) 462 { 463 struct amdgpu_winsys *ws = (struct amdgpu_winsys*)rws; 464 465 return amdgpu_read_mm_registers(ws->dev, reg_offset / 4, num_registers, 466 0xffffffff, 0, out) == 0; 467 } 468 469 static unsigned hash_dev(void *key) 470 { 471 #if defined(PIPE_ARCH_X86_64) 472 return pointer_to_intptr(key) ^ (pointer_to_intptr(key) >> 32); 473 #else 474 return pointer_to_intptr(key); 475 #endif 476 } 477 478 static int compare_dev(void *key1, void *key2) 479 { 480 return key1 != key2; 481 } 482 483 static bool amdgpu_winsys_unref(struct radeon_winsys *rws) 484 { 485 struct amdgpu_winsys *ws = (struct amdgpu_winsys*)rws; 486 bool destroy; 487 488 /* When the reference counter drops to zero, remove the device pointer 489 * from the table. 490 * This must happen while the mutex is locked, so that 491 * amdgpu_winsys_create in another thread doesn't get the winsys 492 * from the table when the counter drops to 0. */ 493 pipe_mutex_lock(dev_tab_mutex); 494 495 destroy = pipe_reference(&ws->reference, NULL); 496 if (destroy && dev_tab) 497 util_hash_table_remove(dev_tab, ws->dev); 498 499 pipe_mutex_unlock(dev_tab_mutex); 500 return destroy; 501 } 502 503 PUBLIC struct radeon_winsys * 504 amdgpu_winsys_create(int fd, radeon_screen_create_t screen_create) 505 { 506 struct amdgpu_winsys *ws; 507 drmVersionPtr version = drmGetVersion(fd); 508 amdgpu_device_handle dev; 509 uint32_t drm_major, drm_minor, r; 510 511 /* The DRM driver version of amdgpu is 3.x.x. */ 512 if (version->version_major != 3) { 513 drmFreeVersion(version); 514 return NULL; 515 } 516 drmFreeVersion(version); 517 518 /* Look up the winsys from the dev table. */ 519 pipe_mutex_lock(dev_tab_mutex); 520 if (!dev_tab) 521 dev_tab = util_hash_table_create(hash_dev, compare_dev); 522 523 /* Initialize the amdgpu device. This should always return the same pointer 524 * for the same fd. */ 525 r = amdgpu_device_initialize(fd, &drm_major, &drm_minor, &dev); 526 if (r) { 527 pipe_mutex_unlock(dev_tab_mutex); 528 fprintf(stderr, "amdgpu: amdgpu_device_initialize failed.\n"); 529 return NULL; 530 } 531 532 /* Lookup a winsys if we have already created one for this device. */ 533 ws = util_hash_table_get(dev_tab, dev); 534 if (ws) { 535 pipe_reference(NULL, &ws->reference); 536 pipe_mutex_unlock(dev_tab_mutex); 537 return &ws->base; 538 } 539 540 /* Create a new winsys. */ 541 ws = CALLOC_STRUCT(amdgpu_winsys); 542 if (!ws) 543 goto fail; 544 545 ws->dev = dev; 546 ws->info.drm_major = drm_major; 547 ws->info.drm_minor = drm_minor; 548 549 if (!do_winsys_init(ws, fd)) 550 goto fail_alloc; 551 552 /* Create managers. */ 553 pb_cache_init(&ws->bo_cache, 500000, ws->check_vm ? 1.0f : 2.0f, 0, 554 (ws->info.vram_size + ws->info.gart_size) / 8, 555 amdgpu_bo_destroy, amdgpu_bo_can_reclaim); 556 557 if (!pb_slabs_init(&ws->bo_slabs, 558 AMDGPU_SLAB_MIN_SIZE_LOG2, AMDGPU_SLAB_MAX_SIZE_LOG2, 559 12, /* number of heaps (domain/flags combinations) */ 560 ws, 561 amdgpu_bo_can_reclaim_slab, 562 amdgpu_bo_slab_alloc, 563 amdgpu_bo_slab_free)) 564 goto fail_cache; 565 566 ws->info.min_alloc_size = 1 << AMDGPU_SLAB_MIN_SIZE_LOG2; 567 568 /* init reference */ 569 pipe_reference_init(&ws->reference, 1); 570 571 /* Set functions. */ 572 ws->base.unref = amdgpu_winsys_unref; 573 ws->base.destroy = amdgpu_winsys_destroy; 574 ws->base.query_info = amdgpu_winsys_query_info; 575 ws->base.cs_request_feature = amdgpu_cs_request_feature; 576 ws->base.query_value = amdgpu_query_value; 577 ws->base.read_registers = amdgpu_read_registers; 578 579 amdgpu_bo_init_functions(ws); 580 amdgpu_cs_init_functions(ws); 581 amdgpu_surface_init_functions(ws); 582 583 LIST_INITHEAD(&ws->global_bo_list); 584 pipe_mutex_init(ws->global_bo_list_lock); 585 pipe_mutex_init(ws->bo_fence_lock); 586 587 if (!util_queue_init(&ws->cs_queue, "amdgpu_cs", 8, 1)) { 588 amdgpu_winsys_destroy(&ws->base); 589 pipe_mutex_unlock(dev_tab_mutex); 590 return NULL; 591 } 592 593 /* Create the screen at the end. The winsys must be initialized 594 * completely. 595 * 596 * Alternatively, we could create the screen based on "ws->gen" 597 * and link all drivers into one binary blob. */ 598 ws->base.screen = screen_create(&ws->base); 599 if (!ws->base.screen) { 600 amdgpu_winsys_destroy(&ws->base); 601 pipe_mutex_unlock(dev_tab_mutex); 602 return NULL; 603 } 604 605 util_hash_table_set(dev_tab, dev, ws); 606 607 /* We must unlock the mutex once the winsys is fully initialized, so that 608 * other threads attempting to create the winsys from the same fd will 609 * get a fully initialized winsys and not just half-way initialized. */ 610 pipe_mutex_unlock(dev_tab_mutex); 611 612 return &ws->base; 613 614 fail_cache: 615 pb_cache_deinit(&ws->bo_cache); 616 do_winsys_deinit(ws); 617 fail_alloc: 618 FREE(ws); 619 fail: 620 pipe_mutex_unlock(dev_tab_mutex); 621 return NULL; 622 } 623