X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fwinsys%2Famdgpu%2Fdrm%2Famdgpu_winsys.c;h=79d2c1345efc61a3d8104fc89b1803edb51ddcb1;hb=ec22dd34c88f8b24a1b4f5b25f4de2aa89f0cad4;hp=a9c5c01c9504d14d56f8e86477b13541e23231b0;hpb=f187a493225e33c5ce514c731a0a140d61dacb0b;p=mesa.git diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c index a9c5c01c950..79d2c1345ef 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c @@ -26,286 +26,89 @@ * next paragraph) shall be included in all copies or substantial portions * of the Software. */ -/* - * Authors: - * Marek Olšák - */ #include "amdgpu_cs.h" #include "amdgpu_public.h" +#include "util/u_cpu_detect.h" #include "util/u_hash_table.h" +#include "util/hash_table.h" +#include "util/xmlconfig.h" #include #include #include #include -#include "amd/common/amdgpu_id.h" +#include "amd/common/ac_llvm_util.h" #include "amd/common/sid.h" #include "amd/common/gfx9d.h" -#define CIK_TILE_MODE_COLOR_2D 14 - -#define CIK__GB_TILE_MODE__PIPE_CONFIG(x) (((x) >> 6) & 0x1f) -#define CIK__PIPE_CONFIG__ADDR_SURF_P2 0 -#define CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16 4 -#define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16 5 -#define CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32 6 -#define CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32 7 -#define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16 8 -#define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16 9 -#define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16 10 -#define CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16 11 -#define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16 12 -#define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32 13 -#define CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32 14 -#define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16 16 -#define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16 17 +#ifndef AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS +#define AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS 0x1E +#endif static struct util_hash_table *dev_tab = NULL; -static mtx_t dev_tab_mutex = _MTX_INITIALIZER_NP; +static simple_mtx_t dev_tab_mutex = _SIMPLE_MTX_INITIALIZER_NP; -static unsigned cik_get_num_tile_pipes(struct amdgpu_gpu_info *info) +DEBUG_GET_ONCE_BOOL_OPTION(all_bos, "RADEON_ALL_BOS", false) + +static void handle_env_var_force_family(struct amdgpu_winsys *ws) { - unsigned mode2d = info->gb_tile_mode[CIK_TILE_MODE_COLOR_2D]; - - switch (CIK__GB_TILE_MODE__PIPE_CONFIG(mode2d)) { - case CIK__PIPE_CONFIG__ADDR_SURF_P2: - return 2; - case CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16: - case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16: - case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32: - case CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32: - return 4; - case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16: - case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16: - case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16: - case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16: - case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16: - case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32: - case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32: - return 8; - case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16: - case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16: - return 16; - default: - fprintf(stderr, "Invalid CIK pipe configuration, assuming P2\n"); - assert(!"this should never occur"); - return 2; - } + const char *family = debug_get_option("SI_FORCE_FAMILY", NULL); + unsigned i; + + if (!family) + return; + + for (i = CHIP_TAHITI; i < CHIP_LAST; i++) { + if (!strcmp(family, ac_get_llvm_processor_name(i))) { + /* Override family and chip_class. */ + ws->info.family = i; + ws->info.name = "GCN-NOOP"; + + if (i >= CHIP_VEGA10) + ws->info.chip_class = GFX9; + else if (i >= CHIP_TONGA) + ws->info.chip_class = VI; + else if (i >= CHIP_BONAIRE) + ws->info.chip_class = CIK; + else + ws->info.chip_class = SI; + + /* Don't submit any IBs. */ + setenv("RADEON_NOOP", "1", 1); + return; + } + } + + fprintf(stderr, "radeonsi: Unknown family: %s\n", family); + exit(1); } /* Helper function to do the ioctls needed for setup and init. */ -static bool do_winsys_init(struct amdgpu_winsys *ws, int fd) +static bool do_winsys_init(struct amdgpu_winsys *ws, + const struct pipe_screen_config *config, + int fd) { - struct amdgpu_buffer_size_alignments alignment_info = {}; - struct amdgpu_heap_info vram, vram_vis, gtt; - struct drm_amdgpu_info_hw_ip dma = {}, uvd = {}, vce = {}; - uint32_t vce_version = 0, vce_feature = 0, uvd_version = 0, uvd_feature = 0; - uint32_t unused_feature; - int r, i, j; - drmDevicePtr devinfo; - - /* Get PCI info. */ - r = drmGetDevice2(fd, 0, &devinfo); - if (r) { - fprintf(stderr, "amdgpu: drmGetDevice2 failed.\n"); - goto fail; - } - ws->info.pci_domain = devinfo->businfo.pci->domain; - ws->info.pci_bus = devinfo->businfo.pci->bus; - ws->info.pci_dev = devinfo->businfo.pci->dev; - ws->info.pci_func = devinfo->businfo.pci->func; - drmFreeDevice(&devinfo); - - /* Query hardware and driver information. */ - r = amdgpu_query_gpu_info(ws->dev, &ws->amdinfo); - if (r) { - fprintf(stderr, "amdgpu: amdgpu_query_gpu_info failed.\n"); - goto fail; - } - - r = amdgpu_query_buffer_size_alignment(ws->dev, &alignment_info); - if (r) { - fprintf(stderr, "amdgpu: amdgpu_query_buffer_size_alignment failed.\n"); - goto fail; - } - - r = amdgpu_query_heap_info(ws->dev, AMDGPU_GEM_DOMAIN_VRAM, 0, &vram); - if (r) { - fprintf(stderr, "amdgpu: amdgpu_query_heap_info(vram) failed.\n"); + if (!ac_query_gpu_info(fd, ws->dev, &ws->info, &ws->amdinfo)) goto fail; - } - r = amdgpu_query_heap_info(ws->dev, AMDGPU_GEM_DOMAIN_VRAM, - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED, - &vram_vis); - if (r) { - fprintf(stderr, "amdgpu: amdgpu_query_heap_info(vram_vis) failed.\n"); - goto fail; - } + handle_env_var_force_family(ws); - r = amdgpu_query_heap_info(ws->dev, AMDGPU_GEM_DOMAIN_GTT, 0, >t); - if (r) { - fprintf(stderr, "amdgpu: amdgpu_query_heap_info(gtt) failed.\n"); - goto fail; - } - - r = amdgpu_query_hw_ip_info(ws->dev, AMDGPU_HW_IP_DMA, 0, &dma); - if (r) { - fprintf(stderr, "amdgpu: amdgpu_query_hw_ip_info(dma) failed.\n"); - goto fail; - } - - r = amdgpu_query_hw_ip_info(ws->dev, AMDGPU_HW_IP_UVD, 0, &uvd); - if (r) { - fprintf(stderr, "amdgpu: amdgpu_query_hw_ip_info(uvd) failed.\n"); - goto fail; - } - - r = amdgpu_query_firmware_version(ws->dev, AMDGPU_INFO_FW_GFX_ME, 0, 0, - &ws->info.me_fw_version, &unused_feature); - if (r) { - fprintf(stderr, "amdgpu: amdgpu_query_firmware_version(me) failed.\n"); - goto fail; - } - - r = amdgpu_query_firmware_version(ws->dev, AMDGPU_INFO_FW_GFX_PFP, 0, 0, - &ws->info.pfp_fw_version, &unused_feature); - if (r) { - fprintf(stderr, "amdgpu: amdgpu_query_firmware_version(pfp) failed.\n"); - goto fail; - } - - r = amdgpu_query_firmware_version(ws->dev, AMDGPU_INFO_FW_GFX_CE, 0, 0, - &ws->info.ce_fw_version, &unused_feature); - if (r) { - fprintf(stderr, "amdgpu: amdgpu_query_firmware_version(ce) failed.\n"); - goto fail; - } - - r = amdgpu_query_firmware_version(ws->dev, AMDGPU_INFO_FW_UVD, 0, 0, - &uvd_version, &uvd_feature); - if (r) { - fprintf(stderr, "amdgpu: amdgpu_query_firmware_version(uvd) failed.\n"); - goto fail; - } - - r = amdgpu_query_hw_ip_info(ws->dev, AMDGPU_HW_IP_VCE, 0, &vce); - if (r) { - fprintf(stderr, "amdgpu: amdgpu_query_hw_ip_info(vce) failed.\n"); - goto fail; - } - - r = amdgpu_query_firmware_version(ws->dev, AMDGPU_INFO_FW_VCE, 0, 0, - &vce_version, &vce_feature); - if (r) { - fprintf(stderr, "amdgpu: amdgpu_query_firmware_version(vce) failed.\n"); - goto fail; - } - - /* Set chip identification. */ - ws->info.pci_id = ws->amdinfo.asic_id; /* TODO: is this correct? */ - ws->info.vce_harvest_config = ws->amdinfo.vce_harvest_config; - - switch (ws->info.pci_id) { -#define CHIPSET(pci_id, name, cfamily) case pci_id: ws->info.family = CHIP_##cfamily; break; -#include "pci_ids/radeonsi_pci_ids.h" -#undef CHIPSET - - default: - fprintf(stderr, "amdgpu: Invalid PCI ID.\n"); - goto fail; - } - - if (ws->info.family >= CHIP_VEGA10) - ws->info.chip_class = GFX9; - else if (ws->info.family >= CHIP_TONGA) - ws->info.chip_class = VI; - else if (ws->info.family >= CHIP_BONAIRE) - ws->info.chip_class = CIK; - else if (ws->info.family >= CHIP_TAHITI) - ws->info.chip_class = SI; - else { - fprintf(stderr, "amdgpu: Unknown family.\n"); - goto fail; - } - - /* LLVM 5.0 is required for GFX9. */ - if (ws->info.chip_class >= GFX9 && HAVE_LLVM < 0x0500) { - fprintf(stderr, "amdgpu: LLVM 5.0 is required, got LLVM %i.%i\n", - HAVE_LLVM >> 8, HAVE_LLVM & 255); - goto fail; - } - - ws->addrlib = amdgpu_addr_create(ws->info.family, &ws->amdinfo); + ws->addrlib = amdgpu_addr_create(&ws->info, &ws->amdinfo, &ws->info.max_alignment); if (!ws->addrlib) { fprintf(stderr, "amdgpu: Cannot create addrlib.\n"); goto fail; } - /* Set which chips have dedicated VRAM. */ - ws->info.has_dedicated_vram = - !(ws->amdinfo.ids_flags & AMDGPU_IDS_FLAGS_FUSION); - - /* Set hardware information. */ - ws->info.gart_size = gtt.heap_size; - ws->info.vram_size = vram.heap_size; - ws->info.vram_vis_size = vram_vis.heap_size; - /* The kernel can split large buffers in VRAM but not in GTT, so large - * allocations can fail or cause buffer movement failures in the kernel. - */ - ws->info.max_alloc_size = MIN2(ws->info.vram_size * 0.9, ws->info.gart_size * 0.7); - /* convert the shader clock from KHz to MHz */ - ws->info.max_shader_clock = ws->amdinfo.max_engine_clk / 1000; - ws->info.max_se = ws->amdinfo.num_shader_engines; - ws->info.max_sh_per_se = ws->amdinfo.num_shader_arrays_per_engine; - ws->info.has_uvd = uvd.available_rings != 0; - ws->info.uvd_fw_version = - uvd.available_rings ? uvd_version : 0; - ws->info.vce_fw_version = - vce.available_rings ? vce_version : 0; - ws->info.has_userptr = true; - ws->info.num_render_backends = ws->amdinfo.rb_pipes; - ws->info.clock_crystal_freq = ws->amdinfo.gpu_counter_freq; - ws->info.tcc_cache_line_size = 64; /* TC L2 line size on GCN */ - if (ws->info.chip_class == GFX9) { - ws->info.num_tile_pipes = 1 << G_0098F8_NUM_PIPES(ws->amdinfo.gb_addr_cfg); - ws->info.pipe_interleave_bytes = - 256 << G_0098F8_PIPE_INTERLEAVE_SIZE_GFX9(ws->amdinfo.gb_addr_cfg); - } else { - ws->info.num_tile_pipes = cik_get_num_tile_pipes(&ws->amdinfo); - ws->info.pipe_interleave_bytes = - 256 << G_0098F8_PIPE_INTERLEAVE_SIZE_GFX6(ws->amdinfo.gb_addr_cfg); - } - ws->info.has_virtual_memory = true; - ws->info.has_sdma = dma.available_rings != 0; - - /* Get the number of good compute units. */ - ws->info.num_good_compute_units = 0; - for (i = 0; i < ws->info.max_se; i++) - for (j = 0; j < ws->info.max_sh_per_se; j++) - ws->info.num_good_compute_units += - util_bitcount(ws->amdinfo.cu_bitmap[i][j]); - - memcpy(ws->info.si_tile_mode_array, ws->amdinfo.gb_tile_mode, - sizeof(ws->amdinfo.gb_tile_mode)); - ws->info.enabled_rb_mask = ws->amdinfo.enabled_rb_pipes_mask; - - memcpy(ws->info.cik_macrotile_mode_array, ws->amdinfo.gb_macro_tile_mode, - sizeof(ws->amdinfo.gb_macro_tile_mode)); - - ws->info.gart_page_size = alignment_info.size_remote; - - if (ws->info.chip_class == SI) - ws->info.gfx_ib_pad_with_type2 = TRUE; - ws->check_vm = strstr(debug_get_option("R600_DEBUG", ""), "check_vm") != NULL; + ws->debug_all_bos = debug_get_option_all_bos(); + ws->reserve_vmid = strstr(debug_get_option("R600_DEBUG", ""), "reserve_vmid") != NULL; + ws->zero_all_vram_allocs = strstr(debug_get_option("R600_DEBUG", ""), "zerovram") != NULL || + driQueryOptionb(config->options, "radeonsi_zerovram"); return true; fail: - if (ws->addrlib) - AddrDestroy(ws->addrlib); amdgpu_device_deinitialize(ws->dev); ws->dev = NULL; return false; @@ -321,13 +124,21 @@ static void amdgpu_winsys_destroy(struct radeon_winsys *rws) { struct amdgpu_winsys *ws = (struct amdgpu_winsys*)rws; + if (ws->reserve_vmid) + amdgpu_vm_unreserve_vmid(ws->dev, 0); + if (util_queue_is_initialized(&ws->cs_queue)) util_queue_destroy(&ws->cs_queue); - mtx_destroy(&ws->bo_fence_lock); - pb_slabs_deinit(&ws->bo_slabs); + simple_mtx_destroy(&ws->bo_fence_lock); + for (unsigned i = 0; i < NUM_SLAB_ALLOCATORS; i++) { + if (ws->bo_slabs[i].groups) + pb_slabs_deinit(&ws->bo_slabs[i]); + } pb_cache_deinit(&ws->bo_cache); - mtx_destroy(&ws->global_bo_list_lock); + util_hash_table_destroy(ws->bo_export_table); + simple_mtx_destroy(&ws->global_bo_list_lock); + simple_mtx_destroy(&ws->bo_export_table_lock); do_winsys_deinit(ws); FREE(rws); } @@ -338,7 +149,7 @@ static void amdgpu_winsys_query_info(struct radeon_winsys *rws, *info = ((struct amdgpu_winsys *)rws)->info; } -static bool amdgpu_cs_request_feature(struct radeon_winsys_cs *rcs, +static bool amdgpu_cs_request_feature(struct radeon_cmdbuf *rcs, enum radeon_feature_id fid, bool enable) { @@ -372,12 +183,19 @@ static uint64_t amdgpu_query_value(struct radeon_winsys *rws, return ws->num_gfx_IBs; case RADEON_NUM_SDMA_IBS: return ws->num_sdma_IBs; + case RADEON_GFX_BO_LIST_COUNTER: + return ws->gfx_bo_list_counter; + case RADEON_GFX_IB_SIZE_COUNTER: + return ws->gfx_ib_size_counter; case RADEON_NUM_BYTES_MOVED: amdgpu_query_info(ws->dev, AMDGPU_INFO_NUM_BYTES_MOVED, 8, &retval); return retval; case RADEON_NUM_EVICTIONS: amdgpu_query_info(ws->dev, AMDGPU_INFO_NUM_EVICTIONS, 8, &retval); return retval; + case RADEON_NUM_VRAM_CPU_PAGE_FAULTS: + amdgpu_query_info(ws->dev, AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS, 8, &retval); + return retval; case RADEON_VRAM_USAGE: amdgpu_query_heap_info(ws->dev, AMDGPU_GEM_DOMAIN_VRAM, 0, &heap); return heap.heap_usage; @@ -416,16 +234,12 @@ static bool amdgpu_read_registers(struct radeon_winsys *rws, 0xffffffff, 0, out) == 0; } -static unsigned hash_dev(void *key) +static unsigned hash_pointer(void *key) { -#if defined(PIPE_ARCH_X86_64) - return pointer_to_intptr(key) ^ (pointer_to_intptr(key) >> 32); -#else - return pointer_to_intptr(key); -#endif + return _mesa_hash_pointer(key); } -static int compare_dev(void *key1, void *key2) +static int compare_pointers(void *key1, void *key2) { return key1 != key2; } @@ -440,18 +254,39 @@ static bool amdgpu_winsys_unref(struct radeon_winsys *rws) * This must happen while the mutex is locked, so that * amdgpu_winsys_create in another thread doesn't get the winsys * from the table when the counter drops to 0. */ - mtx_lock(&dev_tab_mutex); + simple_mtx_lock(&dev_tab_mutex); destroy = pipe_reference(&ws->reference, NULL); - if (destroy && dev_tab) + if (destroy && dev_tab) { util_hash_table_remove(dev_tab, ws->dev); + if (util_hash_table_count(dev_tab) == 0) { + util_hash_table_destroy(dev_tab); + dev_tab = NULL; + } + } - mtx_unlock(&dev_tab_mutex); + simple_mtx_unlock(&dev_tab_mutex); return destroy; } +static const char* amdgpu_get_chip_name(struct radeon_winsys *ws) +{ + amdgpu_device_handle dev = ((struct amdgpu_winsys *)ws)->dev; + return amdgpu_get_marketing_name(dev); +} + +static void amdgpu_pin_threads_to_L3_cache(struct radeon_winsys *rws, + unsigned cache) +{ + struct amdgpu_winsys *ws = (struct amdgpu_winsys*)rws; + + util_pin_thread_to_L3(ws->cs_queue.threads[0], cache, + util_cpu_caps.cores_per_L3); +} + PUBLIC struct radeon_winsys * -amdgpu_winsys_create(int fd, radeon_screen_create_t screen_create) +amdgpu_winsys_create(int fd, const struct pipe_screen_config *config, + radeon_screen_create_t screen_create) { struct amdgpu_winsys *ws; drmVersionPtr version = drmGetVersion(fd); @@ -466,15 +301,15 @@ amdgpu_winsys_create(int fd, radeon_screen_create_t screen_create) drmFreeVersion(version); /* Look up the winsys from the dev table. */ - mtx_lock(&dev_tab_mutex); + simple_mtx_lock(&dev_tab_mutex); if (!dev_tab) - dev_tab = util_hash_table_create(hash_dev, compare_dev); + dev_tab = util_hash_table_create(hash_pointer, compare_pointers); /* Initialize the amdgpu device. This should always return the same pointer * for the same fd. */ r = amdgpu_device_initialize(fd, &drm_major, &drm_minor, &dev); if (r) { - mtx_unlock(&dev_tab_mutex); + simple_mtx_unlock(&dev_tab_mutex); fprintf(stderr, "amdgpu: amdgpu_device_initialize failed.\n"); return NULL; } @@ -483,7 +318,13 @@ amdgpu_winsys_create(int fd, radeon_screen_create_t screen_create) ws = util_hash_table_get(dev_tab, dev); if (ws) { pipe_reference(NULL, &ws->reference); - mtx_unlock(&dev_tab_mutex); + simple_mtx_unlock(&dev_tab_mutex); + + /* Release the device handle, because we don't need it anymore. + * This function is returning an existing winsys instance, which + * has its own device handle. + */ + amdgpu_device_deinitialize(dev); return &ws->base; } @@ -496,24 +337,42 @@ amdgpu_winsys_create(int fd, radeon_screen_create_t screen_create) ws->info.drm_major = drm_major; ws->info.drm_minor = drm_minor; - if (!do_winsys_init(ws, fd)) + if (!do_winsys_init(ws, config, fd)) goto fail_alloc; /* Create managers. */ - pb_cache_init(&ws->bo_cache, 500000, ws->check_vm ? 1.0f : 2.0f, 0, + pb_cache_init(&ws->bo_cache, RADEON_MAX_CACHED_HEAPS, + 500000, ws->check_vm ? 1.0f : 2.0f, 0, (ws->info.vram_size + ws->info.gart_size) / 8, amdgpu_bo_destroy, amdgpu_bo_can_reclaim); - if (!pb_slabs_init(&ws->bo_slabs, - AMDGPU_SLAB_MIN_SIZE_LOG2, AMDGPU_SLAB_MAX_SIZE_LOG2, - 12, /* number of heaps (domain/flags combinations) */ - ws, - amdgpu_bo_can_reclaim_slab, - amdgpu_bo_slab_alloc, - amdgpu_bo_slab_free)) - goto fail_cache; + unsigned min_slab_order = 9; /* 512 bytes */ + unsigned max_slab_order = 18; /* 256 KB - higher numbers increase memory usage */ + unsigned num_slab_orders_per_allocator = (max_slab_order - min_slab_order) / + NUM_SLAB_ALLOCATORS; + + /* Divide the size order range among slab managers. */ + for (unsigned i = 0; i < NUM_SLAB_ALLOCATORS; i++) { + unsigned min_order = min_slab_order; + unsigned max_order = MIN2(min_order + num_slab_orders_per_allocator, + max_slab_order); + + if (!pb_slabs_init(&ws->bo_slabs[i], + min_order, max_order, + RADEON_MAX_SLAB_HEAPS, + ws, + amdgpu_bo_can_reclaim_slab, + amdgpu_bo_slab_alloc, + amdgpu_bo_slab_free)) { + amdgpu_winsys_destroy(&ws->base); + simple_mtx_unlock(&dev_tab_mutex); + return NULL; + } + + min_slab_order = max_order + 1; + } - ws->info.min_alloc_size = 1 << AMDGPU_SLAB_MIN_SIZE_LOG2; + ws->info.min_alloc_size = 1 << ws->bo_slabs[0].min_order; /* init reference */ pipe_reference_init(&ws->reference, 1); @@ -525,18 +384,24 @@ amdgpu_winsys_create(int fd, radeon_screen_create_t screen_create) ws->base.cs_request_feature = amdgpu_cs_request_feature; ws->base.query_value = amdgpu_query_value; ws->base.read_registers = amdgpu_read_registers; + ws->base.get_chip_name = amdgpu_get_chip_name; + ws->base.pin_threads_to_L3_cache = amdgpu_pin_threads_to_L3_cache; amdgpu_bo_init_functions(ws); amdgpu_cs_init_functions(ws); amdgpu_surface_init_functions(ws); LIST_INITHEAD(&ws->global_bo_list); - (void) mtx_init(&ws->global_bo_list_lock, mtx_plain); - (void) mtx_init(&ws->bo_fence_lock, mtx_plain); + ws->bo_export_table = util_hash_table_create(hash_pointer, compare_pointers); + + (void) simple_mtx_init(&ws->global_bo_list_lock, mtx_plain); + (void) simple_mtx_init(&ws->bo_fence_lock, mtx_plain); + (void) simple_mtx_init(&ws->bo_export_table_lock, mtx_plain); - if (!util_queue_init(&ws->cs_queue, "amdgpu_cs", 8, 1)) { + if (!util_queue_init(&ws->cs_queue, "cs", 8, 1, + UTIL_QUEUE_INIT_RESIZE_IF_FULL)) { amdgpu_winsys_destroy(&ws->base); - mtx_unlock(&dev_tab_mutex); + simple_mtx_unlock(&dev_tab_mutex); return NULL; } @@ -545,19 +410,27 @@ amdgpu_winsys_create(int fd, radeon_screen_create_t screen_create) * * Alternatively, we could create the screen based on "ws->gen" * and link all drivers into one binary blob. */ - ws->base.screen = screen_create(&ws->base); + ws->base.screen = screen_create(&ws->base, config); if (!ws->base.screen) { amdgpu_winsys_destroy(&ws->base); - mtx_unlock(&dev_tab_mutex); + simple_mtx_unlock(&dev_tab_mutex); return NULL; } util_hash_table_set(dev_tab, dev, ws); + if (ws->reserve_vmid) { + r = amdgpu_vm_reserve_vmid(dev, 0); + if (r) { + fprintf(stderr, "amdgpu: amdgpu_vm_reserve_vmid failed. (%i)\n", r); + goto fail_cache; + } + } + /* We must unlock the mutex once the winsys is fully initialized, so that * other threads attempting to create the winsys from the same fd will * get a fully initialized winsys and not just half-way initialized. */ - mtx_unlock(&dev_tab_mutex); + simple_mtx_unlock(&dev_tab_mutex); return &ws->base; @@ -567,6 +440,6 @@ fail_cache: fail_alloc: FREE(ws); fail: - mtx_unlock(&dev_tab_mutex); + simple_mtx_unlock(&dev_tab_mutex); return NULL; }