Merge branch 'mesa_7_6_branch' of git+ssh://agd5f@git.freedesktop.org/git/mesa/mesa
[mesa.git] / src / gallium / winsys / drm / radeon / core / radeon_buffer.c
index a15487352b22dbce33c8125bb3c6430b4ac664fb..7bf23cba236520c0749b511e487de47b72ce86d1 100644 (file)
@@ -1,8 +1,8 @@
-/* 
+/*
  * Copyright © 2008 Jérôme Glisse
  *             2009 Corbin Simpson
  * All Rights Reserved.
- * 
+ *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
  * "Software"), to deal in the Software without restriction, including
  * distribute, sub license, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject to
  * the following conditions:
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
  * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  * The above copyright notice and this permission notice (including the
@@ -32,6 +32,8 @@
 
 #include "radeon_buffer.h"
 
+#include "radeon_bo_gem.h"
+
 static const char *radeon_get_name(struct pipe_winsys *ws)
 {
     return "Radeon/GEM+KMS";
@@ -72,6 +74,7 @@ static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws,
             alignment, domain, 0);
     if (radeon_buffer->bo == NULL) {
         FREE(radeon_buffer);
+        return NULL;
     }
     return &radeon_buffer->base;
 }
@@ -93,6 +96,30 @@ static struct pipe_buffer *radeon_buffer_user_create(struct pipe_winsys *ws,
     return &radeon_buffer->base;
 }
 
+static struct pipe_buffer *radeon_surface_buffer_create(struct pipe_winsys *ws,
+                                                        unsigned width,
+                                                        unsigned height,
+                                                        enum pipe_format format,
+                                                        unsigned usage,
+                                                        unsigned tex_usage,
+                                                        unsigned *stride)
+{
+    struct pipe_format_block block;
+    unsigned nblocksx, nblocksy, size;
+
+    pf_get_block(format, &block);
+
+    nblocksx = pf_get_nblocksx(&block, width);
+    nblocksy = pf_get_nblocksy(&block, height);
+
+    /* Radeons enjoy things in multiples of 32. */
+    /* XXX this can be 32 when POT */
+    *stride = (nblocksx * block.size + 63) & ~63;
+    size = *stride * nblocksy;
+
+    return radeon_buffer_create(ws, 64, usage, size);
+}
+
 static void radeon_buffer_del(struct pipe_buffer *buffer)
 {
     struct radeon_pipe_buffer *radeon_buffer =
@@ -111,15 +138,19 @@ static void *radeon_buffer_map(struct pipe_winsys *ws,
     int write = 0;
 
     if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
-       /* XXX Remove this when radeon_bo_map supports DONTBLOCK */
-       return NULL;
+        uint32_t domain;
+
+        if (radeon_bo_is_busy(radeon_buffer->bo, &domain))
+            return NULL;
     }
     if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) {
         write = 1;
     }
 
-    if (radeon_bo_map(radeon_buffer->bo, write))
+    if (radeon_bo_map(radeon_buffer->bo, write)) {
         return NULL;
+    }
+
     return radeon_buffer->bo->ptr;
 }
 
@@ -162,7 +193,6 @@ static void radeon_flush_frontbuffer(struct pipe_winsys *pipe_winsys,
 struct radeon_winsys* radeon_pipe_winsys(int fd)
 {
     struct radeon_winsys* radeon_ws;
-    struct radeon_bo_manager* bom;
 
     radeon_ws = CALLOC_STRUCT(radeon_winsys);
     if (radeon_ws == NULL) {
@@ -175,15 +205,17 @@ struct radeon_winsys* radeon_pipe_winsys(int fd)
         return NULL;
     }
 
+    radeon_ws->priv->fd = fd;
     radeon_ws->priv->bom = radeon_bo_manager_gem_ctor(fd);
 
     radeon_ws->base.flush_frontbuffer = radeon_flush_frontbuffer;
 
     radeon_ws->base.buffer_create = radeon_buffer_create;
-    radeon_ws->base.buffer_destroy = radeon_buffer_del;
     radeon_ws->base.user_buffer_create = radeon_buffer_user_create;
+    radeon_ws->base.surface_buffer_create = radeon_surface_buffer_create;
     radeon_ws->base.buffer_map = radeon_buffer_map;
     radeon_ws->base.buffer_unmap = radeon_buffer_unmap;
+    radeon_ws->base.buffer_destroy = radeon_buffer_del;
 
     radeon_ws->base.fence_reference = radeon_fence_reference;
     radeon_ws->base.fence_signalled = radeon_fence_signalled;