Provides basic window system integration behind a simple interface, allowing tests to be written without dependency on either the driver or window system. With a lot of work, could turn into something like glut for gallium.tags/mesa-7.9-rc1
@@ -52,7 +52,7 @@ opts.Add(ListVariable('statetrackers', 'state trackers to build', default_statet | |||
opts.Add(ListVariable('drivers', 'pipe drivers to build', default_drivers, | |||
['softpipe', 'failover', 'svga', 'i915', 'i965', 'trace', 'r300', 'identity', 'llvmpipe'])) | |||
opts.Add(ListVariable('winsys', 'winsys drivers to build', default_winsys, | |||
['xlib', 'vmware', 'i915', 'i965', 'gdi', 'radeon'])) | |||
['xlib', 'vmware', 'i915', 'i965', 'gdi', 'radeon', 'graw-xlib'])) | |||
opts.Add(EnumVariable('MSVS_VERSION', 'MS Visual C++ version', None, allowed_values=('7.1', '8.0', '9.0'))) | |||
@@ -56,4 +56,5 @@ SConscript([ | |||
'wgl/SConscript', | |||
'perf/SConscript', | |||
'gallium/unit/SConscript', | |||
'gallium/raw/SConscript', | |||
]) |
@@ -0,0 +1,17 @@ | |||
Import('*') | |||
env = env.Clone() | |||
env.Prepend(LIBPATH = [graw.dir]) | |||
env.Prepend(LIBS = [graw.name]) | |||
progs = [ | |||
'clear' | |||
] | |||
for prog in progs: | |||
env.Program( | |||
target = prog, | |||
source = prog + '.c', | |||
) | |||
@@ -0,0 +1,85 @@ | |||
/* Display a cleared blue window. This demo has no dependencies on | |||
* any utility code, just the graw interface and gallium. | |||
*/ | |||
#include "state_tracker/graw.h" | |||
#include "pipe/p_screen.h" | |||
#include "pipe/p_context.h" | |||
#include "pipe/p_state.h" | |||
#include "pipe/p_defines.h" | |||
#include <unistd.h> /* for sleep() */ | |||
enum pipe_format formats[] = { | |||
PIPE_FORMAT_R8G8B8A8_UNORM, | |||
PIPE_FORMAT_B8G8R8A8_UNORM, | |||
PIPE_FORMAT_NONE | |||
}; | |||
static const int WIDTH = 300; | |||
static const int HEIGHT = 300; | |||
int main( int argc, char *argv[] ) | |||
{ | |||
struct pipe_screen *screen; | |||
struct pipe_context *pipe; | |||
struct pipe_surface *surf; | |||
struct pipe_framebuffer_state fb; | |||
struct pipe_texture *tex, templat; | |||
void *window = NULL; | |||
float clear_color[4] = {1,0,1,1}; | |||
int i; | |||
screen = graw_init(); | |||
if (screen == NULL) | |||
exit(1); | |||
for (i = 0; | |||
window == NULL && formats[i] != PIPE_FORMAT_NONE; | |||
i++) { | |||
window = graw_create_window(0,0,300,300, formats[i]); | |||
} | |||
if (window == NULL) | |||
exit(2); | |||
pipe = screen->context_create(screen, NULL); | |||
if (pipe == NULL) | |||
exit(3); | |||
templat.target = PIPE_TEXTURE_2D; | |||
templat.format = formats[i]; | |||
templat.width0 = WIDTH; | |||
templat.height0 = HEIGHT; | |||
templat.depth0 = 1; | |||
templat.last_level = 0; | |||
templat.nr_samples = 1; | |||
templat.tex_usage = (PIPE_TEXTURE_USAGE_RENDER_TARGET | | |||
PIPE_TEXTURE_USAGE_DISPLAY_TARGET); | |||
tex = screen->texture_create(screen, | |||
&templat); | |||
if (tex == NULL) | |||
exit(4); | |||
surf = screen->get_tex_surface(screen, tex, 0, 0, 0, | |||
PIPE_TEXTURE_USAGE_RENDER_TARGET | | |||
PIPE_TEXTURE_USAGE_DISPLAY_TARGET); | |||
if (surf == NULL) | |||
exit(5); | |||
memset(&fb, 0, sizeof fb); | |||
fb.nr_cbufs = 1; | |||
fb.width = WIDTH; | |||
fb.height = HEIGHT; | |||
fb.cbufs[0] = surf; | |||
pipe->set_framebuffer_state(pipe, &fb); | |||
pipe->clear(pipe, PIPE_CLEAR_COLOR, clear_color, 0, 0); | |||
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); | |||
screen->flush_frontbuffer(screen, surf, window); | |||
sleep(100); | |||
return 0; | |||
} |
@@ -0,0 +1,10 @@ | |||
# Meta-driver which combines whichever software rasterizers have been | |||
# built into a single convenience library. | |||
TOP = ../../../.. | |||
include $(TOP)/configs/current | |||
C_SOURCES = \ | |||
sw.c | |||
include ../../Makefile.template |
@@ -0,0 +1,42 @@ | |||
####################################################################### | |||
# SConscript for swrast convenience library | |||
# | |||
# This is a meta-driver which consists of any and all of the software | |||
# rasterizers into a single driver. A software rasterizer is defined | |||
# as any driver which takes an sw_winsys pointer as the only argument | |||
# to create_screen. | |||
# | |||
# XXX: unfortunately users of this driver still need to link in any | |||
# extra libraries needed for the particular driver (eg llvm for | |||
# llvmpipe). Not sure how to get around this. | |||
Import('*') | |||
if not set(('softpipe', 'llvmpipe', 'cell')).intersection(env['drivers']): | |||
print 'warning: no supported pipe driver: skipping build of sw meta-driver' | |||
Return() | |||
env = env.Clone() | |||
if 'softpipe' in env['drivers']: | |||
env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE') | |||
env.Prepend(LIBS = [softpipe]) | |||
if 'llvmpipe' in env['drivers']: | |||
env.Tool('llvm') | |||
if 'LLVM_VERSION' in env: | |||
env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE') | |||
env.Tool('udis86') | |||
env.Prepend(LIBS = [llvmpipe]) | |||
if 'cell' in env['drivers']: | |||
env.Append(CPPDEFINES = 'GALLIUM_CELL') | |||
env.Prepend(LIBS = [cell]) | |||
sw = env.ConvenienceLibrary( | |||
target = 'sw', | |||
source = [ | |||
'sw.c', | |||
] | |||
) | |||
Export('sw') |
@@ -0,0 +1,59 @@ | |||
#include "pipe/p_compiler.h" | |||
#include "util/u_debug.h" | |||
#include "target-helpers/wrap_screen.h" | |||
#include "sw_public.h" | |||
#include "state_tracker/sw_winsys.h" | |||
/* Helper function to choose and instantiate one of the software rasterizers: | |||
* cell, llvmpipe, softpipe. | |||
*/ | |||
#ifdef GALLIUM_SOFTPIPE | |||
#include "softpipe/sp_public.h" | |||
#endif | |||
#ifdef GALLIUM_LLVMPIPE | |||
#include "llvmpipe/lp_public.h" | |||
#endif | |||
#ifdef GALLIUM_CELL | |||
#include "cell/ppu/cell_public.h" | |||
#endif | |||
struct pipe_screen * | |||
swrast_create_screen(struct sw_winsys *winsys) | |||
{ | |||
const char *default_driver; | |||
const char *driver; | |||
struct pipe_screen *screen = NULL; | |||
#if defined(GALLIUM_CELL) | |||
default_driver = "cell"; | |||
#elif defined(GALLIUM_LLVMPIPE) | |||
default_driver = "llvmpipe"; | |||
#elif defined(GALLIUM_SOFTPIPE) | |||
default_driver = "softpipe"; | |||
#else | |||
default_driver = ""; | |||
#endif | |||
driver = debug_get_option("GALLIUM_DRIVER", default_driver); | |||
#if defined(GALLIUM_CELL) | |||
if (screen == NULL && strcmp(driver, "cell") == 0) | |||
screen = cell_create_screen( winsys ); | |||
#endif | |||
#if defined(GALLIUM_LLVMPIPE) | |||
if (screen == NULL && strcmp(driver, "llvmpipe") == 0) | |||
screen = llvmpipe_create_screen( winsys ); | |||
#endif | |||
#if defined(GALLIUM_SOFTPIPE) | |||
if (screen == NULL) | |||
screen = softpipe_create_screen( winsys ); | |||
#endif | |||
return screen; | |||
} |
@@ -0,0 +1,13 @@ | |||
#ifndef SW_PUBLIC_H | |||
#define SW_PUBLIC_H | |||
/* A convenience library, primarily to isolate the logic required to | |||
* figure out which if any software rasterizers have been built and | |||
* select between them. | |||
*/ | |||
struct sw_winsys; | |||
struct pipe_screen * | |||
swrast_create_screen(struct sw_winsys *winsys); | |||
#endif |
@@ -0,0 +1,36 @@ | |||
#ifndef GALLIUM_RAW_H | |||
#define GALLIUM_RAW_H | |||
/* This is an API for exercising gallium functionality in a | |||
* platform-neutral fashion. Whatever platform integration is | |||
* necessary to implement this interface is orchestrated by the | |||
* individual target building this entity. | |||
* | |||
* For instance, the graw-xlib target includes code to implent these | |||
* interfaces on top of the X window system. | |||
* | |||
* Programs using this interface may additionally benefit from some of | |||
* the utilities currently in the libgallium.a library, especially | |||
* those for parsing text representations of TGSI shaders. | |||
*/ | |||
#include "pipe/p_format.h" | |||
struct pipe_screen; | |||
struct pipe_screen *graw_init( void ); | |||
/* Returns a handle to be used with flush_frontbuffer()/present(). | |||
* | |||
* Query format support with screen::is_format_supported and usage | |||
* XXX. | |||
*/ | |||
void *graw_create_window( int x, | |||
int y, | |||
unsigned width, | |||
unsigned height, | |||
enum pipe_format format ); | |||
void graw_destroy_window( void *handle ); | |||
#endif |
@@ -10,6 +10,11 @@ if 'gdi' in env['winsys']: | |||
'libgl-gdi/SConscript', | |||
]) | |||
if 'graw-xlib' in env['winsys']: | |||
SConscript([ | |||
'graw-xlib/SConscript', | |||
]) | |||
if env['dri']: | |||
SConscript([ | |||
'SConscript.dri' |
@@ -0,0 +1,57 @@ | |||
####################################################################### | |||
# SConscript for xlib winsys | |||
Import('*') | |||
if env['platform'] != 'linux': | |||
Return() | |||
if not set(('softpipe', 'llvmpipe', 'cell')).intersection(env['drivers']): | |||
print 'warning: no supported pipe driver: skipping build of xlib libGL.so' | |||
Return() | |||
env = env.Clone() | |||
env.Prepend(LIBS = [ | |||
ws_xlib, | |||
trace, | |||
identity, | |||
# gallium, | |||
]) | |||
env.Append(CPPPATH = [ | |||
'#src/gallium/drivers', | |||
]) | |||
sources = [ | |||
'graw_xlib.c', | |||
] | |||
if 'softpipe' in env['drivers']: | |||
env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE') | |||
env.Prepend(LIBS = [softpipe]) | |||
if 'llvmpipe' in env['drivers']: | |||
env.Tool('llvm') | |||
if 'LLVM_VERSION' in env: | |||
env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE') | |||
env.Tool('udis86') | |||
env.Prepend(LIBS = [llvmpipe]) | |||
# Need this for trace, identity drivers referenced by | |||
# gallium_wrap_screen(). | |||
# | |||
env.Prepend(LIBS = [gallium]) | |||
# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions | |||
graw = env.SharedLibrary( | |||
target ='graw', | |||
source = sources, | |||
) | |||
env.InstallSharedLibrary(graw, version=(1, 0)) | |||
graw = env.FindIxes(graw, 'SHLIBPREFIX', 'SHLIBSUFFIX') | |||
Export('graw') |
@@ -0,0 +1,36 @@ | |||
#ifndef GALLIUM_RAW_H | |||
#define GALLIUM_RAW_H | |||
/* This is an API for exercising gallium functionality in a | |||
* platform-neutral fashion. Whatever platform integration is | |||
* necessary to implement this interface is orchestrated by the | |||
* individual target building this entity. | |||
* | |||
* For instance, the graw-xlib target includes code to implent these | |||
* interfaces on top of the X window system. | |||
* | |||
* Programs using this interface may additionally benefit from some of | |||
* the utilities currently in the libgallium.a library, especially | |||
* those for parsing text representations of TGSI shaders. | |||
*/ | |||
#include "pipe/p_format.h" | |||
struct pipe_screen; | |||
struct pipe_screen *graw_init( void ); | |||
/* Returns a handle to be used with flush_frontbuffer()/present(). | |||
* | |||
* Query format support with screen::is_format_supported and usage | |||
* XXX. | |||
*/ | |||
void *graw_create_window( int x, | |||
int y, | |||
unsigned width, | |||
unsigned height, | |||
enum pipe_format format ); | |||
void graw_destroy_window( void *handle ); | |||
#endif |
@@ -0,0 +1,181 @@ | |||
#include "pipe/p_compiler.h" | |||
#include "util/u_debug.h" | |||
#include "util/u_memory.h" | |||
#include "target-helpers/wrap_screen.h" | |||
#include "state_tracker/xlib_sw_winsys.h" | |||
#ifdef GALLIUM_SOFTPIPE | |||
#include "softpipe/sp_public.h" | |||
#endif | |||
#ifdef GALLIUM_LLVMPIPE | |||
#include "llvmpipe/lp_public.h" | |||
#endif | |||
/* Haven't figured out a decent way to build the helper code yet - | |||
* #include it here temporarily. | |||
*/ | |||
#include "sw/sw_public.h" | |||
#include "sw/sw.c" | |||
#include "graw.h" | |||
#include <X11/Xlib.h> | |||
#include <X11/Xlibint.h> | |||
#include <X11/Xutil.h> | |||
#include <stdio.h> | |||
static struct { | |||
Display *display; | |||
} graw; | |||
struct pipe_screen * | |||
graw_init( void ) | |||
{ | |||
const char *default_driver; | |||
const char *driver; | |||
struct pipe_screen *screen = NULL; | |||
struct sw_winsys *winsys = NULL; | |||
graw.display = XOpenDisplay(NULL); | |||
if (graw.display == NULL) | |||
return NULL; | |||
/* Create the underlying winsys, which performs presents to Xlib | |||
* drawables: | |||
*/ | |||
winsys = xlib_create_sw_winsys( graw.display ); | |||
if (winsys == NULL) | |||
return NULL; | |||
#if defined(GALLIUM_LLVMPIPE) | |||
default_driver = "llvmpipe"; | |||
#elif defined(GALLIUM_SOFTPIPE) | |||
default_driver = "softpipe"; | |||
#else | |||
default_driver = ""; | |||
#endif | |||
driver = debug_get_option("GALLIUM_DRIVER", default_driver); | |||
#if defined(GALLIUM_LLVMPIPE) | |||
if (screen == NULL && strcmp(driver, "llvmpipe") == 0) | |||
screen = llvmpipe_create_screen( winsys ); | |||
#endif | |||
#if defined(GALLIUM_SOFTPIPE) | |||
if (screen == NULL) | |||
screen = softpipe_create_screen( winsys ); | |||
#endif | |||
/* Inject any wrapping layers we want to here: | |||
*/ | |||
return gallium_wrap_screen( screen ); | |||
} | |||
void * | |||
graw_create_window( int x, | |||
int y, | |||
unsigned width, | |||
unsigned height, | |||
enum pipe_format format ) | |||
{ | |||
struct xlib_drawable *handle = NULL; | |||
XSetWindowAttributes attr; | |||
Window root; | |||
Window win = 0; | |||
XVisualInfo templat, *visinfo = NULL; | |||
unsigned mask; | |||
int n; | |||
int scrnum; | |||
scrnum = DefaultScreen( graw.display ); | |||
root = RootWindow( graw.display, scrnum ); | |||
if (format != PIPE_FORMAT_R8G8B8A8_UNORM) | |||
goto fail; | |||
if (graw.display == NULL) | |||
goto fail; | |||
handle = CALLOC_STRUCT(xlib_drawable); | |||
if (handle == NULL) | |||
goto fail; | |||
mask = VisualScreenMask | VisualDepthMask | VisualClassMask; | |||
templat.screen = DefaultScreen(graw.display); | |||
templat.depth = 32; | |||
templat.class = TrueColor; | |||
visinfo = XGetVisualInfo(graw.display, mask, &templat, &n); | |||
if (!visinfo) { | |||
printf("Error: couldn't get an RGB, Double-buffered visual\n"); | |||
exit(1); | |||
} | |||
/* window attributes */ | |||
attr.background_pixel = 0; | |||
attr.border_pixel = 0; | |||
attr.colormap = XCreateColormap( graw.display, root, visinfo->visual, AllocNone); | |||
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; | |||
/* XXX this is a bad way to get a borderless window! */ | |||
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; | |||
win = XCreateWindow( graw.display, root, x, y, width, height, | |||
0, visinfo->depth, InputOutput, | |||
visinfo->visual, mask, &attr ); | |||
/* set hints and properties */ | |||
{ | |||
char *name = NULL; | |||
XSizeHints sizehints; | |||
sizehints.x = x; | |||
sizehints.y = y; | |||
sizehints.width = width; | |||
sizehints.height = height; | |||
sizehints.flags = USSize | USPosition; | |||
XSetNormalHints(graw.display, win, &sizehints); | |||
XSetStandardProperties(graw.display, win, name, name, | |||
None, (char **)NULL, 0, &sizehints); | |||
} | |||
XFree(visinfo); | |||
XMapWindow(graw.display, win); | |||
while (1) { | |||
XEvent e; | |||
XNextEvent( graw.display, &e ); | |||
if (e.type == MapNotify && e.xmap.window == win) { | |||
break; | |||
} | |||
} | |||
handle->visual = visinfo->visual; | |||
handle->drawable = (Drawable)win; | |||
handle->depth = visinfo->depth; | |||
return (void *)handle; | |||
fail: | |||
FREE(handle); | |||
XFree(visinfo); | |||
if (win) | |||
XDestroyWindow(graw.display, win); | |||
return NULL; | |||
} | |||
void | |||
graw_destroy_window( void *xlib_drawable ) | |||
{ | |||
} | |||