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.tags/mesa_7_6_rc1
@@ -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', |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
@@ -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; |
@@ -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; | |||
} |
@@ -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; | |||
}; |
@@ -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 |