Home | History | Annotate | Download | only in drm
      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, &gtt);
    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