Merge branch 'llvm-cliptest-viewport'
[mesa.git] / src / gallium / winsys / r600 / drm / r600_drm.c
index c76e7f5fa5169cb5fce03c5660628cc87137c10b..c9de95ffc027fea1bfb1f945db79f5defa05b7d2 100644 (file)
  *      Corbin Simpson <MostAwesomeDude@gmail.com>
  *      Joakim Sindholt <opensource@zhasha.com>
  */
+#include <stdio.h>
+#include <errno.h>
 #include <sys/ioctl.h>
 #include "util/u_inlines.h"
 #include "util/u_debug.h"
-#include "radeon_priv.h"
-#include "r600_screen.h"
-#include "r600_resource.h"
+#include <pipebuffer/pb_bufmgr.h>
+#include "r600.h"
+#include "r600_priv.h"
 #include "r600_drm_public.h"
-#include "state_tracker/drm_driver.h"
+#include "xf86drm.h"
+#include "radeon_drm.h"
 
-struct radeon *r600_drm_winsys_create(int drmfd)
+#ifndef RADEON_INFO_TILING_CONFIG
+#define RADEON_INFO_TILING_CONFIG 0x6
+#endif
+static int radeon_get_device(struct radeon *radeon)
 {
-       return radeon_new(drmfd, 0);
+       struct drm_radeon_info info;
+       int r;
+
+       radeon->device = 0;
+       info.request = RADEON_INFO_DEVICE_ID;
+       info.value = (uintptr_t)&radeon->device;
+       r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info,
+                       sizeof(struct drm_radeon_info));
+       return r;
 }
 
-boolean r600_buffer_get_handle(struct radeon *rw,
-                              struct pipe_resource *buf,
-                              struct winsys_handle *whandle)
+static int radeon_drm_get_tiling(struct radeon *radeon)
 {
-       struct drm_gem_flink flink;
-       struct r600_resource* rbuffer = (struct r600_resource*)buf;
+       struct drm_radeon_info info;
+       int r;
+       uint32_t tiling_config;
+
+       info.request = RADEON_INFO_TILING_CONFIG;
+       info.value = (uintptr_t)&tiling_config;
+       r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info,
+                               sizeof(struct drm_radeon_info));
+
+       if (r)
+               return r;
+
+       switch ((tiling_config & 0xe) >> 1) {
+       case 0:
+               radeon->tiling_info.num_channels = 1;
+               break;
+       case 1:
+               radeon->tiling_info.num_channels = 2;
+               break;
+       case 2:
+               radeon->tiling_info.num_channels = 4;
+               break;
+       case 3:
+               radeon->tiling_info.num_channels = 8;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch ((tiling_config & 0x30) >> 4) {
+       case 0:
+               radeon->tiling_info.num_banks = 4;
+               break;
+       case 1:
+               radeon->tiling_info.num_banks = 8;
+               break;
+       default:
+               return -EINVAL;
 
-       if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
-               if (!rbuffer->flink) {
-                       flink.handle = rbuffer->bo->handle;
+       }
+       switch ((tiling_config & 0xc0) >> 6) {
+       case 0:
+               radeon->tiling_info.group_bytes = 256;
+               break;
+       case 1:
+               radeon->tiling_info.group_bytes = 512;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
 
-                       if (ioctl(rw->fd, DRM_IOCTL_GEM_FLINK, &flink)) {
-                               return FALSE;
-                       }
+struct radeon *radeon_new(int fd, unsigned device)
+{
+       struct radeon *radeon;
+       int r;
 
-                       rbuffer->flink = flink.name;
+       radeon = calloc(1, sizeof(*radeon));
+       if (radeon == NULL) {
+               return NULL;
+       }
+       radeon->fd = fd;
+       radeon->device = device;
+       radeon->refcount = 1;
+       if (fd >= 0) {
+               r = radeon_get_device(radeon);
+               if (r) {
+                       fprintf(stderr, "Failed to get device id\n");
+                       return radeon_decref(radeon);
                }
-               whandle->handle = rbuffer->flink;
-       } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
-               whandle->handle = rbuffer->bo->handle;
        }
-       return TRUE;
+       radeon->family = radeon_family_from_device(radeon->device);
+       if (radeon->family == CHIP_UNKNOWN) {
+               fprintf(stderr, "Unknown chipset 0x%04X\n", radeon->device);
+               return radeon_decref(radeon);
+       }
+       switch (radeon->family) {
+       case CHIP_R600:
+       case CHIP_RV610:
+       case CHIP_RV630:
+       case CHIP_RV670:
+       case CHIP_RV620:
+       case CHIP_RV635:
+       case CHIP_RS780:
+       case CHIP_RS880:
+       case CHIP_RV770:
+       case CHIP_RV730:
+       case CHIP_RV710:
+       case CHIP_RV740:
+       case CHIP_CEDAR:
+       case CHIP_REDWOOD:
+       case CHIP_JUNIPER:
+       case CHIP_CYPRESS:
+       case CHIP_HEMLOCK:
+               break;
+       case CHIP_R100:
+       case CHIP_RV100:
+       case CHIP_RS100:
+       case CHIP_RV200:
+       case CHIP_RS200:
+       case CHIP_R200:
+       case CHIP_RV250:
+       case CHIP_RS300:
+       case CHIP_RV280:
+       case CHIP_R300:
+       case CHIP_R350:
+       case CHIP_RV350:
+       case CHIP_RV380:
+       case CHIP_R420:
+       case CHIP_R423:
+       case CHIP_RV410:
+       case CHIP_RS400:
+       case CHIP_RS480:
+       case CHIP_RS600:
+       case CHIP_RS690:
+       case CHIP_RS740:
+       case CHIP_RV515:
+       case CHIP_R520:
+       case CHIP_RV530:
+       case CHIP_RV560:
+       case CHIP_RV570:
+       case CHIP_R580:
+       default:
+               fprintf(stderr, "%s unknown or unsupported chipset 0x%04X\n",
+                       __func__, radeon->device);
+               break;
+       }
+
+       /* setup class */
+       switch (radeon->family) {
+       case CHIP_R600:
+       case CHIP_RV610:
+       case CHIP_RV630:
+       case CHIP_RV670:
+       case CHIP_RV620:
+       case CHIP_RV635:
+       case CHIP_RS780:
+       case CHIP_RS880:
+               radeon->chip_class = R600;
+               break;
+       case CHIP_RV770:
+       case CHIP_RV730:
+       case CHIP_RV710:
+       case CHIP_RV740:
+               radeon->chip_class = R700;
+               break;
+       case CHIP_CEDAR:
+       case CHIP_REDWOOD:
+       case CHIP_JUNIPER:
+       case CHIP_CYPRESS:
+       case CHIP_HEMLOCK:
+               radeon->chip_class = EVERGREEN;
+               break;
+       default:
+               fprintf(stderr, "%s unknown or unsupported chipset 0x%04X\n",
+                       __func__, radeon->device);
+               break;
+       }
+
+       if (radeon->chip_class == R600 || radeon->chip_class == R700) {
+               if (radeon_drm_get_tiling(radeon))
+                       return NULL;
+       }
+       radeon->kman = radeon_bo_pbmgr_create(radeon);
+       if (!radeon->kman)
+               return NULL;
+       radeon->cman = pb_cache_manager_create(radeon->kman, 100000);
+       if (!radeon->cman)
+               return NULL;
+       return radeon;
+}
+
+struct radeon *r600_drm_winsys_create(int drmfd)
+{
+       return radeon_new(drmfd, 0);
+}
+
+struct radeon *radeon_decref(struct radeon *radeon)
+{
+       if (radeon == NULL)
+               return NULL;
+       if (--radeon->refcount > 0) {
+               return NULL;
+       }
+
+        if (radeon->cman)
+           radeon->cman->destroy(radeon->cman);
+
+        if (radeon->kman)
+           radeon->kman->destroy(radeon->kman);
+
+        if (radeon->fd >= 0)
+           drmClose(radeon->fd);
+
+       free(radeon);
+       return NULL;
 }