summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/llvmpipe
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@vmware.com>2009-08-29 20:02:25 +0100
committerJosé Fonseca <jfonseca@vmware.com>2009-08-29 20:03:44 +0100
commite173a9bbd64dc38dba6b881ed7a9faea02861042 (patch)
tree292a49f533f73d0da2b222e8900a47fcbf2f8404 /src/gallium/drivers/llvmpipe
parente48dc9c5edb0f001bf7252ee2294d36707aa066c (diff)
llvmpipe: Define an winsys for LLVM. Drop pipe_winsys
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.
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
-rw-r--r--src/gallium/drivers/llvmpipe/SConscript1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_draw_arrays.c10
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c53
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.h5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c106
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.h13
-rw-r--r--src/gallium/drivers/llvmpipe/lp_winsys.h87
7 files changed, 196 insertions, 79 deletions
diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript
index 26bf8b08fb..6bceb84da4 100644
--- a/src/gallium/drivers/llvmpipe/SConscript
+++ b/src/gallium/drivers/llvmpipe/SConscript
@@ -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',
diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
index 6a89b74e3a..0f75afc79b 100644
--- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
+++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
@@ -47,13 +47,13 @@
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;
}
}
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index f302b99ad7..125035771e 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -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);
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.h b/src/gallium/drivers/llvmpipe/lp_screen.h
index 98d2789159..4a1b4d6f3e 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.h
+++ b/src/gallium/drivers/llvmpipe/lp_screen.h
@@ -43,10 +43,15 @@
#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;
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 18e348d69e..724d437833 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -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;
-}
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h
index a1ed6b0ac2..00a20763e4 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.h
+++ b/src/gallium/drivers/llvmpipe/lp_texture.h
@@ -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;
};
diff --git a/src/gallium/drivers/llvmpipe/lp_winsys.h b/src/gallium/drivers/llvmpipe/lp_winsys.h
index 268336b690..595481c2cb 100644
--- a/src/gallium/drivers/llvmpipe/lp_winsys.h
+++ b/src/gallium/drivers/llvmpipe/lp_winsys.h
@@ -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.
*/
@@ -35,27 +35,90 @@
#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