gdi: Integrate with llvmpipe where available.
authorJosé Fonseca <jfonseca@vmware.com>
Wed, 16 Sep 2009 09:39:29 +0000 (10:39 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Wed, 16 Sep 2009 10:35:23 +0000 (11:35 +0100)
src/gallium/winsys/gdi/SConscript
src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c [new file with mode: 0644]

index 86eb9ef55ed7c261d4ffd31f60bea777bedad3a7..f5e6d36d89c2ae8082c444ce03aac9d0a9806191 100644 (file)
@@ -5,35 +5,39 @@ Import('*')
 
 if env['platform'] == 'windows':
 
-       env = env.Clone()
+    env = env.Clone()
 
-       env.Append(CPPPATH = [
-               '#src/gallium/state_trackers/wgl',
-       ])
+    env.Append(CPPPATH = [
+        '#src/gallium/state_trackers/wgl',
+    ])
 
-       env.Append(LIBS = [
-               'gdi32',
-               'user32',
-               'kernel32',
-               'ws2_32',
-       ])
+    env.Append(LIBS = [
+        'gdi32',
+        'user32',
+        'kernel32',
+        'ws2_32',
+    ])
 
-       sources = [
-               'gdi_softpipe_winsys.c',
-       ]
-       
-       if env['gcc']:
-               sources += ['#src/gallium/state_trackers/wgl/opengl32.mingw.def']
-       else:
-               sources += ['#src/gallium/state_trackers/wgl/opengl32.def']
-               
-       drivers = [
-               trace,
-               softpipe,
-       ]
+    if 'llvmpipe' in env['drivers']:
+        sources = ['gdi_llvmpipe_winsys.c']
+        drivers = [llvmpipe]
+        env.Tool('llvm')
+    elif 'softpipe' in env['drivers']:
+        sources = ['gdi_softpipe_winsys.c']
+        drivers = [softpipe]
+    else:
+        print 'warning: softpipe or llvmpipe not selected, gdi winsys disabled'
+        Return()
+    
+    if env['gcc']:
+        sources += ['#src/gallium/state_trackers/wgl/opengl32.mingw.def']
+    else:
+        sources += ['#src/gallium/state_trackers/wgl/opengl32.def']
+        
+    drivers += [trace]
 
-       env.SharedLibrary(
-               target ='opengl32',
-               source = sources,
-               LIBS = wgl + glapi + mesa + drivers + auxiliaries + env['LIBS'],
-       )
+    env.SharedLibrary(
+        target ='opengl32',
+        source = sources,
+        LIBS = wgl + glapi + mesa + drivers + auxiliaries + env['LIBS'],
+    )
diff --git a/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c b/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c
new file mode 100644 (file)
index 0000000..c0c33b4
--- /dev/null
@@ -0,0 +1,284 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * 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
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * 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
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * LLVMpipe support.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#include <windows.h>
+
+#include "pipe/p_format.h"
+#include "pipe/p_context.h"
+#include "pipe/p_inlines.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "llvmpipe/lp_winsys.h"
+#include "llvmpipe/lp_texture.h"
+#include "shared/stw_winsys.h"
+
+
+struct gdi_llvmpipe_displaytarget
+{
+   enum pipe_format format;
+   struct pipe_format_block block;
+   unsigned width;
+   unsigned height;
+   unsigned stride;
+
+   unsigned size;
+
+   void *data;
+
+   BITMAPINFO bmi;
+};
+
+
+/** Cast wrapper */
+static INLINE struct gdi_llvmpipe_displaytarget *
+gdi_llvmpipe_displaytarget( struct llvmpipe_displaytarget *buf )
+{
+   return (struct gdi_llvmpipe_displaytarget *)buf;
+}
+
+
+static boolean
+gdi_llvmpipe_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
+                                                enum pipe_format format )
+{
+   switch(format) {
+   case PIPE_FORMAT_X8R8G8B8_UNORM:
+   case PIPE_FORMAT_A8R8G8B8_UNORM:
+      return TRUE;
+
+   /* TODO: Support other formats possible with BMPs, as described in 
+    * http://msdn.microsoft.com/en-us/library/dd183376(VS.85).aspx */
+      
+   default:
+      return FALSE;
+   }
+}
+
+
+static void *
+gdi_llvmpipe_displaytarget_map(struct llvmpipe_winsys *ws,
+                               struct llvmpipe_displaytarget *dt,
+                               unsigned flags )
+{
+   struct gdi_llvmpipe_displaytarget *gdt = gdi_llvmpipe_displaytarget(dt);
+
+   return gdt->data;
+}
+
+
+static void
+gdi_llvmpipe_displaytarget_unmap(struct llvmpipe_winsys *ws,
+                                 struct llvmpipe_displaytarget *dt )
+{
+
+}
+
+
+static void
+gdi_llvmpipe_displaytarget_destroy(struct llvmpipe_winsys *winsys,
+                                   struct llvmpipe_displaytarget *dt)
+{
+   struct gdi_llvmpipe_displaytarget *gdt = gdi_llvmpipe_displaytarget(dt);
+
+   align_free(gdt->data);
+   FREE(gdt);
+}
+
+
+/**
+ * Round n up to next multiple.
+ */
+static INLINE unsigned
+round_up(unsigned n, unsigned multiple)
+{
+   return (n + multiple - 1) & ~(multiple - 1);
+}
+
+
+static struct llvmpipe_displaytarget *
+gdi_llvmpipe_displaytarget_create(struct llvmpipe_winsys *winsys,
+                                  enum pipe_format format,
+                                  unsigned width, unsigned height,
+                                  unsigned alignment,
+                                  unsigned *stride)
+{
+   struct gdi_llvmpipe_displaytarget *gdt;
+   unsigned cpp;
+   unsigned bpp;
+   
+   gdt = CALLOC_STRUCT(gdi_llvmpipe_displaytarget);
+   if(!gdt)
+      goto no_gdt;
+
+   gdt->format = format;
+   gdt->width = width;
+   gdt->height = height;
+
+   bpp = pf_get_bits(format);
+   cpp = pf_get_size(format);
+   
+   gdt->stride = round_up(width * cpp, alignment);
+   gdt->size = gdt->stride * height;
+   
+   gdt->data = align_malloc(gdt->size, alignment);
+   if(!gdt->data)
+      goto no_data;
+
+   gdt->bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+   gdt->bmi.bmiHeader.biWidth = gdt->stride / cpp;
+   gdt->bmi.bmiHeader.biHeight= -(long)height;
+   gdt->bmi.bmiHeader.biPlanes = 1;
+   gdt->bmi.bmiHeader.biBitCount = bpp;
+   gdt->bmi.bmiHeader.biCompression = BI_RGB;
+   gdt->bmi.bmiHeader.biSizeImage = 0;
+   gdt->bmi.bmiHeader.biXPelsPerMeter = 0;
+   gdt->bmi.bmiHeader.biYPelsPerMeter = 0;
+   gdt->bmi.bmiHeader.biClrUsed = 0;
+   gdt->bmi.bmiHeader.biClrImportant = 0;
+
+   *stride = gdt->stride;
+   return (struct llvmpipe_displaytarget *)gdt;
+
+no_data:
+   FREE(gdt);
+no_gdt:
+   return NULL;
+}
+
+
+static void
+gdi_llvmpipe_displaytarget_display(struct llvmpipe_winsys *winsys, 
+                                   struct llvmpipe_displaytarget *dt,
+                                   void *context_private)
+{
+   assert(0);
+}
+
+
+static void
+gdi_llvmpipe_destroy(struct llvmpipe_winsys *winsys)
+{
+   FREE(winsys);
+}
+
+
+static struct pipe_screen *
+gdi_llvmpipe_screen_create(void)
+{
+   static struct llvmpipe_winsys *winsys;
+   struct pipe_screen *screen;
+
+   winsys = CALLOC_STRUCT(llvmpipe_winsys);
+   if(!winsys)
+      goto no_winsys;
+
+   winsys->destroy = gdi_llvmpipe_destroy;
+   winsys->is_displaytarget_format_supported = gdi_llvmpipe_is_displaytarget_format_supported;
+   winsys->displaytarget_create = gdi_llvmpipe_displaytarget_create;
+   winsys->displaytarget_map = gdi_llvmpipe_displaytarget_map;
+   winsys->displaytarget_unmap = gdi_llvmpipe_displaytarget_unmap;
+   winsys->displaytarget_display = gdi_llvmpipe_displaytarget_display;
+   winsys->displaytarget_destroy = gdi_llvmpipe_displaytarget_destroy;
+
+   screen = llvmpipe_create_screen(winsys);
+   if(!screen)
+      goto no_screen;
+
+   return screen;
+   
+no_screen:
+   FREE(winsys);
+no_winsys:
+   return NULL;
+}
+
+
+static struct pipe_context *
+gdi_llvmpipe_context_create(struct pipe_screen *screen)
+{
+   return llvmpipe_create(screen);
+}
+
+
+static void
+gdi_llvmpipe_flush_frontbuffer(struct pipe_screen *screen,
+                               struct pipe_surface *surface,
+                               HDC hDC)
+{
+    struct llvmpipe_texture *texture;
+    struct gdi_llvmpipe_displaytarget *gdt;
+
+    texture = llvmpipe_texture(surface->texture);
+    gdt = gdi_llvmpipe_displaytarget(texture->dt);
+
+    StretchDIBits(hDC,
+                  0, 0, gdt->width, gdt->height,
+                  0, 0, gdt->width, gdt->height,
+                  gdt->data, &gdt->bmi, 0, SRCCOPY);
+}
+
+
+static const struct stw_winsys stw_winsys = {
+   &gdi_llvmpipe_screen_create,
+   &gdi_llvmpipe_context_create,
+   &gdi_llvmpipe_flush_frontbuffer
+};
+
+
+BOOL WINAPI
+DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
+{
+   switch (fdwReason) {
+   case DLL_PROCESS_ATTACH:
+      if (!stw_init(&stw_winsys)) {
+         return FALSE;
+      }
+      return stw_init_thread();
+
+   case DLL_THREAD_ATTACH:
+      return stw_init_thread();
+
+   case DLL_THREAD_DETACH:
+      stw_cleanup_thread();
+      break;
+
+   case DLL_PROCESS_DETACH:
+      stw_cleanup_thread();
+      stw_cleanup();
+      break;
+   }
+   return TRUE;
+}