i915: Create a texture and surface for shared frontbuffer
authorJakob Bornecrantz <jakob@tungstengraphics.com>
Tue, 24 Jun 2008 12:42:12 +0000 (14:42 +0200)
committerJakob Bornecrantz <jakob@tungstengraphics.com>
Tue, 24 Jun 2008 12:42:12 +0000 (14:42 +0200)
src/gallium/winsys/dri/intel/intel_screen.c
src/gallium/winsys/dri/intel/intel_screen.h

index 809af2e553093621b4d1a9e8a5c682376f3c56db..18427a4586fcd3bff9f358561ab266f4dfebc609 100644 (file)
 #include "intel_drm/ws_dri_bufpool.h"
 
 #include "pipe/p_context.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_inlines.h"
 #include "state_tracker/st_public.h"
 #include "state_tracker/st_cb_fbo.h"
 
+static void
+intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle);
 
+static void
+intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle)
+{
+   struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf));
+   struct pipe_screen *screen = intelScreen->base.screen;
+   struct pipe_texture *texture;
+   struct pipe_texture templat;
+   struct pipe_surface *surface;
+   struct pipe_buffer *buffer = &be_buf->base;
+   unsigned pitch;
+
+   assert(intelScreen->front.cpp == 4);
+
+   /* XXX create a intel_be function for this */
+   {
+      driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0);
+      driBOSetReferenced(intelScreen->front.buffer, handle);
+
+      memset(be_buf, 0, sizeof(*be_buf));
+      buffer->refcount = 1;
+      buffer->alignment = 0;
+      buffer->usage = 0;
+      buffer->size = driBOSize(intelScreen->front.buffer);
+      be_buf->driBO = intelScreen->front.buffer;
+   }
+
+   memset(&templat, 0, sizeof(templat));
+   templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+   templat.target = PIPE_TEXTURE_2D;
+   templat.last_level = 0;
+   templat.depth[0] = 1;
+   templat.format = PIPE_FORMAT_A8R8G8B8_UNORM;
+   templat.cpp = intelScreen->front.cpp;
+   templat.width[0] = intelScreen->front.width;
+   templat.height[0] = intelScreen->front.height;
+   pitch = intelScreen->front.pitch / intelScreen->front.cpp;
+
+   texture = screen->texture_blanket(screen,
+                                     &templat,
+                                     &pitch,
+                                     buffer);
+
+   /* Unref the buffer we don't need it anyways */
+   pipe_buffer_reference(screen->winsys, &buffer, NULL);
+
+   surface = screen->get_tex_surface(screen,
+                                     texture,
+                                     0,
+                                     0,
+                                     0,
+                                     PIPE_BUFFER_USAGE_GPU_WRITE);
+
+   intelScreen->front.texture = texture;
+   intelScreen->front.surface = surface;
+}
 
 PUBLIC const char __driConfigOptions[] =
    DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE
@@ -157,10 +216,12 @@ intelUpdateScreenRotation(__DRIscreenPrivate * sPriv, drmI830Sarea * sarea)
    }
 #else
    if (intelScreen->base.staticPool) {
-      if (intelScreen->front.buffer)
+      if (intelScreen->front.buffer) {
         driBOUnReference(intelScreen->front.buffer);
-      driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0);
-      driBOSetReferenced(intelScreen->front.buffer, sarea->front_bo_handle);
+        pipe_surface_reference(&intelScreen->front.surface, NULL);
+        pipe_texture_reference(&intelScreen->front.texture, NULL);
+      }
+      intelCreateSurface(intelScreen, &intelScreen->base.base, sarea->front_bo_handle);
    }
 #endif
 }
index 8036917903126d3b05c098fd1feaf531843c21c2..e62f9e71eca95e5a700130bf248a535ef23fe98c 100644 (file)
@@ -47,6 +47,8 @@ struct intel_screen
       /* We create a static dri buffer for the frontbuffer.
        */
       struct _DriBufferObject *buffer;
+      struct pipe_surface *surface;
+      struct pipe_texture *texture;
 
       char *map;                   /* memory map */
       int offset;                  /* from start of video mem, in bytes */