r300: respect radeon common code fallbacks
[mesa.git] / src / gallium / winsys / drm / radeon / core / radeon_drm.c
index f886fda2f271cf03208adeccf8388f5deee2f242..e817a26da6ddca926a097271e35bb66be9f83698 100644 (file)
  */
 
 #include "radeon_drm.h"
+#include "radeon_r300.h"
+#include "radeon_buffer.h"
 
-static struct radeon_libdrm_winsys *
-radeon_winsys_create(int fd)
-{
-    struct radeon_libdrm_winsys *rws;
+#include "r300_winsys.h"
+#include "trace/tr_drm.h"
 
-    rws = CALLOC_STRUCT(radeon_libdrm_winsys);
-    if (rws == NULL) {
-        return NULL;
-    }
+#include "util/u_memory.h"
 
-    rws->fd = fd;
-    return rws;
-}
+#include "xf86drm.h"
+#include <sys/ioctl.h>
 
 /* Helper function to do the ioctls needed for setup and init. */
-static void do_ioctls(int fd, struct radeon_libdrm_winsys* winsys)
+static void do_ioctls(int fd, struct radeon_winsys* winsys)
 {
     struct drm_radeon_gem_info gem_info = {0};
     struct drm_radeon_info info = {0};
@@ -137,24 +133,60 @@ struct pipe_screen* radeon_create_screen(struct drm_api* api,
                                          int drmFB,
                                          struct drm_create_screen_arg *arg)
 {
-    struct radeon_libdrm_winsys* rws; 
-
-    rws = radeon_winsys_create(drmFB);
-    if (!rws)
-       return NULL;
-
-    do_ioctls(drmFB, rws);
+    struct radeon_winsys* rwinsys = radeon_pipe_winsys(drmFB);
+    do_ioctls(drmFB, rwinsys);
 
     /* The state tracker can organize a softpipe fallback if no hw
      * driver is found.
      */
-    if (is_r3xx(rws->pci_id)) {
-        radeon_setup_winsys(drmFB, rws);
-        return r300_create_screen(&rws->base);
+    if (is_r3xx(rwinsys->pci_id)) {
+        radeon_setup_winsys(drmFB, rwinsys);
+        return r300_create_screen(rwinsys);
     } else {
-        FREE(rws);
+        FREE(rwinsys);
+        return NULL;
+    }
+}
+
+
+boolean radeon_buffer_from_texture(struct drm_api* api,
+                                   struct pipe_screen* screen,
+                                   struct pipe_texture* texture,
+                                   struct pipe_buffer** buffer,
+                                   unsigned* stride)
+{
+    /* XXX fix this */
+    return r300_get_texture_buffer(screen, texture, buffer, stride);
+}
+
+/* Create a buffer from a handle. */
+/* XXX what's up with name? */
+struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api,
+                                              struct pipe_screen* screen,
+                                              const char* name,
+                                              unsigned handle)
+{
+    struct radeon_bo_manager* bom =
+        ((struct radeon_winsys*)screen->winsys)->priv->bom;
+    struct radeon_pipe_buffer* radeon_buffer;
+    struct radeon_bo* bo = NULL;
+
+    bo = radeon_bo_open(bom, handle, 0, 0, 0, 0);
+    if (bo == NULL) {
+        return NULL;
+    }
+
+    radeon_buffer = CALLOC_STRUCT(radeon_pipe_buffer);
+    if (radeon_buffer == NULL) {
+        radeon_bo_unref(bo);
         return NULL;
     }
+
+    pipe_reference_init(&radeon_buffer->base.reference, 1);
+    radeon_buffer->base.screen = screen;
+    radeon_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL;
+    radeon_buffer->bo = bo;
+    return &radeon_buffer->base;
 }
 
 static struct pipe_texture*
@@ -165,20 +197,18 @@ radeon_texture_from_shared_handle(struct drm_api *api,
                                   unsigned stride,
                                   unsigned handle)
 {
-    struct pb_buffer *_buf;
-    struct r300_winsys_buffer *buf;
+    struct pipe_buffer *buffer;
     struct pipe_texture *blanket;
-    struct radeon_libdrm_winsys *ws = radeon_winsys_screen(r300_winsys_screen(screen));
 
-    _buf = radeon_drm_bufmgr_create_buffer_from_handle(ws->kman, handle);
-    if (!_buf) {
-       return NULL;
+    buffer = radeon_buffer_from_handle(api, screen, name, handle);
+    if (!buffer) {
+        return NULL;
     }
 
-    buf = radeon_libdrm_winsys_buffer(_buf);
-    blanket = r300_texture_blanket_winsys_buffer(screen, templ, &stride, buf);
+    blanket = screen->texture_blanket(screen, templ, &stride, buffer);
+
+    pipe_buffer_reference(&buffer, NULL);
 
-    pb_reference(&_buf, NULL);
     return blanket;
 }
 
@@ -188,14 +218,34 @@ static boolean radeon_shared_handle_from_texture(struct drm_api *api,
                                                  unsigned *stride,
                                                  unsigned *handle)
 {
-    struct r300_winsys_buffer *radeon_buffer;
-    struct pb_buffer *_buf;
-    if (!r300_get_texture_buffer(screen, texture, &radeon_buffer, stride)) {
+    int retval, fd;
+    struct drm_gem_flink flink;
+    struct radeon_pipe_buffer* radeon_buffer;
+    struct pipe_buffer *buffer = NULL;
+
+    if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) {
         return FALSE;
     }
 
-    _buf = radeon_pb_buffer(radeon_buffer);
-    return radeon_drm_bufmgr_shared_handle_from_buffer(_buf, handle);
+    radeon_buffer = (struct radeon_pipe_buffer*)buffer;
+    if (!radeon_buffer->flinked) {
+        fd = ((struct radeon_winsys*)screen->winsys)->priv->fd;
+
+        flink.handle = radeon_buffer->bo->handle;
+
+        retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
+        if (retval) {
+            debug_printf("radeon: DRM_IOCTL_GEM_FLINK failed, error %d\n",
+                    retval);
+            return FALSE;
+        }
+
+        radeon_buffer->flink = flink.name;
+        radeon_buffer->flinked = TRUE;
+    }
+
+    *handle = radeon_buffer->flink;
+    return TRUE;
 }
 
 static boolean radeon_local_handle_from_texture(struct drm_api *api,
@@ -204,18 +254,16 @@ static boolean radeon_local_handle_from_texture(struct drm_api *api,
                                                 unsigned *stride,
                                                 unsigned *handle)
 {
-    struct r300_winsys_buffer *radeon_buffer;
-    struct pb_buffer *_buf;
-
-    if (!r300_get_texture_buffer(screen, texture, &radeon_buffer, stride)) {
+    struct pipe_buffer *buffer = NULL;
+    if (!radeon_buffer_from_texture(api, screen, texture, &buffer, stride)) {
         return FALSE;
     }
 
-    _buf = radeon_pb_buffer(radeon_buffer);
-    *handle = radeon_drm_bufmgr_handle_from_buffer(_buf);
+    *handle = ((struct radeon_pipe_buffer*)buffer)->bo->handle;
+
+    pipe_buffer_reference(&buffer, NULL);
 
-    pb_reference(&_buf, NULL);
-    return true;
+    return TRUE;
 }
 
 static void radeon_drm_api_destroy(struct drm_api *api)