mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 05:28:05 +02:00
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.
This commit is contained in:
parent
e48dc9c5ed
commit
e173a9bbd6
7 changed files with 197 additions and 80 deletions
|
|
@ -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 pipe_buffer *buffer;
|
||||
struct llvmpipe_displaytarget *dt;
|
||||
|
||||
/**
|
||||
* Malloc'ed data for regular textures, or a mapping to dt above.
|
||||
*/
|
||||
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;
|
||||
|
||||
|
||||
/**
|
||||
* 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 * );
|
||||
|
||||
|
||||
struct pipe_screen *
|
||||
llvmpipe_create_screen(struct pipe_winsys *);
|
||||
|
||||
|
||||
boolean
|
||||
llvmpipe_get_texture_buffer( struct pipe_texture *texture,
|
||||
struct pipe_buffer **buf,
|
||||
unsigned *stride );
|
||||
llvmpipe_create_screen( struct llvmpipe_winsys * );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue