llvmpipe: Define an winsys for LLVM. Drop pipe_winsys
authorJosé Fonseca <jfonseca@vmware.com>
Sat, 29 Aug 2009 19:02:25 +0000 (20:02 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Sat, 29 Aug 2009 19:03:44 +0000 (20:03 +0100)
lp_winsys will eventually be unified with softpipe's eventually, but we
are free to move quicker since we don't have the myriad of users yet.

Will provide a pipe_winsys adaptor from Keith's softpipe-private-winsys
soon.

src/gallium/drivers/llvmpipe/SConscript
src/gallium/drivers/llvmpipe/lp_draw_arrays.c
src/gallium/drivers/llvmpipe/lp_screen.c
src/gallium/drivers/llvmpipe/lp_screen.h
src/gallium/drivers/llvmpipe/lp_texture.c
src/gallium/drivers/llvmpipe/lp_texture.h
src/gallium/drivers/llvmpipe/lp_winsys.h

index 26bf8b08fb5f49e776b38b3da4bc94bc4c168512..6bceb84da47ecb3b88d25d9743a8735729533eaa 100644 (file)
@@ -26,6 +26,7 @@ llvmpipe = env.ConvenienceLibrary(
                'lp_bld_swizzle.c',
                'lp_bld_tgsi_soa.c',            
                'lp_bld_type.c',
+               'lp_buffer.c',
                'lp_clear.c',
                'lp_context.c',
                'lp_draw_arrays.c',
index 6a89b74e3a37184c9fe39b8009c4c4f3ac37b340..0f75afc79be0826fe9c720561bb79b9165a4a31d 100644 (file)
 static void
 llvmpipe_map_constant_buffers(struct llvmpipe_context *lp)
 {
-   struct pipe_winsys *ws = lp->pipe.winsys;
+   struct pipe_screen *screen = lp->pipe.screen;
    uint i, size;
 
    for (i = 0; i < PIPE_SHADER_TYPES; i++) {
       if (lp->constants[i].buffer && lp->constants[i].buffer->size)
-         lp->mapped_constants[i] = ws->buffer_map(ws, lp->constants[i].buffer,
-                                                  PIPE_BUFFER_USAGE_CPU_READ);
+         lp->mapped_constants[i] = screen->buffer_map(screen, lp->constants[i].buffer,
+                                                      PIPE_BUFFER_USAGE_CPU_READ);
    }
 
    if (lp->constants[PIPE_SHADER_VERTEX].buffer)
@@ -72,7 +72,7 @@ llvmpipe_map_constant_buffers(struct llvmpipe_context *lp)
 static void
 llvmpipe_unmap_constant_buffers(struct llvmpipe_context *lp)
 {
-   struct pipe_winsys *ws = lp->pipe.winsys;
+   struct pipe_screen *screen = lp->pipe.screen;
    uint i;
 
    /* really need to flush all prims since the vert/frag shaders const buffers
@@ -86,7 +86,7 @@ llvmpipe_unmap_constant_buffers(struct llvmpipe_context *lp)
 
    for (i = 0; i < 2; i++) {
       if (lp->constants[i].buffer && lp->constants[i].buffer->size)
-         ws->buffer_unmap(ws, lp->constants[i].buffer);
+         screen->buffer_unmap(screen, lp->constants[i].buffer);
       lp->mapped_constants[i] = NULL;
    }
 }
index f302b99ad769beedbe873ecba304d9d067d22a4e..125035771e52dc3d7c867684582e3986963e1e54 100644 (file)
@@ -33,6 +33,7 @@
 #include "pipe/p_screen.h"
 
 #include "lp_texture.h"
+#include "lp_buffer.h"
 #include "lp_winsys.h"
 #include "lp_jit.h"
 #include "lp_screen.h"
@@ -41,7 +42,7 @@
 static const char *
 llvmpipe_get_vendor(struct pipe_screen *screen)
 {
-   return "Tungsten Graphics, Inc.";
+   return "VMware, Inc.";
 }
 
 
@@ -126,12 +127,15 @@ llvmpipe_get_paramf(struct pipe_screen *screen, int param)
  * \param type  one of PIPE_TEXTURE, PIPE_SURFACE
  */
 static boolean
-llvmpipe_is_format_supported( struct pipe_screen *screen,
+llvmpipe_is_format_supported( struct pipe_screen *_screen,
                               enum pipe_format format, 
                               enum pipe_texture_target target,
                               unsigned tex_usage, 
                               unsigned geom_flags )
 {
+   struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
+   struct llvmpipe_winsys *winsys = screen->winsys;
+
    assert(target == PIPE_TEXTURE_1D ||
           target == PIPE_TEXTURE_2D ||
           target == PIPE_TEXTURE_3D ||
@@ -149,8 +153,42 @@ llvmpipe_is_format_supported( struct pipe_screen *screen,
    case PIPE_FORMAT_DXT5_RGBA:
       return FALSE;
    default:
-      return TRUE;
+      break;
    }
+
+   if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
+      return winsys->is_displaytarget_format_supported(winsys, format);
+
+   return TRUE;
+}
+
+
+static struct pipe_buffer *
+llvmpipe_surface_buffer_create(struct pipe_screen *screen,
+                               unsigned width, unsigned height,
+                               enum pipe_format format,
+                               unsigned tex_usage,
+                               unsigned usage,
+                               unsigned *stride)
+{
+   /* This function should never be used */
+   assert(0);
+   return NULL;
+}
+
+
+static void
+llvmpipe_flush_frontbuffer(struct pipe_screen *_screen,
+                           struct pipe_surface *surface,
+                           void *context_private)
+{
+   struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
+   struct llvmpipe_winsys *winsys = screen->winsys;
+   struct llvmpipe_texture *texture = llvmpipe_texture(surface->texture);
+
+   assert(texture->dt);
+   if (texture->dt)
+      winsys->displaytarget_display(winsys, texture->dt, context_private);
 }
 
 
@@ -176,14 +214,14 @@ llvmpipe_destroy_screen( struct pipe_screen *_screen )
  * Note: we're not presently subclassing pipe_screen (no llvmpipe_screen).
  */
 struct pipe_screen *
-llvmpipe_create_screen(struct pipe_winsys *winsys)
+llvmpipe_create_screen(struct llvmpipe_winsys *winsys)
 {
    struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen);
 
    if (!screen)
       return NULL;
 
-   screen->base.winsys = winsys;
+   screen->winsys = winsys;
 
    screen->base.destroy = llvmpipe_destroy_screen;
 
@@ -193,8 +231,11 @@ llvmpipe_create_screen(struct pipe_winsys *winsys)
    screen->base.get_paramf = llvmpipe_get_paramf;
    screen->base.is_format_supported = llvmpipe_is_format_supported;
 
+   screen->base.surface_buffer_create = llvmpipe_surface_buffer_create;
+   screen->base.flush_frontbuffer = llvmpipe_flush_frontbuffer;
+
    llvmpipe_init_screen_texture_funcs(&screen->base);
-   u_simple_screen_init(&screen->base);
+   llvmpipe_init_screen_buffer_funcs(&screen->base);
 
    lp_jit_screen_init(screen);
 
index 98d27891596b862e01969b9ec0ddf39777a35e86..4a1b4d6f3e21ce727aec6cc35c342f635338875f 100644 (file)
 #include "pipe/p_defines.h"
 
 
+struct llvmpipe_winsys;
+
+
 struct llvmpipe_screen
 {
    struct pipe_screen base;
 
+   struct llvmpipe_winsys *winsys;
+
    LLVMModuleRef module;
    LLVMExecutionEngineRef engine;
    LLVMModuleProviderRef provider;
index 18e348d69e0bcf9c95793bb50f43fd3104eb95d1..724d43783360e3a037f6c34cac3688f4ca75cb40 100644 (file)
@@ -52,7 +52,7 @@
 /* Conventional allocation path for non-display textures:
  */
 static boolean
-llvmpipe_texture_layout(struct pipe_screen *screen,
+llvmpipe_texture_layout(struct llvmpipe_screen *screen,
                         struct llvmpipe_texture * lpt)
 {
    struct pipe_texture *pt = &lpt->base;
@@ -84,34 +84,29 @@ llvmpipe_texture_layout(struct pipe_screen *screen,
       depth = minify(depth);
    }
 
-   lpt->buffer = screen->buffer_create(screen, 32,
-                                       PIPE_BUFFER_USAGE_PIXEL,
-                                       buffer_size);
+   lpt->data = align_malloc(buffer_size, 16);
 
-   return lpt->buffer != NULL;
+   return lpt->data != NULL;
 }
 
 static boolean
-llvmpipe_displaytarget_layout(struct pipe_screen *screen,
+llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
                               struct llvmpipe_texture * lpt)
 {
-   unsigned usage = (PIPE_BUFFER_USAGE_CPU_READ_WRITE |
-                     PIPE_BUFFER_USAGE_GPU_READ_WRITE);
-   unsigned tex_usage = lpt->base.tex_usage;
+   struct llvmpipe_winsys *winsys = screen->winsys;
 
    pf_get_block(lpt->base.format, &lpt->base.block);
    lpt->base.nblocksx[0] = pf_get_nblocksx(&lpt->base.block, lpt->base.width[0]);  
    lpt->base.nblocksy[0] = pf_get_nblocksy(&lpt->base.block, lpt->base.height[0]);  
 
-   lpt->buffer = screen->surface_buffer_create( screen, 
-                                                lpt->base.width[0], 
-                                                lpt->base.height[0],
-                                                lpt->base.format,
-                                                usage,
-                                                tex_usage,
-                                                &lpt->stride[0]);
+   lpt->dt = winsys->displaytarget_create(winsys,
+                                          lpt->base.format,
+                                          lpt->base.width[0],
+                                          lpt->base.height[0],
+                                          16,
+                                          &lpt->stride[0] );
 
-   return lpt->buffer != NULL;
+   return lpt->dt != NULL;
 }
 
 
@@ -119,16 +114,17 @@ llvmpipe_displaytarget_layout(struct pipe_screen *screen,
 
 
 static struct pipe_texture *
-llvmpipe_texture_create(struct pipe_screen *screen,
+llvmpipe_texture_create(struct pipe_screen *_screen,
                         const struct pipe_texture *templat)
 {
+   struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
    struct llvmpipe_texture *lpt = CALLOC_STRUCT(llvmpipe_texture);
    if (!lpt)
       return NULL;
 
    lpt->base = *templat;
    pipe_reference_init(&lpt->base.reference, 1);
-   lpt->base.screen = screen;
+   lpt->base.screen = &screen->base;
 
    /* XXX: The xlib state tracker is brain-dead and will request
     * PIPE_FORMAT_Z16_UNORM no matter how much we tell it we don't support it.
@@ -160,6 +156,8 @@ llvmpipe_texture_blanket(struct pipe_screen * screen,
                          const unsigned *stride,
                          struct pipe_buffer *buffer)
 {
+   /* FIXME */
+#if 0
    struct llvmpipe_texture *lpt;
    assert(screen);
 
@@ -184,15 +182,25 @@ llvmpipe_texture_blanket(struct pipe_screen * screen,
    pipe_buffer_reference(&lpt->buffer, buffer);
 
    return &lpt->base;
+#else
+   return NULL;
+#endif
 }
 
 
 static void
 llvmpipe_texture_destroy(struct pipe_texture *pt)
 {
+   struct llvmpipe_screen *screen = llvmpipe_screen(pt->screen);
    struct llvmpipe_texture *lpt = llvmpipe_texture(pt);
 
-   pipe_buffer_reference(&lpt->buffer, NULL);
+   if(lpt->dt) {
+      struct llvmpipe_winsys *winsys = screen->winsys;
+      winsys->displaytarget_destroy(winsys, lpt->dt);
+   }
+   else
+      align_free(lpt->data);
+
    FREE(lpt);
 }
 
@@ -333,27 +341,34 @@ llvmpipe_tex_transfer_destroy(struct pipe_transfer *transfer)
 
 
 static void *
-llvmpipe_transfer_map( struct pipe_screen *screen,
+llvmpipe_transfer_map( struct pipe_screen *_screen,
                        struct pipe_transfer *transfer )
 {
+   struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
    ubyte *map, *xfer_map;
    struct llvmpipe_texture *lpt;
-   unsigned flags = 0;
 
    assert(transfer->texture);
    lpt = llvmpipe_texture(transfer->texture);
 
-   if (transfer->usage != PIPE_TRANSFER_READ) {
-      flags |= PIPE_BUFFER_USAGE_CPU_WRITE;
-   }
+   if(lpt->dt) {
+      struct llvmpipe_winsys *winsys = screen->winsys;
+      unsigned flags = 0;
 
-   if (transfer->usage != PIPE_TRANSFER_WRITE) {
-      flags |= PIPE_BUFFER_USAGE_CPU_READ;
-   }
+      if (transfer->usage != PIPE_TRANSFER_READ) {
+         flags |= PIPE_BUFFER_USAGE_CPU_WRITE;
+      }
 
-   map = pipe_buffer_map(screen, lpt->buffer, flags);
-   if (map == NULL)
-      return NULL;
+      if (transfer->usage != PIPE_TRANSFER_WRITE) {
+         flags |= PIPE_BUFFER_USAGE_CPU_READ;
+      }
+
+      map = winsys->displaytarget_map(winsys, lpt->dt, flags);
+      if (map == NULL)
+         return NULL;
+   }
+   else
+      map = lpt->data;
 
    /* May want to different things here depending on read/write nature
     * of the map:
@@ -363,7 +378,7 @@ llvmpipe_transfer_map( struct pipe_screen *screen,
       /* Do something to notify sharing contexts of a texture change.
        * In llvmpipe, that would mean flushing the texture cache.
        */
-      llvmpipe_screen(screen)->timestamp++;
+      screen->timestamp++;
    }
    
    xfer_map = map + llvmpipe_transfer(transfer)->offset +
@@ -375,15 +390,19 @@ llvmpipe_transfer_map( struct pipe_screen *screen,
 
 
 static void
-llvmpipe_transfer_unmap(struct pipe_screen *screen,
+llvmpipe_transfer_unmap(struct pipe_screen *_screen,
                        struct pipe_transfer *transfer)
 {
+   struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
    struct llvmpipe_texture *lpt;
 
    assert(transfer->texture);
    lpt = llvmpipe_texture(transfer->texture);
 
-   pipe_buffer_unmap( screen, lpt->buffer );
+   if(lpt->dt) {
+      struct llvmpipe_winsys *winsys = screen->winsys;
+      winsys->displaytarget_unmap(winsys, lpt->dt);
+   }
 }
 
 
@@ -408,22 +427,3 @@ llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen)
    screen->transfer_map = llvmpipe_transfer_map;
    screen->transfer_unmap = llvmpipe_transfer_unmap;
 }
-
-
-boolean
-llvmpipe_get_texture_buffer( struct pipe_texture *texture,
-                             struct pipe_buffer **buf,
-                             unsigned *stride )
-{
-   struct llvmpipe_texture *tex = (struct llvmpipe_texture *)texture;
-
-   if (!tex)
-      return FALSE;
-
-   pipe_buffer_reference(buf, tex->buffer);
-
-   if (stride)
-      *stride = tex->stride[0];
-
-   return TRUE;
-}
index a1ed6b0ac28b302b5ab2a09863b9a63367de51b1..00a20763e43f1c642b80222ef8f7b6c1d6451497 100644 (file)
@@ -35,7 +35,7 @@
 struct pipe_context;
 struct pipe_screen;
 struct llvmpipe_context;
-
+struct llvmpipe_displaytarget;
 
 struct llvmpipe_texture
 {
@@ -44,9 +44,16 @@ struct llvmpipe_texture
    unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS];
    unsigned stride[PIPE_MAX_TEXTURE_LEVELS];
 
-   /* The data is held here:
+   /**
+    * Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET
+    * usage.
+    */
+   struct llvmpipe_displaytarget *dt;
+
+   /**
+    * Malloc'ed data for regular textures, or a mapping to dt above.
     */
-   struct pipe_buffer *buffer;
+   void *data;
 
    unsigned timestamp;
 };
index 268336b69035d1b6a63f3ec1ba7d8e7e4d45fa59..595481c2cbc21e4fce33fb332e6ee8cf56266a66 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************
  * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2007-2009 VMware, Inc.
  * All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -25,9 +25,9 @@
  * 
  **************************************************************************/
 
-/* This is the interface that llvmpipe requires any window system
- * hosting it to implement.  This is the only include file in llvmpipe
- * which is public.
+/**
+ * @file
+ * llvmpipe public interface.
  */
 
 
 #define LP_WINSYS_H
 
 
+#include "pipe/p_compiler.h" // for boolean
+#include "pipe/p_format.h"
+
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 
 struct pipe_screen;
-struct pipe_winsys;
 struct pipe_context;
 
 
-struct pipe_context *llvmpipe_create( struct pipe_screen * );
+/**
+ * Opaque pointer.
+ */
+struct llvmpipe_displaytarget;
 
 
-struct pipe_screen *
-llvmpipe_create_screen(struct pipe_winsys *);
+/**
+ * This is the interface that llvmpipe expects any window system
+ * hosting it to implement.
+ * 
+ * llvmpipe is for the most part a self sufficient driver. The only thing it
+ * does not know is how to display a surface.
+ */
+struct llvmpipe_winsys
+{
+   void 
+   (*destroy)( struct llvmpipe_winsys *ws );
+
+   boolean
+   (*is_displaytarget_format_supported)( struct llvmpipe_winsys *ws,
+                                         enum pipe_format format );
+   
+   /**
+    * Allocate storage for a render target.
+    * 
+    * Often surfaces which are meant to be blitted to the front screen (i.e.,
+    * display targets) must be allocated with special characteristics, memory 
+    * pools, or obtained directly from the windowing system.
+    *  
+    * This callback is invoked by the pipe_screen when creating a texture marked
+    * with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET flag to get the underlying 
+    * storage.
+    */
+   struct llvmpipe_displaytarget *
+   (*displaytarget_create)( struct llvmpipe_winsys *ws,
+                            enum pipe_format format,
+                            unsigned width, unsigned height,
+                            unsigned alignment,
+                            unsigned *stride );
+
+   void *
+   (*displaytarget_map)( struct llvmpipe_winsys *ws, 
+                         struct llvmpipe_displaytarget *dt,
+                         unsigned flags );
+
+   void
+   (*displaytarget_unmap)( struct llvmpipe_winsys *ws,
+                           struct llvmpipe_displaytarget *dt );
+
+   /**
+    * @sa pipe_screen:flush_frontbuffer.
+    *
+    * This call will likely become asynchronous eventually.
+    */
+   void
+   (*displaytarget_display)( struct llvmpipe_winsys *ws, 
+                             struct llvmpipe_displaytarget *dt,
+                             void *context_private );
+
+   void 
+   (*displaytarget_destroy)( struct llvmpipe_winsys *ws, 
+                             struct llvmpipe_displaytarget *dt );
+};
+
+
+struct pipe_context *
+llvmpipe_create( struct pipe_screen * );
 
 
-boolean
-llvmpipe_get_texture_buffer( struct pipe_texture *texture,
-                             struct pipe_buffer **buf,
-                             unsigned *stride );
+struct pipe_screen *
+llvmpipe_create_screen( struct llvmpipe_winsys * );
 
 
 #ifdef __cplusplus