X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fwinsys%2Famdgpu%2Fdrm%2Famdgpu_winsys.c;h=98d72bd9f2c8fa4e545211c1a177e04a30ad8946;hb=79a8e674aef8d50e79f5d4ab25e0f951d1c69398;hp=c956cf489827b321589460543caaafabb79fb8cc;hpb=4f96846d9d96fcb84fb0fb1823b3f59c3c426253;p=mesa.git diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c index c956cf48982..98d72bd9f2c 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c @@ -39,7 +39,7 @@ #include #include #include -#include "amdgpu_id.h" +#include "amd/common/amdgpu_id.h" #define CIK_TILE_MODE_COLOR_2D 14 @@ -59,6 +59,10 @@ #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16 16 #define CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16 17 +#ifndef AMDGPU_INFO_NUM_EVICTIONS +#define AMDGPU_INFO_NUM_EVICTIONS 0x18 +#endif + static struct util_hash_table *dev_tab = NULL; pipe_static_mutex(dev_tab_mutex); @@ -92,28 +96,28 @@ static unsigned cik_get_num_tile_pipes(struct amdgpu_gpu_info *info) } } -/* Convert Sea Islands register values GB_ADDR_CFG and MC_ADDR_CFG - * into GB_TILING_CONFIG register which is only present on R600-R700. */ -static unsigned r600_get_gb_tiling_config(struct amdgpu_gpu_info *info) -{ - unsigned num_pipes = info->gb_addr_cfg & 0x7; - unsigned num_banks = info->mc_arb_ramcfg & 0x3; - unsigned pipe_interleave_bytes = (info->gb_addr_cfg >> 4) & 0x7; - unsigned row_size = (info->gb_addr_cfg >> 28) & 0x3; - - return num_pipes | (num_banks << 4) | - (pipe_interleave_bytes << 8) | - (row_size << 12); -} - /* Helper function to do the ioctls needed for setup and init. */ -static boolean do_winsys_init(struct amdgpu_winsys *ws) +static bool do_winsys_init(struct amdgpu_winsys *ws, int fd) { struct amdgpu_buffer_size_alignments alignment_info = {}; struct amdgpu_heap_info vram, gtt; struct drm_amdgpu_info_hw_ip dma = {}, uvd = {}, vce = {}; - uint32_t vce_version = 0, vce_feature = 0; + 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 = drmGetDevice(fd, &devinfo); + if (r) { + fprintf(stderr, "amdgpu: drmGetDevice 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); @@ -152,6 +156,34 @@ static boolean do_winsys_init(struct amdgpu_winsys *ws) 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"); @@ -183,15 +215,16 @@ static boolean do_winsys_init(struct amdgpu_winsys *ws) 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 3.6 is required for VI. */ + /* LLVM 3.6.1 is required for VI. */ if (ws->info.chip_class >= VI && - (HAVE_LLVM < 0x0306 || - (HAVE_LLVM == 0x0306 && MESA_LLVM_VERSION_PATCH < 1))) { + HAVE_LLVM == 0x0306 && MESA_LLVM_VERSION_PATCH < 1) { fprintf(stderr, "amdgpu: LLVM 3.6.1 is required, got LLVM %i.%i.%i\n", HAVE_LLVM >> 8, HAVE_LLVM & 255, MESA_LLVM_VERSION_PATCH); goto fail; @@ -199,6 +232,26 @@ static boolean do_winsys_init(struct amdgpu_winsys *ws) /* family and rev_id are for addrlib */ switch (ws->info.family) { + case CHIP_TAHITI: + ws->family = FAMILY_SI; + ws->rev_id = SI_TAHITI_P_A0; + break; + case CHIP_PITCAIRN: + ws->family = FAMILY_SI; + ws->rev_id = SI_PITCAIRN_PM_A0; + break; + case CHIP_VERDE: + ws->family = FAMILY_SI; + ws->rev_id = SI_CAPEVERDE_M_A0; + break; + case CHIP_OLAND: + ws->family = FAMILY_SI; + ws->rev_id = SI_OLAND_M_A0; + break; + case CHIP_HAINAN: + ws->family = FAMILY_SI; + ws->rev_id = SI_HAINAN_V_A0; + break; case CHIP_BONAIRE: ws->family = FAMILY_CI; ws->rev_id = CI_BONAIRE_M_A0; @@ -239,6 +292,14 @@ static boolean do_winsys_init(struct amdgpu_winsys *ws) ws->family = FAMILY_VI; ws->rev_id = VI_FIJI_P_A0; break; + case CHIP_POLARIS10: + ws->family = FAMILY_VI; + ws->rev_id = VI_POLARIS10_P_A0; + break; + case CHIP_POLARIS11: + ws->family = FAMILY_VI; + ws->rev_id = VI_POLARIS11_M_A0; + break; default: fprintf(stderr, "amdgpu: Unknown family.\n"); goto fail; @@ -250,23 +311,30 @@ static boolean do_winsys_init(struct amdgpu_winsys *ws) 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; + /* The kernel can split large buffers, so we can do large allocations. */ + ws->info.max_alloc_size = MAX2(ws->info.vram_size, ws->info.gart_size) * 0.9; /* 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.has_userptr = true; ws->info.num_render_backends = ws->amdinfo.rb_pipes; ws->info.clock_crystal_freq = ws->amdinfo.gpu_counter_freq; - ws->info.r600_tiling_config = r600_get_gb_tiling_config(&ws->amdinfo); ws->info.num_tile_pipes = cik_get_num_tile_pipes(&ws->amdinfo); ws->info.pipe_interleave_bytes = 256 << ((ws->amdinfo.gb_addr_cfg >> 4) & 0x7); - ws->info.has_virtual_memory = TRUE; + ws->info.has_virtual_memory = true; ws->info.has_sdma = dma.available_rings != 0; /* Get the number of good compute units. */ @@ -278,34 +346,46 @@ static boolean do_winsys_init(struct amdgpu_winsys *ws) memcpy(ws->info.si_tile_mode_array, ws->amdinfo.gb_tile_mode, sizeof(ws->amdinfo.gb_tile_mode)); - ws->info.si_tile_mode_array_valid = TRUE; 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.cik_macrotile_mode_array_valid = TRUE; - ws->gart_page_size = alignment_info.size_remote; + ws->info.gart_page_size = alignment_info.size_remote; + + if (ws->info.chip_class == SI) + ws->info.gfx_ib_pad_with_type2 = TRUE; - return TRUE; + ws->check_vm = strstr(debug_get_option("R600_DEBUG", ""), "check_vm") != NULL; + + return true; fail: if (ws->addrlib) AddrDestroy(ws->addrlib); amdgpu_device_deinitialize(ws->dev); ws->dev = NULL; - return FALSE; + return false; +} + +static void do_winsys_deinit(struct amdgpu_winsys *ws) +{ + AddrDestroy(ws->addrlib); + amdgpu_device_deinitialize(ws->dev); } static void amdgpu_winsys_destroy(struct radeon_winsys *rws) { struct amdgpu_winsys *ws = (struct amdgpu_winsys*)rws; + if (util_queue_is_initialized(&ws->cs_queue)) + util_queue_destroy(&ws->cs_queue); + pipe_mutex_destroy(ws->bo_fence_lock); + pb_slabs_deinit(&ws->bo_slabs); pb_cache_deinit(&ws->bo_cache); pipe_mutex_destroy(ws->global_bo_list_lock); - AddrDestroy(ws->addrlib); - amdgpu_device_deinitialize(ws->dev); + do_winsys_deinit(ws); FREE(rws); } @@ -315,11 +395,11 @@ static void amdgpu_winsys_query_info(struct radeon_winsys *rws, *info = ((struct amdgpu_winsys *)rws)->info; } -static boolean amdgpu_cs_request_feature(struct radeon_winsys_cs *rcs, - enum radeon_feature_id fid, - boolean enable) +static bool amdgpu_cs_request_feature(struct radeon_winsys_cs *rcs, + enum radeon_feature_id fid, + bool enable) { - return FALSE; + return false; } static uint64_t amdgpu_query_value(struct radeon_winsys *rws, @@ -334,6 +414,10 @@ static uint64_t amdgpu_query_value(struct radeon_winsys *rws, return ws->allocated_vram; case RADEON_REQUESTED_GTT_MEMORY: return ws->allocated_gtt; + case RADEON_MAPPED_VRAM: + return ws->mapped_vram; + case RADEON_MAPPED_GTT: + return ws->mapped_gtt; case RADEON_BUFFER_WAIT_TIME_NS: return ws->buffer_wait_time; case RADEON_TIMESTAMP: @@ -344,6 +428,9 @@ static uint64_t amdgpu_query_value(struct radeon_winsys *rws, 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_VRAM_USAGE: amdgpu_query_heap_info(ws->dev, AMDGPU_GEM_DOMAIN_VRAM, 0, &heap); return heap.heap_usage; @@ -385,6 +472,8 @@ static int compare_dev(void *key1, void *key2) return key1 != key2; } +DEBUG_GET_ONCE_BOOL_OPTION(thread, "RADEON_THREAD", true) + static bool amdgpu_winsys_unref(struct radeon_winsys *rws) { struct amdgpu_winsys *ws = (struct amdgpu_winsys*)rws; @@ -444,23 +533,32 @@ amdgpu_winsys_create(int fd, radeon_screen_create_t screen_create) /* Create a new winsys. */ ws = CALLOC_STRUCT(amdgpu_winsys); - if (!ws) { - pipe_mutex_unlock(dev_tab_mutex); - return NULL; - } + if (!ws) + goto fail; ws->dev = dev; ws->info.drm_major = drm_major; ws->info.drm_minor = drm_minor; - if (!do_winsys_init(ws)) - goto fail; + if (!do_winsys_init(ws, fd)) + goto fail_alloc; /* Create managers. */ - pb_cache_init(&ws->bo_cache, 500000, 2.0f, 0, + pb_cache_init(&ws->bo_cache, 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; + + ws->info.min_alloc_size = 1 << AMDGPU_SLAB_MIN_SIZE_LOG2; + /* init reference */ pipe_reference_init(&ws->reference, 1); @@ -480,6 +578,9 @@ amdgpu_winsys_create(int fd, radeon_screen_create_t screen_create) pipe_mutex_init(ws->global_bo_list_lock); pipe_mutex_init(ws->bo_fence_lock); + if (sysconf(_SC_NPROCESSORS_ONLN) > 1 && debug_get_option_thread()) + util_queue_init(&ws->cs_queue, "amdgpu_cs", 8, 1); + /* Create the screen at the end. The winsys must be initialized * completely. * @@ -501,9 +602,12 @@ amdgpu_winsys_create(int fd, radeon_screen_create_t screen_create) return &ws->base; -fail: - pipe_mutex_unlock(dev_tab_mutex); +fail_cache: pb_cache_deinit(&ws->bo_cache); + do_winsys_deinit(ws); +fail_alloc: FREE(ws); +fail: + pipe_mutex_unlock(dev_tab_mutex); return NULL; }