static uint64_t radeon_query_value(struct radeon_winsys *rws, enum radeon_value_id value) { struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws; uint64_t ts = 0; switch (value) { case RADEON_REQUESTED_VRAM_MEMORY: return ws->allocated_vram; case RADEON_REQUESTED_GTT_MEMORY: return ws->allocated_gtt; case RADEON_BUFFER_WAIT_TIME_NS: return ws->buffer_wait_time; case RADEON_TIMESTAMP: if (ws->info.drm_minor < 20 || ws->gen < DRV_R600) { assert(0); return 0; } radeon_get_drm_value(ws->fd, RADEON_INFO_TIMESTAMP, "timestamp", (uint32_t*)&ts); return ts; } return 0; }
static uint64_t radeon_query_value(struct radeon_winsys *rws, enum radeon_value_id value) { struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws; uint64_t retval = 0; switch (value) { case RADEON_REQUESTED_VRAM_MEMORY: return ws->allocated_vram; case RADEON_REQUESTED_GTT_MEMORY: return ws->allocated_gtt; case RADEON_BUFFER_WAIT_TIME_NS: return ws->buffer_wait_time; case RADEON_TIMESTAMP: if (ws->info.drm_minor < 20 || ws->gen < DRV_R600) { assert(0); return 0; } radeon_get_drm_value(ws->fd, RADEON_INFO_TIMESTAMP, "timestamp", (uint32_t*)&retval); return retval; case RADEON_NUM_CS_FLUSHES: return ws->num_cs_flushes; case RADEON_NUM_BYTES_MOVED: radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_BYTES_MOVED, "num-bytes-moved", (uint32_t*)&retval); return retval; case RADEON_VRAM_USAGE: radeon_get_drm_value(ws->fd, RADEON_INFO_VRAM_USAGE, "vram-usage", (uint32_t*)&retval); return retval; case RADEON_GTT_USAGE: radeon_get_drm_value(ws->fd, RADEON_INFO_GTT_USAGE, "gtt-usage", (uint32_t*)&retval); return retval; case RADEON_GPU_TEMPERATURE: radeon_get_drm_value(ws->fd, RADEON_INFO_CURRENT_GPU_TEMP, "gpu-temp", (uint32_t*)&retval); return retval; case RADEON_CURRENT_SCLK: radeon_get_drm_value(ws->fd, RADEON_INFO_CURRENT_GPU_SCLK, "current-gpu-sclk", (uint32_t*)&retval); return retval; case RADEON_CURRENT_MCLK: radeon_get_drm_value(ws->fd, RADEON_INFO_CURRENT_GPU_MCLK, "current-gpu-mclk", (uint32_t*)&retval); return retval; case RADEON_GPU_RESET_COUNTER: radeon_get_drm_value(ws->fd, RADEON_INFO_GPU_RESET_COUNTER, "gpu-reset-counter", (uint32_t*)&retval); return retval; } return 0; }
static void radeon_read_registers(struct radeon_winsys *rws, unsigned reg_offset, unsigned num_registers, uint32_t *out) { struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws; unsigned i; for (i = 0; i < num_registers; i++) { uint32_t reg = reg_offset + i*4; radeon_get_drm_value(ws->fd, RADEON_INFO_READ_REG, "read-reg", ®); out[i] = reg; } }
static uint64_t radeon_query_timestamp(struct radeon_winsys *rws) { struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws; uint64_t ts = 0; if (ws->info.drm_minor < 20 || ws->gen < R600) { assert(0); return 0; } radeon_get_drm_value(ws->fd, RADEON_INFO_TIMESTAMP, "timestamp", (uint32_t*)&ts); return ts; }
/* Helper function to do the ioctls needed for setup and init. */ static boolean do_winsys_init(struct radeon_drm_winsys *ws) { struct drm_radeon_gem_info gem_info; int retval; drmVersionPtr version; memset(&gem_info, 0, sizeof(gem_info)); /* We do things in a specific order here. * * DRM version first. We need to be sure we're running on a KMS chipset. * This is also for some features. * * Then, the PCI ID. This is essential and should return usable numbers * for all Radeons. If this fails, we probably got handed an FD for some * non-Radeon card. * * The GEM info is actually bogus on the kernel side, as well as our side * (see radeon_gem_info_ioctl in radeon_gem.c) but that's alright because * we don't actually use the info for anything yet. * * The GB and Z pipe requests should always succeed, but they might not * return sensical values for all chipsets, but that's alright because * the pipe drivers already know that. */ /* Get DRM version. */ version = drmGetVersion(ws->fd); if (version->version_major != 2 || version->version_minor < 3) { fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is " "only compatible with 2.3.x (kernel 2.6.34) or later.\n", __FUNCTION__, version->version_major, version->version_minor, version->version_patchlevel); drmFreeVersion(version); return FALSE; } ws->info.drm_major = version->version_major; ws->info.drm_minor = version->version_minor; ws->info.drm_patchlevel = version->version_patchlevel; drmFreeVersion(version); /* Get PCI ID. */ if (!radeon_get_drm_value(ws->fd, RADEON_INFO_DEVICE_ID, "PCI ID", &ws->info.pci_id)) return FALSE; /* Check PCI ID. */ switch (ws->info.pci_id) { #define CHIPSET(pci_id, name, cfamily) case pci_id: ws->info.family = CHIP_##cfamily; ws->gen = DRV_R300; break; #include "pci_ids/r300_pci_ids.h" #undef CHIPSET #define CHIPSET(pci_id, name, cfamily) case pci_id: ws->info.family = CHIP_##cfamily; ws->gen = DRV_R600; break; #include "pci_ids/r600_pci_ids.h" #undef CHIPSET #define CHIPSET(pci_id, name, cfamily) case pci_id: ws->info.family = CHIP_##cfamily; ws->gen = DRV_SI; break; #include "pci_ids/radeonsi_pci_ids.h" #undef CHIPSET default: fprintf(stderr, "radeon: Invalid PCI ID.\n"); return FALSE; } switch (ws->info.family) { default: case CHIP_UNKNOWN: fprintf(stderr, "radeon: Unknown family.\n"); return FALSE; case CHIP_R300: case CHIP_R350: case CHIP_RV350: case CHIP_RV370: case CHIP_RV380: case CHIP_RS400: case CHIP_RC410: case CHIP_RS480: ws->info.chip_class = R300; break; case CHIP_R420: /* R4xx-based cores. */ case CHIP_R423: case CHIP_R430: case CHIP_R480: case CHIP_R481: case CHIP_RV410: case CHIP_RS600: case CHIP_RS690: case CHIP_RS740: ws->info.chip_class = R400; break; case CHIP_RV515: /* R5xx-based cores. */ case CHIP_R520: case CHIP_RV530: case CHIP_R580: case CHIP_RV560: case CHIP_RV570: ws->info.chip_class = R500; break; case CHIP_R600: case CHIP_RV610: case CHIP_RV630: case CHIP_RV670: case CHIP_RV620: case CHIP_RV635: case CHIP_RS780: case CHIP_RS880: ws->info.chip_class = R600; break; case CHIP_RV770: case CHIP_RV730: case CHIP_RV710: case CHIP_RV740: ws->info.chip_class = R700; break; case CHIP_CEDAR: case CHIP_REDWOOD: case CHIP_JUNIPER: case CHIP_CYPRESS: case CHIP_HEMLOCK: case CHIP_PALM: case CHIP_SUMO: case CHIP_SUMO2: case CHIP_BARTS: case CHIP_TURKS: case CHIP_CAICOS: ws->info.chip_class = EVERGREEN; break; case CHIP_CAYMAN: case CHIP_ARUBA: ws->info.chip_class = CAYMAN; break; case CHIP_TAHITI: case CHIP_PITCAIRN: case CHIP_VERDE: case CHIP_OLAND: case CHIP_HAINAN: ws->info.chip_class = SI; break; case CHIP_BONAIRE: case CHIP_KAVERI: case CHIP_KABINI: case CHIP_HAWAII: case CHIP_MULLINS: ws->info.chip_class = CIK; break; } /* Check for dma */ ws->info.r600_has_dma = FALSE; /* DMA is disabled on R700. There is IB corruption and hangs. */ if (ws->info.chip_class >= EVERGREEN && ws->info.drm_minor >= 27) { ws->info.r600_has_dma = TRUE; } /* Check for UVD and VCE */ ws->info.has_uvd = FALSE; ws->info.vce_fw_version = 0x00000000; if (ws->info.drm_minor >= 32) { uint32_t value = RADEON_CS_RING_UVD; if (radeon_get_drm_value(ws->fd, RADEON_INFO_RING_WORKING, "UVD Ring working", &value)) ws->info.has_uvd = value; value = RADEON_CS_RING_VCE; if (radeon_get_drm_value(ws->fd, RADEON_INFO_RING_WORKING, NULL, &value) && value) { if (radeon_get_drm_value(ws->fd, RADEON_INFO_VCE_FW_VERSION, "VCE FW version", &value)) ws->info.vce_fw_version = value; } } /* Check for userptr support. */ { struct drm_radeon_gem_userptr args = {0}; /* If the ioctl doesn't exist, -EINVAL is returned. * * If the ioctl exists, it should return -EACCES * if RADEON_GEM_USERPTR_READONLY or RADEON_GEM_USERPTR_REGISTER * aren't set. */ ws->info.has_userptr = drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_USERPTR, &args, sizeof(args)) == -EACCES; } /* Get GEM info. */ retval = drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_INFO, &gem_info, sizeof(gem_info)); if (retval) { fprintf(stderr, "radeon: Failed to get MM info, error number %d\n", retval); return FALSE; } ws->info.gart_size = gem_info.gart_size; ws->info.vram_size = gem_info.vram_size; /* Get max clock frequency info and convert it to MHz */ radeon_get_drm_value(ws->fd, RADEON_INFO_MAX_SCLK, NULL, &ws->info.max_sclk); ws->info.max_sclk /= 1000; radeon_get_drm_value(ws->fd, RADEON_INFO_SI_BACKEND_ENABLED_MASK, NULL, &ws->info.si_backend_enabled_mask); ws->num_cpus = sysconf(_SC_NPROCESSORS_ONLN); /* Generation-specific queries. */ if (ws->gen == DRV_R300) { if (!radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_GB_PIPES, "GB pipe count", &ws->info.r300_num_gb_pipes)) return FALSE; if (!radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_Z_PIPES, "Z pipe count", &ws->info.r300_num_z_pipes)) return FALSE; } else if (ws->gen >= DRV_R600) { if (ws->info.drm_minor >= 9 && !radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_BACKENDS, "num backends", &ws->info.r600_num_backends)) return FALSE; /* get the GPU counter frequency, failure is not fatal */ radeon_get_drm_value(ws->fd, RADEON_INFO_CLOCK_CRYSTAL_FREQ, NULL, &ws->info.r600_clock_crystal_freq); radeon_get_drm_value(ws->fd, RADEON_INFO_TILING_CONFIG, NULL, &ws->info.r600_tiling_config); if (ws->info.drm_minor >= 11) { radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_TILE_PIPES, NULL, &ws->info.r600_num_tile_pipes); if (radeon_get_drm_value(ws->fd, RADEON_INFO_BACKEND_MAP, NULL, &ws->info.r600_backend_map)) ws->info.r600_backend_map_valid = TRUE; } ws->info.r600_virtual_address = FALSE; if (ws->info.drm_minor >= 13) { uint32_t ib_vm_max_size; ws->info.r600_virtual_address = TRUE; if (!radeon_get_drm_value(ws->fd, RADEON_INFO_VA_START, NULL, &ws->va_start)) ws->info.r600_virtual_address = FALSE; if (!radeon_get_drm_value(ws->fd, RADEON_INFO_IB_VM_MAX_SIZE, NULL, &ib_vm_max_size)) ws->info.r600_virtual_address = FALSE; radeon_get_drm_value(ws->fd, RADEON_INFO_VA_UNMAP_WORKING, NULL, &ws->va_unmap_working); } if (ws->gen == DRV_R600 && !debug_get_bool_option("RADEON_VA", FALSE)) ws->info.r600_virtual_address = FALSE; } /* Get max pipes, this is only needed for compute shaders. All evergreen+ * chips have at least 2 pipes, so we use 2 as a default. */ ws->info.r600_max_pipes = 2; radeon_get_drm_value(ws->fd, RADEON_INFO_MAX_PIPES, NULL, &ws->info.r600_max_pipes); /* All GPUs have at least one compute unit */ ws->info.max_compute_units = 1; radeon_get_drm_value(ws->fd, RADEON_INFO_ACTIVE_CU_COUNT, NULL, &ws->info.max_compute_units); radeon_get_drm_value(ws->fd, RADEON_INFO_MAX_SE, NULL, &ws->info.max_se); if (!ws->info.max_se) { switch (ws->info.family) { default: ws->info.max_se = 1; break; case CHIP_CYPRESS: case CHIP_HEMLOCK: case CHIP_BARTS: case CHIP_CAYMAN: case CHIP_TAHITI: case CHIP_PITCAIRN: case CHIP_BONAIRE: ws->info.max_se = 2; break; case CHIP_HAWAII: ws->info.max_se = 4; break; } } radeon_get_drm_value(ws->fd, RADEON_INFO_MAX_SH_PER_SE, NULL, &ws->info.max_sh_per_se); radeon_get_drm_value(ws->fd, RADEON_INFO_ACCEL_WORKING2, NULL, &ws->accel_working2); if (ws->info.family == CHIP_HAWAII && ws->accel_working2 < 2) { fprintf(stderr, "radeon: GPU acceleration for Hawaii disabled, " "returned accel_working2 value %u is smaller than 2. " "Please install a newer kernel.\n", ws->accel_working2); return FALSE; } if (radeon_get_drm_value(ws->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, NULL, ws->info.si_tile_mode_array)) { ws->info.si_tile_mode_array_valid = TRUE; } if (radeon_get_drm_value(ws->fd, RADEON_INFO_CIK_MACROTILE_MODE_ARRAY, NULL, ws->info.cik_macrotile_mode_array)) { ws->info.cik_macrotile_mode_array_valid = TRUE; } return TRUE; }
/* Helper function to do the ioctls needed for setup and init. */ static boolean do_winsys_init(struct radeon_drm_winsys *ws) { struct drm_radeon_gem_info gem_info; int retval; drmVersionPtr version; memset(&gem_info, 0, sizeof(gem_info)); /* We do things in a specific order here. * * DRM version first. We need to be sure we're running on a KMS chipset. * This is also for some features. * * Then, the PCI ID. This is essential and should return usable numbers * for all Radeons. If this fails, we probably got handed an FD for some * non-Radeon card. * * The GEM info is actually bogus on the kernel side, as well as our side * (see radeon_gem_info_ioctl in radeon_gem.c) but that's alright because * we don't actually use the info for anything yet. * * The GB and Z pipe requests should always succeed, but they might not * return sensical values for all chipsets, but that's alright because * the pipe drivers already know that. */ /* Get DRM version. */ version = drmGetVersion(ws->fd); if (version->version_major != 2 || version->version_minor < 3) { fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is " "only compatible with 2.3.x (kernel 2.6.34) or later.\n", __FUNCTION__, version->version_major, version->version_minor, version->version_patchlevel); drmFreeVersion(version); return FALSE; } ws->info.drm_major = version->version_major; ws->info.drm_minor = version->version_minor; ws->info.drm_patchlevel = version->version_patchlevel; drmFreeVersion(version); /* Get PCI ID. */ if (!radeon_get_drm_value(ws->fd, RADEON_INFO_DEVICE_ID, "PCI ID", &ws->info.pci_id)) return FALSE; /* Check PCI ID. */ switch (ws->info.pci_id) { #define CHIPSET(pci_id, name, family) case pci_id: #include "pci_ids/r300_pci_ids.h" #undef CHIPSET ws->gen = R300; break; #define CHIPSET(pci_id, name, family) case pci_id: #include "pci_ids/r600_pci_ids.h" #undef CHIPSET ws->gen = R600; break; #define CHIPSET(pci_id, name, family) case pci_id: #include "pci_ids/radeonsi_pci_ids.h" #undef CHIPSET ws->gen = SI; break; default: fprintf(stderr, "radeon: Invalid PCI ID.\n"); return FALSE; } /* Get GEM info. */ retval = drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_INFO, &gem_info, sizeof(gem_info)); if (retval) { fprintf(stderr, "radeon: Failed to get MM info, error number %d\n", retval); return FALSE; } ws->info.gart_size = gem_info.gart_size; ws->info.vram_size = gem_info.vram_size; ws->num_cpus = sysconf(_SC_NPROCESSORS_ONLN); /* Generation-specific queries. */ if (ws->gen == R300) { if (!radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_GB_PIPES, "GB pipe count", &ws->info.r300_num_gb_pipes)) return FALSE; if (!radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_Z_PIPES, "Z pipe count", &ws->info.r300_num_z_pipes)) return FALSE; } else if (ws->gen >= R600) { if (ws->info.drm_minor >= 9 && !radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_BACKENDS, "num backends", &ws->info.r600_num_backends)) return FALSE; /* get the GPU counter frequency, failure is not fatal */ radeon_get_drm_value(ws->fd, RADEON_INFO_CLOCK_CRYSTAL_FREQ, NULL, &ws->info.r600_clock_crystal_freq); radeon_get_drm_value(ws->fd, RADEON_INFO_TILING_CONFIG, NULL, &ws->info.r600_tiling_config); if (ws->info.drm_minor >= 11) { radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_TILE_PIPES, NULL, &ws->info.r600_num_tile_pipes); if (radeon_get_drm_value(ws->fd, RADEON_INFO_BACKEND_MAP, NULL, &ws->info.r600_backend_map)) ws->info.r600_backend_map_valid = TRUE; } ws->info.r600_virtual_address = FALSE; if (ws->info.drm_minor >= 13) { ws->info.r600_virtual_address = TRUE; if (!radeon_get_drm_value(ws->fd, RADEON_INFO_VA_START, NULL, &ws->info.r600_va_start)) ws->info.r600_virtual_address = FALSE; if (!radeon_get_drm_value(ws->fd, RADEON_INFO_IB_VM_MAX_SIZE, NULL, &ws->info.r600_ib_vm_max_size)) ws->info.r600_virtual_address = FALSE; } /* Remove this line once the virtual address space feature is fixed. */ if (ws->gen == R600 && !debug_get_bool_option("RADEON_VA", FALSE)) ws->info.r600_virtual_address = FALSE; } /* Get max pipes, this is only needed for compute shaders. All evergreen+ * chips have at least 2 pipes, so we use 2 as a default. */ ws->info.r600_max_pipes = 2; radeon_get_drm_value(ws->fd, RADEON_INFO_MAX_PIPES, NULL, &ws->info.r600_max_pipes); return TRUE; }
/* Helper function to do the ioctls needed for setup and init. */ static boolean do_winsys_init(struct radeon_drm_winsys *ws) { struct drm_radeon_gem_info gem_info; int retval; drmVersionPtr version; memset(&gem_info, 0, sizeof(gem_info)); /* We do things in a specific order here. * * DRM version first. We need to be sure we're running on a KMS chipset. * This is also for some features. * * Then, the PCI ID. This is essential and should return usable numbers * for all Radeons. If this fails, we probably got handed an FD for some * non-Radeon card. * * The GEM info is actually bogus on the kernel side, as well as our side * (see radeon_gem_info_ioctl in radeon_gem.c) but that's alright because * we don't actually use the info for anything yet. * * The GB and Z pipe requests should always succeed, but they might not * return sensical values for all chipsets, but that's alright because * the pipe drivers already know that. */ /* Get DRM version. */ version = drmGetVersion(ws->fd); if (version->version_major != 2 || version->version_minor < 3) { fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is " "only compatible with 2.3.x (kernel 2.6.34) or later.\n", __FUNCTION__, version->version_major, version->version_minor, version->version_patchlevel); drmFreeVersion(version); return FALSE; } ws->info.drm_major = version->version_major; ws->info.drm_minor = version->version_minor; ws->info.drm_patchlevel = version->version_patchlevel; drmFreeVersion(version); /* Get PCI ID. */ if (!radeon_get_drm_value(ws->fd, RADEON_INFO_DEVICE_ID, "PCI ID", &ws->info.pci_id)) return FALSE; /* Check PCI ID. */ switch (ws->info.pci_id) { #define CHIPSET(pci_id, name, cfamily) case pci_id: ws->info.family = CHIP_##cfamily; ws->gen = DRV_R300; break; #include "pci_ids/r300_pci_ids.h" #undef CHIPSET #define CHIPSET(pci_id, name, cfamily) case pci_id: ws->info.family = CHIP_##cfamily; ws->gen = DRV_R600; break; #include "pci_ids/r600_pci_ids.h" #undef CHIPSET #define CHIPSET(pci_id, name, cfamily) case pci_id: ws->info.family = CHIP_##cfamily; ws->gen = DRV_SI; break; #include "pci_ids/radeonsi_pci_ids.h" #undef CHIPSET default: fprintf(stderr, "radeon: Invalid PCI ID.\n"); return FALSE; } switch (ws->info.family) { default: case CHIP_UNKNOWN: fprintf(stderr, "radeon: Unknown family.\n"); return FALSE; case CHIP_R300: case CHIP_R350: case CHIP_RV350: case CHIP_RV370: case CHIP_RV380: case CHIP_RS400: case CHIP_RC410: case CHIP_RS480: ws->info.chip_class = R300; break; case CHIP_R420: /* R4xx-based cores. */ case CHIP_R423: case CHIP_R430: case CHIP_R480: case CHIP_R481: case CHIP_RV410: case CHIP_RS600: case CHIP_RS690: case CHIP_RS740: ws->info.chip_class = R400; break; case CHIP_RV515: /* R5xx-based cores. */ case CHIP_R520: case CHIP_RV530: case CHIP_R580: case CHIP_RV560: case CHIP_RV570: ws->info.chip_class = R500; break; case CHIP_R600: case CHIP_RV610: case CHIP_RV630: case CHIP_RV670: case CHIP_RV620: case CHIP_RV635: case CHIP_RS780: case CHIP_RS880: ws->info.chip_class = R600; break; case CHIP_RV770: case CHIP_RV730: case CHIP_RV710: case CHIP_RV740: ws->info.chip_class = R700; break; case CHIP_CEDAR: case CHIP_REDWOOD: case CHIP_JUNIPER: case CHIP_CYPRESS: case CHIP_HEMLOCK: case CHIP_PALM: case CHIP_SUMO: case CHIP_SUMO2: case CHIP_BARTS: case CHIP_TURKS: case CHIP_CAICOS: ws->info.chip_class = EVERGREEN; break; case CHIP_CAYMAN: case CHIP_ARUBA: ws->info.chip_class = CAYMAN; break; case CHIP_TAHITI: case CHIP_PITCAIRN: case CHIP_VERDE: case CHIP_OLAND: case CHIP_HAINAN: ws->info.chip_class = SI; break; case CHIP_BONAIRE: case CHIP_KAVERI: case CHIP_KABINI: ws->info.chip_class = CIK; break; } /* Check for dma */ ws->info.r600_has_dma = FALSE; if (ws->info.chip_class >= R700 && ws->info.drm_minor >= 27) { ws->info.r600_has_dma = TRUE; } /* Check for UVD */ ws->info.has_uvd = FALSE; if (ws->info.drm_minor >= 32) { uint32_t value = RADEON_CS_RING_UVD; if (radeon_get_drm_value(ws->fd, RADEON_INFO_RING_WORKING, "UVD Ring working", &value)) ws->info.has_uvd = value; } /* Get GEM info. */ retval = drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_INFO, &gem_info, sizeof(gem_info)); if (retval) { fprintf(stderr, "radeon: Failed to get MM info, error number %d\n", retval); return FALSE; } ws->info.gart_size = gem_info.gart_size; ws->info.vram_size = gem_info.vram_size; ws->num_cpus = sysconf(_SC_NPROCESSORS_ONLN); /* Generation-specific queries. */ if (ws->gen == DRV_R300) { if (!radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_GB_PIPES, "GB pipe count", &ws->info.r300_num_gb_pipes)) return FALSE; if (!radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_Z_PIPES, "Z pipe count", &ws->info.r300_num_z_pipes)) return FALSE; } else if (ws->gen >= DRV_R600) { if (ws->info.drm_minor >= 9 && !radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_BACKENDS, "num backends", &ws->info.r600_num_backends)) return FALSE; /* get the GPU counter frequency, failure is not fatal */ radeon_get_drm_value(ws->fd, RADEON_INFO_CLOCK_CRYSTAL_FREQ, NULL, &ws->info.r600_clock_crystal_freq); radeon_get_drm_value(ws->fd, RADEON_INFO_TILING_CONFIG, NULL, &ws->info.r600_tiling_config); if (ws->info.drm_minor >= 11) { radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_TILE_PIPES, NULL, &ws->info.r600_num_tile_pipes); if (radeon_get_drm_value(ws->fd, RADEON_INFO_BACKEND_MAP, NULL, &ws->info.r600_backend_map)) ws->info.r600_backend_map_valid = TRUE; } ws->info.r600_virtual_address = FALSE; if (ws->info.drm_minor >= 13) { ws->info.r600_virtual_address = TRUE; if (!radeon_get_drm_value(ws->fd, RADEON_INFO_VA_START, NULL, &ws->info.r600_va_start)) ws->info.r600_virtual_address = FALSE; if (!radeon_get_drm_value(ws->fd, RADEON_INFO_IB_VM_MAX_SIZE, NULL, &ws->info.r600_ib_vm_max_size)) ws->info.r600_virtual_address = FALSE; } if (ws->gen == DRV_R600 && !debug_get_bool_option("RADEON_VA", TRUE)) ws->info.r600_virtual_address = FALSE; } /* Get max pipes, this is only needed for compute shaders. All evergreen+ * chips have at least 2 pipes, so we use 2 as a default. */ ws->info.r600_max_pipes = 2; radeon_get_drm_value(ws->fd, RADEON_INFO_MAX_PIPES, NULL, &ws->info.r600_max_pipes); return TRUE; }