softpipe: rework to use the llvmpipe winsys
Promote the llvmpipe winsys more or less unchanged to state_trackers/sw_winsys.h. Some minor breakages: - softpipe::texture_blanket is broken, but scheduled for removal anyway. - haven't fixed up g3vdl yet.
This commit is contained in:
@@ -167,7 +167,7 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
|
||||
unsigned geom_flags )
|
||||
{
|
||||
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
|
||||
struct llvmpipe_winsys *winsys = screen->winsys;
|
||||
struct sw_winsys *winsys = screen->winsys;
|
||||
const struct util_format_description *format_desc;
|
||||
|
||||
format_desc = util_format_description(format);
|
||||
@@ -258,7 +258,7 @@ llvmpipe_flush_frontbuffer(struct pipe_screen *_screen,
|
||||
void *context_private)
|
||||
{
|
||||
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
|
||||
struct llvmpipe_winsys *winsys = screen->winsys;
|
||||
struct sw_winsys *winsys = screen->winsys;
|
||||
struct llvmpipe_texture *texture = llvmpipe_texture(surface->texture);
|
||||
|
||||
assert(texture->dt);
|
||||
@@ -271,7 +271,7 @@ static void
|
||||
llvmpipe_destroy_screen( struct pipe_screen *_screen )
|
||||
{
|
||||
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
|
||||
struct llvmpipe_winsys *winsys = screen->winsys;
|
||||
struct sw_winsys *winsys = screen->winsys;
|
||||
|
||||
lp_jit_screen_cleanup(screen);
|
||||
|
||||
@@ -288,7 +288,7 @@ 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 llvmpipe_winsys *winsys)
|
||||
llvmpipe_create_screen(struct sw_winsys *winsys)
|
||||
{
|
||||
struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen);
|
||||
|
||||
|
@@ -43,14 +43,14 @@
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
|
||||
struct llvmpipe_winsys;
|
||||
struct sw_winsys;
|
||||
|
||||
|
||||
struct llvmpipe_screen
|
||||
{
|
||||
struct pipe_screen base;
|
||||
|
||||
struct llvmpipe_winsys *winsys;
|
||||
struct sw_winsys *winsys;
|
||||
|
||||
LLVMModuleRef module;
|
||||
LLVMExecutionEngineRef engine;
|
||||
|
@@ -479,7 +479,7 @@ lp_setup_set_sampler_textures( struct setup_context *setup,
|
||||
*/
|
||||
|
||||
struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
|
||||
struct llvmpipe_winsys *winsys = screen->winsys;
|
||||
struct sw_winsys *winsys = screen->winsys;
|
||||
jit_tex->data = winsys->displaytarget_map(winsys, lp_tex->dt,
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
assert(jit_tex->data);
|
||||
|
@@ -93,7 +93,7 @@ static boolean
|
||||
llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
|
||||
struct llvmpipe_texture *lpt)
|
||||
{
|
||||
struct llvmpipe_winsys *winsys = screen->winsys;
|
||||
struct sw_winsys *winsys = screen->winsys;
|
||||
|
||||
/* Round up the surface size to a multiple of the tile size to
|
||||
* avoid tile clipping.
|
||||
@@ -187,7 +187,7 @@ llvmpipe_texture_destroy(struct pipe_texture *pt)
|
||||
|
||||
if (lpt->dt) {
|
||||
/* display target */
|
||||
struct llvmpipe_winsys *winsys = screen->winsys;
|
||||
struct sw_winsys *winsys = screen->winsys;
|
||||
winsys->displaytarget_destroy(winsys, lpt->dt);
|
||||
}
|
||||
else {
|
||||
@@ -357,7 +357,7 @@ llvmpipe_transfer_map( struct pipe_screen *_screen,
|
||||
|
||||
if (lpt->dt) {
|
||||
/* display target */
|
||||
struct llvmpipe_winsys *winsys = screen->winsys;
|
||||
struct sw_winsys *winsys = screen->winsys;
|
||||
|
||||
map = winsys->displaytarget_map(winsys, lpt->dt,
|
||||
pipe_transfer_buffer_flags(transfer));
|
||||
@@ -398,7 +398,7 @@ llvmpipe_transfer_unmap(struct pipe_screen *screen,
|
||||
|
||||
if (lpt->dt) {
|
||||
/* display target */
|
||||
struct llvmpipe_winsys *winsys = lp_screen->winsys;
|
||||
struct sw_winsys *winsys = lp_screen->winsys;
|
||||
winsys->displaytarget_unmap(winsys, lpt->dt);
|
||||
}
|
||||
}
|
||||
|
@@ -35,7 +35,8 @@
|
||||
struct pipe_context;
|
||||
struct pipe_screen;
|
||||
struct llvmpipe_context;
|
||||
struct llvmpipe_displaytarget;
|
||||
|
||||
struct sw_displaytarget;
|
||||
|
||||
|
||||
struct llvmpipe_texture
|
||||
@@ -49,7 +50,7 @@ struct llvmpipe_texture
|
||||
* Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET
|
||||
* usage.
|
||||
*/
|
||||
struct llvmpipe_displaytarget *dt;
|
||||
struct sw_displaytarget *dt;
|
||||
|
||||
/**
|
||||
* Malloc'ed data for regular textures, or a mapping to dt above.
|
||||
|
@@ -6,6 +6,7 @@ LIBNAME = softpipe
|
||||
C_SOURCES = \
|
||||
sp_fs_exec.c \
|
||||
sp_fs_sse.c \
|
||||
sp_buffer.c \
|
||||
sp_clear.c \
|
||||
sp_flush.c \
|
||||
sp_query.c \
|
||||
@@ -32,7 +33,6 @@ C_SOURCES = \
|
||||
sp_tex_tile_cache.c \
|
||||
sp_tile_cache.c \
|
||||
sp_surface.c \
|
||||
sp_video_context.c \
|
||||
sp_winsys.c
|
||||
sp_video_context.c
|
||||
|
||||
include ../../Makefile.template
|
||||
|
@@ -7,6 +7,7 @@ softpipe = env.ConvenienceLibrary(
|
||||
source = [
|
||||
'sp_fs_exec.c',
|
||||
'sp_fs_sse.c',
|
||||
'sp_buffer.c',
|
||||
'sp_clear.c',
|
||||
'sp_context.c',
|
||||
'sp_draw_arrays.c',
|
||||
@@ -33,8 +34,7 @@ softpipe = env.ConvenienceLibrary(
|
||||
'sp_tex_tile_cache.c',
|
||||
'sp_texture.c',
|
||||
'sp_tile_cache.c',
|
||||
'sp_video_context.c',
|
||||
'sp_winsys.c'
|
||||
'sp_video_context.c'
|
||||
])
|
||||
|
||||
Export('softpipe')
|
||||
|
118
src/gallium/drivers/softpipe/sp_buffer.c
Normal file
118
src/gallium/drivers/softpipe/sp_buffer.c
Normal file
@@ -0,0 +1,118 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* 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 above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* 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 VMWARE 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
#include "sp_screen.h"
|
||||
#include "sp_buffer.h"
|
||||
|
||||
|
||||
static void *
|
||||
softpipe_buffer_map(struct pipe_screen *screen,
|
||||
struct pipe_buffer *buf,
|
||||
unsigned flags)
|
||||
{
|
||||
struct softpipe_buffer *softpipe_buf = softpipe_buffer(buf);
|
||||
return softpipe_buf->data;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
softpipe_buffer_unmap(struct pipe_screen *screen,
|
||||
struct pipe_buffer *buf)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
softpipe_buffer_destroy(struct pipe_buffer *buf)
|
||||
{
|
||||
struct softpipe_buffer *sbuf = softpipe_buffer(buf);
|
||||
|
||||
if (!sbuf->userBuffer)
|
||||
align_free(sbuf->data);
|
||||
|
||||
FREE(sbuf);
|
||||
}
|
||||
|
||||
|
||||
static struct pipe_buffer *
|
||||
softpipe_buffer_create(struct pipe_screen *screen,
|
||||
unsigned alignment,
|
||||
unsigned usage,
|
||||
unsigned size)
|
||||
{
|
||||
struct softpipe_buffer *buffer = CALLOC_STRUCT(softpipe_buffer);
|
||||
|
||||
pipe_reference_init(&buffer->base.reference, 1);
|
||||
buffer->base.screen = screen;
|
||||
buffer->base.alignment = MAX2(alignment, 16);
|
||||
buffer->base.usage = usage;
|
||||
buffer->base.size = size;
|
||||
|
||||
buffer->data = align_malloc(size, alignment);
|
||||
|
||||
return &buffer->base;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create buffer which wraps user-space data.
|
||||
*/
|
||||
static struct pipe_buffer *
|
||||
softpipe_user_buffer_create(struct pipe_screen *screen,
|
||||
void *ptr,
|
||||
unsigned bytes)
|
||||
{
|
||||
struct softpipe_buffer *buffer;
|
||||
|
||||
buffer = CALLOC_STRUCT(softpipe_buffer);
|
||||
if(!buffer)
|
||||
return NULL;
|
||||
|
||||
pipe_reference_init(&buffer->base.reference, 1);
|
||||
buffer->base.screen = screen;
|
||||
buffer->base.size = bytes;
|
||||
buffer->userBuffer = TRUE;
|
||||
buffer->data = ptr;
|
||||
|
||||
return &buffer->base;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
softpipe_init_screen_buffer_funcs(struct pipe_screen *screen)
|
||||
{
|
||||
screen->buffer_create = softpipe_buffer_create;
|
||||
screen->user_buffer_create = softpipe_user_buffer_create;
|
||||
screen->buffer_map = softpipe_buffer_map;
|
||||
screen->buffer_unmap = softpipe_buffer_unmap;
|
||||
screen->buffer_destroy = softpipe_buffer_destroy;
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -18,56 +18,38 @@
|
||||
* 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* IN NO EVENT SHALL VMWARE 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* This is the interface that softpipe requires any window system
|
||||
* hosting it to implement. This is the only include file in softpipe
|
||||
* which is public.
|
||||
*/
|
||||
#ifndef SP_BUFFER_H
|
||||
#define SP_BUFFER_H
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
|
||||
#ifndef SP_WINSYS_H
|
||||
#define SP_WINSYS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
struct pipe_screen;
|
||||
struct pipe_winsys;
|
||||
struct pipe_context;
|
||||
struct pipe_texture;
|
||||
struct pipe_buffer;
|
||||
struct softpipe_buffer
|
||||
{
|
||||
struct pipe_buffer base;
|
||||
boolean userBuffer; /** Is this a user-space buffer? */
|
||||
void *data;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a softpipe screen that uses the
|
||||
* given winsys for allocating buffers.
|
||||
*/
|
||||
struct pipe_screen *softpipe_create_screen( struct pipe_winsys * );
|
||||
|
||||
/**
|
||||
* Create a softpipe screen that uses
|
||||
* regular malloc to create all its buffers.
|
||||
*/
|
||||
struct pipe_screen *softpipe_create_screen_malloc(void);
|
||||
|
||||
boolean
|
||||
softpipe_get_texture_buffer( struct pipe_texture *texture,
|
||||
struct pipe_buffer **buf,
|
||||
unsigned *stride );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
/** Cast wrapper */
|
||||
static INLINE struct softpipe_buffer *
|
||||
softpipe_buffer( struct pipe_buffer *buf )
|
||||
{
|
||||
return (struct softpipe_buffer *)buf;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SP_WINSYS_H */
|
||||
|
||||
void
|
||||
softpipe_init_screen_buffer_funcs(struct pipe_screen *screen);
|
||||
|
||||
|
||||
#endif /* SP_BUFFER_H */
|
@@ -210,7 +210,7 @@ softpipe_create_context( struct pipe_screen *screen,
|
||||
softpipe->dump_fs = debug_get_bool_option( "GALLIUM_DUMP_FS", FALSE );
|
||||
softpipe->dump_gs = debug_get_bool_option( "SOFTPIPE_DUMP_GS", FALSE );
|
||||
|
||||
softpipe->pipe.winsys = screen->winsys;
|
||||
softpipe->pipe.winsys = NULL;
|
||||
softpipe->pipe.screen = screen;
|
||||
softpipe->pipe.destroy = softpipe_destroy;
|
||||
softpipe->pipe.priv = priv;
|
||||
|
@@ -40,83 +40,13 @@
|
||||
#include "sp_context.h"
|
||||
#include "sp_query.h"
|
||||
#include "sp_state.h"
|
||||
#include "sp_buffer.h"
|
||||
|
||||
#include "draw/draw_context.h"
|
||||
|
||||
|
||||
|
||||
static void
|
||||
softpipe_map_constant_buffers(struct softpipe_context *sp)
|
||||
{
|
||||
struct pipe_winsys *ws = sp->pipe.winsys;
|
||||
uint i;
|
||||
|
||||
for (i = 0; i < PIPE_SHADER_TYPES; i++) {
|
||||
uint j;
|
||||
|
||||
for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) {
|
||||
if (sp->constants[i][j] && sp->constants[i][j]->size) {
|
||||
sp->mapped_constants[i][j] = ws->buffer_map(ws,
|
||||
sp->constants[i][j],
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
|
||||
if (sp->constants[PIPE_SHADER_VERTEX][i]) {
|
||||
draw_set_mapped_constant_buffer(sp->draw,
|
||||
PIPE_SHADER_VERTEX,
|
||||
i,
|
||||
sp->mapped_constants[PIPE_SHADER_VERTEX][i],
|
||||
sp->constants[PIPE_SHADER_VERTEX][i]->size);
|
||||
}
|
||||
if (sp->constants[PIPE_SHADER_GEOMETRY][i]) {
|
||||
draw_set_mapped_constant_buffer(sp->draw,
|
||||
PIPE_SHADER_GEOMETRY,
|
||||
i,
|
||||
sp->mapped_constants[PIPE_SHADER_GEOMETRY][i],
|
||||
sp->constants[PIPE_SHADER_GEOMETRY][i]->size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
softpipe_unmap_constant_buffers(struct softpipe_context *sp)
|
||||
{
|
||||
struct pipe_winsys *ws = sp->pipe.winsys;
|
||||
uint i;
|
||||
|
||||
/* really need to flush all prims since the vert/frag shaders const buffers
|
||||
* are going away now.
|
||||
*/
|
||||
draw_flush(sp->draw);
|
||||
|
||||
for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
|
||||
draw_set_mapped_constant_buffer(sp->draw,
|
||||
PIPE_SHADER_VERTEX,
|
||||
i,
|
||||
NULL,
|
||||
0);
|
||||
draw_set_mapped_constant_buffer(sp->draw,
|
||||
PIPE_SHADER_GEOMETRY,
|
||||
i,
|
||||
NULL,
|
||||
0);
|
||||
}
|
||||
|
||||
for (i = 0; i < PIPE_SHADER_TYPES; i++) {
|
||||
uint j;
|
||||
|
||||
for (j = 0; j < PIPE_MAX_CONSTANT_BUFFERS; j++) {
|
||||
if (sp->constants[i][j] && sp->constants[i][j]->size) {
|
||||
ws->buffer_unmap(ws, sp->constants[i][j]);
|
||||
}
|
||||
sp->mapped_constants[i][j] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -261,25 +191,16 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
|
||||
}
|
||||
|
||||
softpipe_map_transfers(sp);
|
||||
softpipe_map_constant_buffers(sp);
|
||||
|
||||
/* Map vertex buffers */
|
||||
for (i = 0; i < sp->num_vertex_buffers; i++) {
|
||||
void *buf;
|
||||
|
||||
buf = pipe_buffer_map(pipe->screen,
|
||||
sp->vertex_buffer[i].buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
void *buf = softpipe_buffer(sp->vertex_buffer[i].buffer)->data;
|
||||
draw_set_mapped_vertex_buffer(draw, i, buf);
|
||||
}
|
||||
|
||||
/* Map index buffer, if present */
|
||||
if (indexBuffer) {
|
||||
void *mapped_indexes;
|
||||
|
||||
mapped_indexes = pipe_buffer_map(pipe->screen,
|
||||
indexBuffer,
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
void *mapped_indexes = softpipe_buffer(indexBuffer)->data;
|
||||
draw_set_mapped_element_buffer_range(draw,
|
||||
indexSize,
|
||||
minIndex,
|
||||
@@ -300,15 +221,18 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
|
||||
/* unmap vertex/index buffers - will cause draw module to flush */
|
||||
for (i = 0; i < sp->num_vertex_buffers; i++) {
|
||||
draw_set_mapped_vertex_buffer(draw, i, NULL);
|
||||
pipe_buffer_unmap(pipe->screen, sp->vertex_buffer[i].buffer);
|
||||
}
|
||||
if (indexBuffer) {
|
||||
draw_set_mapped_element_buffer(draw, 0, NULL);
|
||||
pipe_buffer_unmap(pipe->screen, indexBuffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Flush only when a user vertex/index buffer is present
|
||||
* (or even better, modify draw module to do this
|
||||
* internally when this condition is seen?)
|
||||
*/
|
||||
draw_flush(draw);
|
||||
|
||||
/* Note: leave drawing surfaces mapped */
|
||||
softpipe_unmap_constant_buffers(sp);
|
||||
|
||||
sp->dirty_render_cache = TRUE;
|
||||
}
|
||||
|
@@ -32,10 +32,12 @@
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_screen.h"
|
||||
|
||||
#include "state_tracker/sw_winsys.h"
|
||||
|
||||
#include "sp_texture.h"
|
||||
#include "sp_winsys.h"
|
||||
#include "sp_screen.h"
|
||||
#include "sp_context.h"
|
||||
#include "sp_buffer.h"
|
||||
|
||||
|
||||
static const char *
|
||||
@@ -145,6 +147,8 @@ softpipe_is_format_supported( struct pipe_screen *screen,
|
||||
unsigned tex_usage,
|
||||
unsigned geom_flags )
|
||||
{
|
||||
struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
|
||||
|
||||
assert(target == PIPE_TEXTURE_1D ||
|
||||
target == PIPE_TEXTURE_2D ||
|
||||
target == PIPE_TEXTURE_3D ||
|
||||
@@ -166,15 +170,25 @@ softpipe_is_format_supported( struct pipe_screen *screen,
|
||||
case PIPE_FORMAT_NONE:
|
||||
return FALSE;
|
||||
default:
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
|
||||
if(!winsys->is_displaytarget_format_supported(winsys, format))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* XXX: this is often a lie. Pull in logic from llvmpipe to fix.
|
||||
*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
softpipe_destroy_screen( struct pipe_screen *screen )
|
||||
{
|
||||
struct pipe_winsys *winsys = screen->winsys;
|
||||
struct softpipe_screen *sp_screen = softpipe_screen(screen);
|
||||
struct sw_winsys *winsys = sp_screen->winsys;
|
||||
|
||||
if(winsys->destroy)
|
||||
winsys->destroy(winsys);
|
||||
@@ -183,21 +197,37 @@ softpipe_destroy_screen( struct pipe_screen *screen )
|
||||
}
|
||||
|
||||
|
||||
/* This is often overriden by the co-state tracker.
|
||||
*/
|
||||
static void
|
||||
softpipe_flush_frontbuffer(struct pipe_screen *_screen,
|
||||
struct pipe_surface *surface,
|
||||
void *context_private)
|
||||
{
|
||||
struct softpipe_screen *screen = softpipe_screen(_screen);
|
||||
struct sw_winsys *winsys = screen->winsys;
|
||||
struct softpipe_texture *texture = softpipe_texture(surface->texture);
|
||||
|
||||
assert(texture->dt);
|
||||
if (texture->dt)
|
||||
winsys->displaytarget_display(winsys, texture->dt, context_private);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new pipe_screen object
|
||||
* Note: we're not presently subclassing pipe_screen (no softpipe_screen).
|
||||
*/
|
||||
struct pipe_screen *
|
||||
softpipe_create_screen(struct pipe_winsys *winsys)
|
||||
softpipe_create_screen(struct sw_winsys *winsys)
|
||||
{
|
||||
struct softpipe_screen *screen = CALLOC_STRUCT(softpipe_screen);
|
||||
|
||||
if (!screen)
|
||||
return NULL;
|
||||
|
||||
screen->base.winsys = winsys;
|
||||
screen->winsys = winsys;
|
||||
|
||||
screen->base.winsys = NULL;
|
||||
screen->base.destroy = softpipe_destroy_screen;
|
||||
|
||||
screen->base.get_name = softpipe_get_name;
|
||||
@@ -206,9 +236,10 @@ softpipe_create_screen(struct pipe_winsys *winsys)
|
||||
screen->base.get_paramf = softpipe_get_paramf;
|
||||
screen->base.is_format_supported = softpipe_is_format_supported;
|
||||
screen->base.context_create = softpipe_create_context;
|
||||
screen->base.flush_frontbuffer = softpipe_flush_frontbuffer;
|
||||
|
||||
softpipe_init_screen_texture_funcs(&screen->base);
|
||||
u_simple_screen_init(&screen->base);
|
||||
softpipe_init_screen_buffer_funcs(&screen->base);
|
||||
|
||||
return &screen->base;
|
||||
}
|
||||
|
@@ -35,10 +35,13 @@
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
|
||||
struct sw_winsys;
|
||||
|
||||
struct softpipe_screen {
|
||||
struct pipe_screen base;
|
||||
|
||||
struct sw_winsys *winsys;
|
||||
|
||||
/* Increments whenever textures are modified. Contexts can track
|
||||
* this.
|
||||
*/
|
||||
@@ -55,4 +58,13 @@ softpipe_screen( struct pipe_screen *pipe )
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a softpipe screen that uses the
|
||||
* given winsys for allocating buffers.
|
||||
*/
|
||||
struct pipe_screen *softpipe_create_screen( struct sw_winsys * );
|
||||
|
||||
|
||||
|
||||
#endif /* SP_SCREEN_H */
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include "sp_context.h"
|
||||
#include "sp_state.h"
|
||||
#include "sp_fs.h"
|
||||
#include "sp_buffer.h"
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_memory.h"
|
||||
@@ -163,26 +164,35 @@ softpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
|
||||
FREE( state );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
softpipe_set_constant_buffer(struct pipe_context *pipe,
|
||||
uint shader, uint index,
|
||||
struct pipe_buffer *buf)
|
||||
struct pipe_buffer *constants)
|
||||
{
|
||||
struct softpipe_context *softpipe = softpipe_context(pipe);
|
||||
unsigned size = constants ? constants->size : 0;
|
||||
const void *data = constants ? softpipe_buffer(constants)->data : NULL;
|
||||
|
||||
assert(shader < PIPE_SHADER_TYPES);
|
||||
assert(index < PIPE_MAX_CONSTANT_BUFFERS);
|
||||
assert(index == 0);
|
||||
|
||||
if(softpipe->constants[shader][index] == constants)
|
||||
return;
|
||||
|
||||
draw_flush(softpipe->draw);
|
||||
|
||||
/* note: reference counting */
|
||||
pipe_buffer_reference(&softpipe->constants[shader][index], buf);
|
||||
pipe_buffer_reference(&softpipe->constants[shader][index], constants);
|
||||
|
||||
if(shader == PIPE_SHADER_VERTEX) {
|
||||
draw_set_mapped_constant_buffer(softpipe->draw, PIPE_SHADER_VERTEX, 0,
|
||||
data, size);
|
||||
}
|
||||
|
||||
softpipe->dirty |= SP_NEW_CONSTANTS;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
softpipe_create_gs_state(struct pipe_context *pipe,
|
||||
const struct pipe_shader_state *templ)
|
||||
|
@@ -40,7 +40,8 @@
|
||||
#include "sp_context.h"
|
||||
#include "sp_texture.h"
|
||||
#include "sp_screen.h"
|
||||
#include "sp_winsys.h"
|
||||
|
||||
#include "state_tracker/sw_winsys.h"
|
||||
|
||||
|
||||
/**
|
||||
@@ -72,11 +73,9 @@ softpipe_texture_layout(struct pipe_screen *screen,
|
||||
depth = u_minify(depth, 1);
|
||||
}
|
||||
|
||||
spt->buffer = screen->buffer_create(screen, 32,
|
||||
PIPE_BUFFER_USAGE_PIXEL,
|
||||
buffer_size);
|
||||
spt->data = align_malloc(buffer_size, 16);
|
||||
|
||||
return spt->buffer != NULL;
|
||||
return spt->data != NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -87,19 +86,18 @@ static boolean
|
||||
softpipe_displaytarget_layout(struct pipe_screen *screen,
|
||||
struct softpipe_texture * spt)
|
||||
{
|
||||
unsigned usage = (PIPE_BUFFER_USAGE_CPU_READ_WRITE |
|
||||
PIPE_BUFFER_USAGE_GPU_READ_WRITE);
|
||||
unsigned tex_usage = spt->base.tex_usage;
|
||||
struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
|
||||
|
||||
spt->buffer = screen->surface_buffer_create( screen,
|
||||
/* Round up the surface size to a multiple of the tile size?
|
||||
*/
|
||||
spt->dt = winsys->displaytarget_create(winsys,
|
||||
spt->base.format,
|
||||
spt->base.width0,
|
||||
spt->base.height0,
|
||||
spt->base.format,
|
||||
usage,
|
||||
tex_usage,
|
||||
16,
|
||||
&spt->stride[0] );
|
||||
|
||||
return spt->buffer != NULL;
|
||||
return spt->dt != NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -149,37 +147,29 @@ softpipe_texture_blanket(struct pipe_screen * screen,
|
||||
const unsigned *stride,
|
||||
struct pipe_buffer *buffer)
|
||||
{
|
||||
struct softpipe_texture *spt;
|
||||
assert(screen);
|
||||
|
||||
/* Only supports one type */
|
||||
if (base->target != PIPE_TEXTURE_2D ||
|
||||
base->last_level != 0 ||
|
||||
base->depth0 != 1) {
|
||||
/* Texture blanket is going away.
|
||||
*/
|
||||
debug_printf("softpipe_texture_blanket() not implemented!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
spt = CALLOC_STRUCT(softpipe_texture);
|
||||
if (!spt)
|
||||
return NULL;
|
||||
|
||||
spt->base = *base;
|
||||
pipe_reference_init(&spt->base.reference, 1);
|
||||
spt->base.screen = screen;
|
||||
spt->stride[0] = stride[0];
|
||||
|
||||
pipe_buffer_reference(&spt->buffer, buffer);
|
||||
|
||||
return &spt->base;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
softpipe_texture_destroy(struct pipe_texture *pt)
|
||||
{
|
||||
struct softpipe_screen *screen = softpipe_screen(pt->screen);
|
||||
struct softpipe_texture *spt = softpipe_texture(pt);
|
||||
|
||||
pipe_buffer_reference(&spt->buffer, NULL);
|
||||
if (spt->dt) {
|
||||
/* display target */
|
||||
struct sw_winsys *winsys = screen->winsys;
|
||||
winsys->displaytarget_destroy(winsys, spt->dt);
|
||||
}
|
||||
else {
|
||||
/* regular texture */
|
||||
align_free(spt->data);
|
||||
}
|
||||
|
||||
FREE(spt);
|
||||
}
|
||||
|
||||
@@ -359,9 +349,20 @@ softpipe_transfer_map( struct pipe_screen *screen,
|
||||
spt = softpipe_texture(transfer->texture);
|
||||
format = transfer->texture->format;
|
||||
|
||||
map = pipe_buffer_map(screen, spt->buffer, pipe_transfer_buffer_flags(transfer));
|
||||
if (spt->dt) {
|
||||
/* display target */
|
||||
struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
|
||||
|
||||
map = winsys->displaytarget_map(winsys, spt->dt,
|
||||
pipe_transfer_buffer_flags(transfer));
|
||||
if (map == NULL)
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
map = spt->data;
|
||||
if (map == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* May want to different things here depending on read/write nature
|
||||
* of the map:
|
||||
@@ -393,7 +394,11 @@ softpipe_transfer_unmap(struct pipe_screen *screen,
|
||||
assert(transfer->texture);
|
||||
spt = softpipe_texture(transfer->texture);
|
||||
|
||||
pipe_buffer_unmap( screen, spt->buffer );
|
||||
if (spt->dt) {
|
||||
/* display target */
|
||||
struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
|
||||
winsys->displaytarget_unmap(winsys, spt->dt);
|
||||
}
|
||||
|
||||
if (transfer->usage & PIPE_TRANSFER_WRITE) {
|
||||
/* Mark the texture as dirty to expire the tile caches. */
|
||||
@@ -474,24 +479,4 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return pipe_buffer handle and stride for given texture object.
|
||||
* XXX used for???
|
||||
*/
|
||||
boolean
|
||||
softpipe_get_texture_buffer( struct pipe_texture *texture,
|
||||
struct pipe_buffer **buf,
|
||||
unsigned *stride )
|
||||
{
|
||||
struct softpipe_texture *tex = (struct softpipe_texture *) texture;
|
||||
|
||||
if (!tex)
|
||||
return FALSE;
|
||||
|
||||
pipe_buffer_reference(buf, tex->buffer);
|
||||
|
||||
if (stride)
|
||||
*stride = tex->stride[0];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -45,9 +45,16 @@ struct softpipe_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 sw_displaytarget *dt;
|
||||
|
||||
/**
|
||||
* Malloc'ed data for regular textures, or a mapping to dt above.
|
||||
*/
|
||||
void *data;
|
||||
|
||||
/* True if texture images are power-of-two in all dimensions:
|
||||
*/
|
||||
|
@@ -1,245 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
|
||||
* 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
|
||||
* Malloc softpipe winsys. Uses malloc for all memory allocations.
|
||||
*
|
||||
* @author Keith Whitwell
|
||||
* @author Brian Paul
|
||||
* @author Jose Fonseca
|
||||
*/
|
||||
|
||||
|
||||
#include "util/u_simple_screen.h"/* port to just p_screen */
|
||||
#include "util/u_format.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "pipe/p_format.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "sp_winsys.h"
|
||||
|
||||
|
||||
struct st_softpipe_buffer
|
||||
{
|
||||
struct pipe_buffer base;
|
||||
boolean userBuffer; /** Is this a user-space buffer? */
|
||||
void *data;
|
||||
void *mapped;
|
||||
};
|
||||
|
||||
|
||||
/** Cast wrapper */
|
||||
static INLINE struct st_softpipe_buffer *
|
||||
st_softpipe_buffer( struct pipe_buffer *buf )
|
||||
{
|
||||
return (struct st_softpipe_buffer *)buf;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
st_softpipe_buffer_map(struct pipe_winsys *winsys,
|
||||
struct pipe_buffer *buf,
|
||||
unsigned flags)
|
||||
{
|
||||
struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf);
|
||||
st_softpipe_buf->mapped = st_softpipe_buf->data;
|
||||
return st_softpipe_buf->mapped;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
st_softpipe_buffer_unmap(struct pipe_winsys *winsys,
|
||||
struct pipe_buffer *buf)
|
||||
{
|
||||
struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf);
|
||||
st_softpipe_buf->mapped = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
st_softpipe_buffer_destroy(struct pipe_buffer *buf)
|
||||
{
|
||||
struct st_softpipe_buffer *oldBuf = st_softpipe_buffer(buf);
|
||||
|
||||
if (oldBuf->data) {
|
||||
if (!oldBuf->userBuffer)
|
||||
align_free(oldBuf->data);
|
||||
|
||||
oldBuf->data = NULL;
|
||||
}
|
||||
|
||||
FREE(oldBuf);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
st_softpipe_flush_frontbuffer(struct pipe_winsys *winsys,
|
||||
struct pipe_surface *surf,
|
||||
void *context_private)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char *
|
||||
st_softpipe_get_name(struct pipe_winsys *winsys)
|
||||
{
|
||||
return "softpipe";
|
||||
}
|
||||
|
||||
|
||||
static struct pipe_buffer *
|
||||
st_softpipe_buffer_create(struct pipe_winsys *winsys,
|
||||
unsigned alignment,
|
||||
unsigned usage,
|
||||
unsigned size)
|
||||
{
|
||||
struct st_softpipe_buffer *buffer = CALLOC_STRUCT(st_softpipe_buffer);
|
||||
|
||||
pipe_reference_init(&buffer->base.reference, 1);
|
||||
buffer->base.alignment = alignment;
|
||||
buffer->base.usage = usage;
|
||||
buffer->base.size = size;
|
||||
|
||||
buffer->data = align_malloc(size, alignment);
|
||||
|
||||
return &buffer->base;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create buffer which wraps user-space data.
|
||||
*/
|
||||
static struct pipe_buffer *
|
||||
st_softpipe_user_buffer_create(struct pipe_winsys *winsys,
|
||||
void *ptr,
|
||||
unsigned bytes)
|
||||
{
|
||||
struct st_softpipe_buffer *buffer;
|
||||
|
||||
buffer = CALLOC_STRUCT(st_softpipe_buffer);
|
||||
if(!buffer)
|
||||
return NULL;
|
||||
|
||||
pipe_reference_init(&buffer->base.reference, 1);
|
||||
buffer->base.size = bytes;
|
||||
buffer->userBuffer = TRUE;
|
||||
buffer->data = ptr;
|
||||
|
||||
return &buffer->base;
|
||||
}
|
||||
|
||||
|
||||
static struct pipe_buffer *
|
||||
st_softpipe_surface_buffer_create(struct pipe_winsys *winsys,
|
||||
unsigned width, unsigned height,
|
||||
enum pipe_format format,
|
||||
unsigned usage,
|
||||
unsigned tex_usage,
|
||||
unsigned *stride)
|
||||
{
|
||||
const unsigned alignment = 64;
|
||||
unsigned nblocksy;
|
||||
|
||||
nblocksy = util_format_get_nblocksy(format, height);
|
||||
*stride = align(util_format_get_stride(format, width), alignment);
|
||||
|
||||
return winsys->buffer_create(winsys, alignment,
|
||||
usage,
|
||||
*stride * nblocksy);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
st_softpipe_fence_reference(struct pipe_winsys *winsys,
|
||||
struct pipe_fence_handle **ptr,
|
||||
struct pipe_fence_handle *fence)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
st_softpipe_fence_signalled(struct pipe_winsys *winsys,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
st_softpipe_fence_finish(struct pipe_winsys *winsys,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
st_softpipe_destroy(struct pipe_winsys *winsys)
|
||||
{
|
||||
FREE(winsys);
|
||||
}
|
||||
|
||||
|
||||
struct pipe_screen *
|
||||
softpipe_create_screen_malloc(void)
|
||||
{
|
||||
static struct pipe_winsys *winsys;
|
||||
struct pipe_screen *screen;
|
||||
|
||||
winsys = CALLOC_STRUCT(pipe_winsys);
|
||||
if(!winsys)
|
||||
return NULL;
|
||||
|
||||
winsys->destroy = st_softpipe_destroy;
|
||||
|
||||
winsys->buffer_create = st_softpipe_buffer_create;
|
||||
winsys->user_buffer_create = st_softpipe_user_buffer_create;
|
||||
winsys->buffer_map = st_softpipe_buffer_map;
|
||||
winsys->buffer_unmap = st_softpipe_buffer_unmap;
|
||||
winsys->buffer_destroy = st_softpipe_buffer_destroy;
|
||||
|
||||
winsys->surface_buffer_create = st_softpipe_surface_buffer_create;
|
||||
|
||||
winsys->fence_reference = st_softpipe_fence_reference;
|
||||
winsys->fence_signalled = st_softpipe_fence_signalled;
|
||||
winsys->fence_finish = st_softpipe_fence_finish;
|
||||
|
||||
winsys->flush_frontbuffer = st_softpipe_flush_frontbuffer;
|
||||
winsys->get_name = st_softpipe_get_name;
|
||||
|
||||
screen = softpipe_create_screen(winsys);
|
||||
if(!screen)
|
||||
st_softpipe_destroy(winsys);
|
||||
|
||||
return screen;
|
||||
}
|
@@ -27,12 +27,12 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* llvmpipe public interface.
|
||||
* Software rasterizer winsys.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LP_WINSYS_H
|
||||
#define LP_WINSYS_H
|
||||
#ifndef SW_WINSYS_H
|
||||
#define SW_WINSYS_H
|
||||
|
||||
|
||||
#include "pipe/p_compiler.h" /* for boolean */
|
||||
@@ -51,23 +51,23 @@ struct pipe_context;
|
||||
/**
|
||||
* Opaque pointer.
|
||||
*/
|
||||
struct llvmpipe_displaytarget;
|
||||
struct sw_displaytarget;
|
||||
|
||||
|
||||
/**
|
||||
* This is the interface that llvmpipe expects any window system
|
||||
* This is the interface that sw expects any window system
|
||||
* hosting it to implement.
|
||||
*
|
||||
* llvmpipe is for the most part a self sufficient driver. The only thing it
|
||||
* sw 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
|
||||
struct sw_winsys
|
||||
{
|
||||
void
|
||||
(*destroy)( struct llvmpipe_winsys *ws );
|
||||
(*destroy)( struct sw_winsys *ws );
|
||||
|
||||
boolean
|
||||
(*is_displaytarget_format_supported)( struct llvmpipe_winsys *ws,
|
||||
(*is_displaytarget_format_supported)( struct sw_winsys *ws,
|
||||
enum pipe_format format );
|
||||
|
||||
/**
|
||||
@@ -81,21 +81,21 @@ struct llvmpipe_winsys
|
||||
* with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET flag to get the underlying
|
||||
* storage.
|
||||
*/
|
||||
struct llvmpipe_displaytarget *
|
||||
(*displaytarget_create)( struct llvmpipe_winsys *ws,
|
||||
struct sw_displaytarget *
|
||||
(*displaytarget_create)( struct sw_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,
|
||||
(*displaytarget_map)( struct sw_winsys *ws,
|
||||
struct sw_displaytarget *dt,
|
||||
unsigned flags );
|
||||
|
||||
void
|
||||
(*displaytarget_unmap)( struct llvmpipe_winsys *ws,
|
||||
struct llvmpipe_displaytarget *dt );
|
||||
(*displaytarget_unmap)( struct sw_winsys *ws,
|
||||
struct sw_displaytarget *dt );
|
||||
|
||||
/**
|
||||
* @sa pipe_screen:flush_frontbuffer.
|
||||
@@ -103,23 +103,19 @@ struct llvmpipe_winsys
|
||||
* This call will likely become asynchronous eventually.
|
||||
*/
|
||||
void
|
||||
(*displaytarget_display)( struct llvmpipe_winsys *ws,
|
||||
struct llvmpipe_displaytarget *dt,
|
||||
(*displaytarget_display)( struct sw_winsys *ws,
|
||||
struct sw_displaytarget *dt,
|
||||
void *context_private );
|
||||
|
||||
void
|
||||
(*displaytarget_destroy)( struct llvmpipe_winsys *ws,
|
||||
struct llvmpipe_displaytarget *dt );
|
||||
(*displaytarget_destroy)( struct sw_winsys *ws,
|
||||
struct sw_displaytarget *dt );
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct pipe_screen *
|
||||
llvmpipe_create_screen( struct llvmpipe_winsys * );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LP_WINSYS_H */
|
||||
#endif /* SW_WINSYS_H */
|
@@ -18,7 +18,7 @@ if env['platform'] == 'windows':
|
||||
'ws2_32',
|
||||
])
|
||||
|
||||
sources = []
|
||||
sources = ['gdi_sw_winsys.c']
|
||||
drivers = []
|
||||
|
||||
if 'softpipe' in env['drivers']:
|
||||
|
@@ -36,153 +36,8 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "pipe/p_format.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_format.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "llvmpipe/lp_winsys.h"
|
||||
#include "gdi_winsys.h"
|
||||
#include "llvmpipe/lp_texture.h"
|
||||
#include "stw_winsys.h"
|
||||
|
||||
|
||||
struct gdi_llvmpipe_displaytarget
|
||||
{
|
||||
enum pipe_format format;
|
||||
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_B8G8R8X8_UNORM:
|
||||
case PIPE_FORMAT_B8G8R8A8_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);
|
||||
}
|
||||
|
||||
|
||||
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 = util_format_get_blocksizebits(format);
|
||||
cpp = util_format_get_blocksize(format);
|
||||
|
||||
gdt->stride = align(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 *
|
||||
@@ -191,18 +46,10 @@ gdi_llvmpipe_screen_create(void)
|
||||
static struct llvmpipe_winsys *winsys;
|
||||
struct pipe_screen *screen;
|
||||
|
||||
winsys = CALLOC_STRUCT(llvmpipe_winsys);
|
||||
winsys = gdi_create_sw_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;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 Tungsten Graphics, Inc., Bismarck, ND., USA
|
||||
* Copyright 2009 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -28,257 +28,58 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Softpipe support.
|
||||
* LLVMpipe support.
|
||||
*
|
||||
* @author Keith Whitwell
|
||||
* @author Brian Paul
|
||||
* @author Jose Fonseca
|
||||
* @author Jose Fonseca <jfonseca@vmware.com>
|
||||
*/
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "util/u_simple_screen.h"
|
||||
#include "pipe/p_format.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_format.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "softpipe/sp_winsys.h"
|
||||
#include "gdi_winsys.h"
|
||||
#include "softpipe/sp_texture.h"
|
||||
#include "stw_winsys.h"
|
||||
|
||||
|
||||
struct gdi_softpipe_buffer
|
||||
{
|
||||
struct pipe_buffer base;
|
||||
boolean userBuffer; /** Is this a user-space buffer? */
|
||||
void *data;
|
||||
void *mapped;
|
||||
};
|
||||
|
||||
|
||||
/** Cast wrapper */
|
||||
static INLINE struct gdi_softpipe_buffer *
|
||||
gdi_softpipe_buffer( struct pipe_buffer *buf )
|
||||
{
|
||||
return (struct gdi_softpipe_buffer *)buf;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
gdi_softpipe_buffer_map(struct pipe_winsys *winsys,
|
||||
struct pipe_buffer *buf,
|
||||
unsigned flags)
|
||||
{
|
||||
struct gdi_softpipe_buffer *gdi_softpipe_buf = gdi_softpipe_buffer(buf);
|
||||
gdi_softpipe_buf->mapped = gdi_softpipe_buf->data;
|
||||
return gdi_softpipe_buf->mapped;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gdi_softpipe_buffer_unmap(struct pipe_winsys *winsys,
|
||||
struct pipe_buffer *buf)
|
||||
{
|
||||
struct gdi_softpipe_buffer *gdi_softpipe_buf = gdi_softpipe_buffer(buf);
|
||||
gdi_softpipe_buf->mapped = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gdi_softpipe_buffer_destroy(struct pipe_buffer *buf)
|
||||
{
|
||||
struct gdi_softpipe_buffer *oldBuf = gdi_softpipe_buffer(buf);
|
||||
|
||||
if (oldBuf->data) {
|
||||
if (!oldBuf->userBuffer)
|
||||
align_free(oldBuf->data);
|
||||
|
||||
oldBuf->data = NULL;
|
||||
}
|
||||
|
||||
FREE(oldBuf);
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
gdi_softpipe_get_name(struct pipe_winsys *winsys)
|
||||
{
|
||||
return "softpipe";
|
||||
}
|
||||
|
||||
|
||||
static struct pipe_buffer *
|
||||
gdi_softpipe_buffer_create(struct pipe_winsys *winsys,
|
||||
unsigned alignment,
|
||||
unsigned usage,
|
||||
unsigned size)
|
||||
{
|
||||
struct gdi_softpipe_buffer *buffer = CALLOC_STRUCT(gdi_softpipe_buffer);
|
||||
|
||||
pipe_reference_init(&buffer->base.reference, 1);
|
||||
buffer->base.alignment = alignment;
|
||||
buffer->base.usage = usage;
|
||||
buffer->base.size = size;
|
||||
|
||||
buffer->data = align_malloc(size, alignment);
|
||||
|
||||
return &buffer->base;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create buffer which wraps user-space data.
|
||||
*/
|
||||
static struct pipe_buffer *
|
||||
gdi_softpipe_user_buffer_create(struct pipe_winsys *winsys,
|
||||
void *ptr,
|
||||
unsigned bytes)
|
||||
{
|
||||
struct gdi_softpipe_buffer *buffer;
|
||||
|
||||
buffer = CALLOC_STRUCT(gdi_softpipe_buffer);
|
||||
if(!buffer)
|
||||
return NULL;
|
||||
|
||||
pipe_reference_init(&buffer->base.reference, 1);
|
||||
buffer->base.size = bytes;
|
||||
buffer->userBuffer = TRUE;
|
||||
buffer->data = ptr;
|
||||
|
||||
return &buffer->base;
|
||||
}
|
||||
|
||||
|
||||
static struct pipe_buffer *
|
||||
gdi_softpipe_surface_buffer_create(struct pipe_winsys *winsys,
|
||||
unsigned width, unsigned height,
|
||||
enum pipe_format format,
|
||||
unsigned usage,
|
||||
unsigned tex_usage,
|
||||
unsigned *stride)
|
||||
{
|
||||
const unsigned alignment = 64;
|
||||
unsigned nblocksy;
|
||||
|
||||
nblocksy = util_format_get_nblocksy(format, height);
|
||||
*stride = align(util_format_get_stride(format, width), alignment);
|
||||
|
||||
return winsys->buffer_create(winsys, alignment,
|
||||
usage,
|
||||
*stride * nblocksy);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gdi_softpipe_dummy_flush_frontbuffer(struct pipe_winsys *winsys,
|
||||
struct pipe_surface *surface,
|
||||
void *context_private)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gdi_softpipe_fence_reference(struct pipe_winsys *winsys,
|
||||
struct pipe_fence_handle **ptr,
|
||||
struct pipe_fence_handle *fence)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gdi_softpipe_fence_signalled(struct pipe_winsys *winsys,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gdi_softpipe_fence_finish(struct pipe_winsys *winsys,
|
||||
struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gdi_softpipe_destroy(struct pipe_winsys *winsys)
|
||||
{
|
||||
FREE(winsys);
|
||||
}
|
||||
|
||||
|
||||
static struct pipe_screen *
|
||||
gdi_softpipe_screen_create(void)
|
||||
{
|
||||
static struct pipe_winsys *winsys;
|
||||
static struct softpipe_winsys *winsys;
|
||||
struct pipe_screen *screen;
|
||||
|
||||
winsys = CALLOC_STRUCT(pipe_winsys);
|
||||
winsys = gdi_create_sw_winsys();
|
||||
if(!winsys)
|
||||
return NULL;
|
||||
|
||||
winsys->destroy = gdi_softpipe_destroy;
|
||||
|
||||
winsys->buffer_create = gdi_softpipe_buffer_create;
|
||||
winsys->user_buffer_create = gdi_softpipe_user_buffer_create;
|
||||
winsys->buffer_map = gdi_softpipe_buffer_map;
|
||||
winsys->buffer_unmap = gdi_softpipe_buffer_unmap;
|
||||
winsys->buffer_destroy = gdi_softpipe_buffer_destroy;
|
||||
|
||||
winsys->surface_buffer_create = gdi_softpipe_surface_buffer_create;
|
||||
|
||||
winsys->fence_reference = gdi_softpipe_fence_reference;
|
||||
winsys->fence_signalled = gdi_softpipe_fence_signalled;
|
||||
winsys->fence_finish = gdi_softpipe_fence_finish;
|
||||
|
||||
winsys->flush_frontbuffer = gdi_softpipe_dummy_flush_frontbuffer;
|
||||
winsys->get_name = gdi_softpipe_get_name;
|
||||
goto no_winsys;
|
||||
|
||||
screen = softpipe_create_screen(winsys);
|
||||
if(!screen)
|
||||
gdi_softpipe_destroy(winsys);
|
||||
goto no_screen;
|
||||
|
||||
return screen;
|
||||
|
||||
no_screen:
|
||||
FREE(winsys);
|
||||
no_winsys:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
gdi_softpipe_present(struct pipe_screen *screen,
|
||||
struct pipe_surface *surface,
|
||||
HDC hDC)
|
||||
{
|
||||
struct softpipe_texture *texture;
|
||||
struct gdi_softpipe_buffer *buffer;
|
||||
BITMAPINFO bmi;
|
||||
struct gdi_softpipe_displaytarget *gdt;
|
||||
|
||||
texture = softpipe_texture(surface->texture);
|
||||
|
||||
buffer = gdi_softpipe_buffer(texture->buffer);
|
||||
|
||||
memset(&bmi, 0, sizeof(BITMAPINFO));
|
||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bmi.bmiHeader.biWidth = texture->stride[surface->level] / util_format_get_blocksize(surface->format);
|
||||
bmi.bmiHeader.biHeight= -(long)surface->height;
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biBitCount = util_format_get_blocksizebits(surface->format);
|
||||
bmi.bmiHeader.biCompression = BI_RGB;
|
||||
bmi.bmiHeader.biSizeImage = 0;
|
||||
bmi.bmiHeader.biXPelsPerMeter = 0;
|
||||
bmi.bmiHeader.biYPelsPerMeter = 0;
|
||||
bmi.bmiHeader.biClrUsed = 0;
|
||||
bmi.bmiHeader.biClrImportant = 0;
|
||||
gdt = gdi_softpipe_displaytarget(texture->dt);
|
||||
|
||||
StretchDIBits(hDC,
|
||||
0, 0, surface->width, surface->height,
|
||||
0, 0, surface->width, surface->height,
|
||||
buffer->data, &bmi, 0, SRCCOPY);
|
||||
0, 0, gdt->width, gdt->height,
|
||||
0, 0, gdt->width, gdt->height,
|
||||
gdt->data, &gdt->bmi, 0, SRCCOPY);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -29,6 +29,7 @@ DEFINES += \
|
||||
XLIB_WINSYS_SOURCES = \
|
||||
xlib.c \
|
||||
xlib_cell.c \
|
||||
xlib_sw_winsys.c \
|
||||
xlib_llvmpipe.c \
|
||||
xlib_softpipe.c
|
||||
|
||||
|
@@ -36,7 +36,7 @@ drivers = [trace]
|
||||
|
||||
if 'softpipe' in env['drivers']:
|
||||
env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE')
|
||||
sources += ['xlib_softpipe.c']
|
||||
sources += ['xlib_softpipe.c', 'xlib_sw_winsys.c']
|
||||
drivers += [softpipe]
|
||||
|
||||
if 'llvmpipe' in env['drivers']:
|
||||
@@ -44,7 +44,7 @@ if 'llvmpipe' in env['drivers']:
|
||||
if 'LLVM_VERSION' in env:
|
||||
env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE')
|
||||
env.Tool('udis86')
|
||||
sources += ['xlib_llvmpipe.c']
|
||||
sources += ['xlib_llvmpipe.c', 'xlib_sw_winsys.c']
|
||||
drivers += [llvmpipe]
|
||||
|
||||
if 'cell' in env['drivers']:
|
||||
|
@@ -33,9 +33,7 @@
|
||||
|
||||
#include "xlib.h"
|
||||
#include "xm_winsys.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "util/u_debug.h"
|
||||
|
||||
/* Todo, replace all this with callback-structs provided by the
|
||||
* individual implementations.
|
||||
|
@@ -9,5 +9,12 @@ extern struct xm_driver xlib_softpipe_driver;
|
||||
extern struct xm_driver xlib_llvmpipe_driver;
|
||||
extern struct xm_driver xlib_cell_driver;
|
||||
|
||||
/* Internal:
|
||||
*/
|
||||
struct sw_winsys;
|
||||
struct sw_displaytarget;
|
||||
struct sw_winsys *xlib_create_sw_winsys( void );
|
||||
void xlib_sw_display(struct xmesa_buffer *xm_buffer,
|
||||
struct sw_displaytarget *dt);
|
||||
|
||||
#endif
|
||||
|
@@ -33,367 +33,16 @@
|
||||
*/
|
||||
|
||||
|
||||
#if defined(GALLIUM_LLVMPIPE)
|
||||
|
||||
#include "xm_api.h"
|
||||
|
||||
#undef ASSERT
|
||||
#undef Elements
|
||||
|
||||
#include "util/u_simple_screen.h"
|
||||
#include "pipe/p_format.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_format.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "llvmpipe/lp_winsys.h"
|
||||
#include "llvmpipe/lp_texture.h"
|
||||
|
||||
#include "xlib.h"
|
||||
|
||||
/**
|
||||
* Subclass of pipe_buffer for Xlib winsys.
|
||||
* Low-level OS/window system memory buffer
|
||||
*/
|
||||
struct xm_displaytarget
|
||||
{
|
||||
enum pipe_format format;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned stride;
|
||||
|
||||
void *data;
|
||||
void *mapped;
|
||||
|
||||
XImage *tempImage;
|
||||
#ifdef USE_XSHM
|
||||
int shm;
|
||||
XShmSegmentInfo shminfo;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Subclass of llvmpipe_winsys for Xlib winsys
|
||||
*/
|
||||
struct xmesa_llvmpipe_winsys
|
||||
{
|
||||
struct llvmpipe_winsys base;
|
||||
/* struct xmesa_visual *xm_visual; */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** Cast wrapper */
|
||||
static INLINE struct xm_displaytarget *
|
||||
xm_displaytarget( struct llvmpipe_displaytarget *dt )
|
||||
{
|
||||
return (struct xm_displaytarget *)dt;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* X Shared Memory Image extension code
|
||||
*/
|
||||
|
||||
#ifdef USE_XSHM
|
||||
|
||||
static volatile int mesaXErrorFlag = 0;
|
||||
|
||||
/**
|
||||
* Catches potential Xlib errors.
|
||||
*/
|
||||
static int
|
||||
mesaHandleXError(Display *dpy, XErrorEvent *event)
|
||||
{
|
||||
(void) dpy;
|
||||
(void) event;
|
||||
mesaXErrorFlag = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static char *alloc_shm(struct xm_displaytarget *buf, unsigned size)
|
||||
{
|
||||
XShmSegmentInfo *const shminfo = & buf->shminfo;
|
||||
|
||||
shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
|
||||
if (shminfo->shmid < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
|
||||
if (shminfo->shmaddr == (char *) -1) {
|
||||
shmctl(shminfo->shmid, IPC_RMID, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
shminfo->readOnly = False;
|
||||
return shminfo->shmaddr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allocate a shared memory XImage back buffer for the given XMesaBuffer.
|
||||
*/
|
||||
static void
|
||||
alloc_shm_ximage(struct xm_displaytarget *xm_buffer,
|
||||
struct xmesa_buffer *xmb,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
/*
|
||||
* We have to do a _lot_ of error checking here to be sure we can
|
||||
* really use the XSHM extension. It seems different servers trigger
|
||||
* errors at different points if the extension won't work. Therefore
|
||||
* we have to be very careful...
|
||||
*/
|
||||
int (*old_handler)(Display *, XErrorEvent *);
|
||||
|
||||
xm_buffer->tempImage = XShmCreateImage(xmb->xm_visual->display,
|
||||
xmb->xm_visual->visinfo->visual,
|
||||
xmb->xm_visual->visinfo->depth,
|
||||
ZPixmap,
|
||||
NULL,
|
||||
&xm_buffer->shminfo,
|
||||
width, height);
|
||||
if (xm_buffer->tempImage == NULL) {
|
||||
xm_buffer->shm = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
mesaXErrorFlag = 0;
|
||||
old_handler = XSetErrorHandler(mesaHandleXError);
|
||||
/* This may trigger the X protocol error we're ready to catch: */
|
||||
XShmAttach(xmb->xm_visual->display, &xm_buffer->shminfo);
|
||||
XSync(xmb->xm_visual->display, False);
|
||||
|
||||
if (mesaXErrorFlag) {
|
||||
/* we are on a remote display, this error is normal, don't print it */
|
||||
XFlush(xmb->xm_visual->display);
|
||||
mesaXErrorFlag = 0;
|
||||
XDestroyImage(xm_buffer->tempImage);
|
||||
xm_buffer->tempImage = NULL;
|
||||
xm_buffer->shm = 0;
|
||||
(void) XSetErrorHandler(old_handler);
|
||||
return;
|
||||
}
|
||||
|
||||
xm_buffer->shm = 1;
|
||||
}
|
||||
|
||||
#endif /* USE_XSHM */
|
||||
|
||||
static boolean
|
||||
xm_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
|
||||
enum pipe_format format )
|
||||
{
|
||||
/* TODO: check visuals or other sensible thing here */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
xm_displaytarget_map(struct llvmpipe_winsys *ws,
|
||||
struct llvmpipe_displaytarget *dt,
|
||||
unsigned flags)
|
||||
{
|
||||
struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
|
||||
xm_dt->mapped = xm_dt->data;
|
||||
return xm_dt->mapped;
|
||||
}
|
||||
|
||||
static void
|
||||
xm_displaytarget_unmap(struct llvmpipe_winsys *ws,
|
||||
struct llvmpipe_displaytarget *dt)
|
||||
{
|
||||
struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
|
||||
xm_dt->mapped = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
xm_displaytarget_destroy(struct llvmpipe_winsys *ws,
|
||||
struct llvmpipe_displaytarget *dt)
|
||||
{
|
||||
struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
|
||||
|
||||
if (xm_dt->data) {
|
||||
#ifdef USE_XSHM
|
||||
if (xm_dt->shminfo.shmid >= 0) {
|
||||
shmdt(xm_dt->shminfo.shmaddr);
|
||||
shmctl(xm_dt->shminfo.shmid, IPC_RMID, 0);
|
||||
|
||||
xm_dt->shminfo.shmid = -1;
|
||||
xm_dt->shminfo.shmaddr = (char *) -1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
FREE(xm_dt->data);
|
||||
}
|
||||
|
||||
FREE(xm_dt);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Display/copy the image in the surface into the X window specified
|
||||
* by the XMesaBuffer.
|
||||
*/
|
||||
static void
|
||||
xm_llvmpipe_display(struct xmesa_buffer *xm_buffer,
|
||||
struct llvmpipe_displaytarget *dt)
|
||||
{
|
||||
XImage *ximage;
|
||||
struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
|
||||
static boolean no_swap = 0;
|
||||
static boolean firsttime = 1;
|
||||
|
||||
if (firsttime) {
|
||||
no_swap = getenv("SP_NO_RAST") != NULL;
|
||||
firsttime = 0;
|
||||
}
|
||||
|
||||
if (no_swap)
|
||||
return;
|
||||
|
||||
#ifdef USE_XSHM
|
||||
if (xm_dt->shm)
|
||||
{
|
||||
if (xm_dt->tempImage == NULL)
|
||||
{
|
||||
assert(util_format_get_blockwidth(xm_dt->format) == 1);
|
||||
assert(util_format_get_blockheight(xm_dt->format) == 1);
|
||||
alloc_shm_ximage(xm_dt, xm_buffer,
|
||||
xm_dt->stride / util_format_get_blocksize(xm_dt->format),
|
||||
xm_dt->height);
|
||||
}
|
||||
|
||||
ximage = xm_dt->tempImage;
|
||||
ximage->data = xm_dt->data;
|
||||
|
||||
/* _debug_printf("XSHM\n"); */
|
||||
XShmPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc,
|
||||
ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height, False);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* display image in Window */
|
||||
ximage = xm_dt->tempImage;
|
||||
ximage->data = xm_dt->data;
|
||||
|
||||
/* check that the XImage has been previously initialized */
|
||||
assert(ximage->format);
|
||||
assert(ximage->bitmap_unit);
|
||||
|
||||
/* update XImage's fields */
|
||||
ximage->width = xm_dt->width;
|
||||
ximage->height = xm_dt->height;
|
||||
ximage->bytes_per_line = xm_dt->stride;
|
||||
|
||||
/* _debug_printf("XPUT\n"); */
|
||||
XPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc,
|
||||
ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display/copy the image in the surface into the X window specified
|
||||
* by the XMesaBuffer.
|
||||
*/
|
||||
static void
|
||||
xm_displaytarget_display(struct llvmpipe_winsys *ws,
|
||||
struct llvmpipe_displaytarget *dt,
|
||||
void *context_private)
|
||||
{
|
||||
XMesaContext xmctx = (XMesaContext) context_private;
|
||||
struct xmesa_buffer *xm_buffer = xmctx->xm_buffer;
|
||||
xm_llvmpipe_display(xm_buffer, dt);
|
||||
}
|
||||
|
||||
|
||||
static struct llvmpipe_displaytarget *
|
||||
xm_displaytarget_create(struct llvmpipe_winsys *winsys,
|
||||
enum pipe_format format,
|
||||
unsigned width, unsigned height,
|
||||
unsigned alignment,
|
||||
unsigned *stride)
|
||||
{
|
||||
struct xm_displaytarget *xm_dt = CALLOC_STRUCT(xm_displaytarget);
|
||||
unsigned nblocksy, size;
|
||||
|
||||
xm_dt = CALLOC_STRUCT(xm_displaytarget);
|
||||
if(!xm_dt)
|
||||
goto no_xm_dt;
|
||||
|
||||
xm_dt->format = format;
|
||||
xm_dt->width = width;
|
||||
xm_dt->height = height;
|
||||
|
||||
nblocksy = util_format_get_nblocksy(format, height);
|
||||
xm_dt->stride = align(util_format_get_stride(format, width), alignment);
|
||||
size = xm_dt->stride * nblocksy;
|
||||
|
||||
#ifdef USE_XSHM
|
||||
if (!debug_get_bool_option("XLIB_NO_SHM", FALSE))
|
||||
{
|
||||
xm_dt->shminfo.shmid = -1;
|
||||
xm_dt->shminfo.shmaddr = (char *) -1;
|
||||
xm_dt->shm = TRUE;
|
||||
|
||||
xm_dt->data = alloc_shm(xm_dt, size);
|
||||
if(!xm_dt->data)
|
||||
goto no_data;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!xm_dt->data) {
|
||||
xm_dt->data = align_malloc(size, alignment);
|
||||
if(!xm_dt->data)
|
||||
goto no_data;
|
||||
}
|
||||
|
||||
*stride = xm_dt->stride;
|
||||
return (struct llvmpipe_displaytarget *)xm_dt;
|
||||
|
||||
no_data:
|
||||
FREE(xm_dt);
|
||||
no_xm_dt:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
xm_destroy( struct llvmpipe_winsys *ws )
|
||||
{
|
||||
FREE(ws);
|
||||
}
|
||||
|
||||
|
||||
static struct llvmpipe_winsys *
|
||||
xlib_create_llvmpipe_winsys( void )
|
||||
{
|
||||
struct xmesa_llvmpipe_winsys *ws;
|
||||
|
||||
ws = CALLOC_STRUCT(xmesa_llvmpipe_winsys);
|
||||
if (!ws)
|
||||
return NULL;
|
||||
|
||||
ws->base.destroy = xm_destroy;
|
||||
|
||||
ws->base.is_displaytarget_format_supported = xm_is_displaytarget_format_supported;
|
||||
|
||||
ws->base.displaytarget_create = xm_displaytarget_create;
|
||||
ws->base.displaytarget_map = xm_displaytarget_map;
|
||||
ws->base.displaytarget_unmap = xm_displaytarget_unmap;
|
||||
ws->base.displaytarget_destroy = xm_displaytarget_destroy;
|
||||
|
||||
ws->base.displaytarget_display = xm_displaytarget_display;
|
||||
|
||||
return &ws->base;
|
||||
}
|
||||
#if defined(GALLIUM_LLVMPIPE)
|
||||
|
||||
#include "llvmpipe/lp_texture.h"
|
||||
#include "llvmpipe/lp_winsys.h"
|
||||
#include "state_tracker/sw_winsys.h"
|
||||
|
||||
static struct pipe_screen *
|
||||
xlib_create_llvmpipe_screen( void )
|
||||
@@ -401,7 +50,7 @@ xlib_create_llvmpipe_screen( void )
|
||||
struct llvmpipe_winsys *winsys;
|
||||
struct pipe_screen *screen;
|
||||
|
||||
winsys = xlib_create_llvmpipe_winsys();
|
||||
winsys = xlib_create_sw_winsys();
|
||||
if (winsys == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -427,7 +76,7 @@ xlib_llvmpipe_display_surface(struct xmesa_buffer *xm_buffer,
|
||||
|
||||
assert(texture->dt);
|
||||
if (texture->dt)
|
||||
xm_llvmpipe_display(xm_buffer, texture->dt);
|
||||
xlib_sw_display(xm_buffer, texture->dt);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -26,461 +26,19 @@
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell
|
||||
* Brian Paul
|
||||
*/
|
||||
|
||||
|
||||
#include "xm_api.h"
|
||||
|
||||
#undef ASSERT
|
||||
#undef Elements
|
||||
|
||||
#include "util/u_simple_screen.h"
|
||||
#include "pipe/p_format.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_format.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "softpipe/sp_winsys.h"
|
||||
#include "softpipe/sp_texture.h"
|
||||
|
||||
#include "xlib.h"
|
||||
|
||||
/**
|
||||
* Subclass of pipe_buffer for Xlib winsys.
|
||||
* Low-level OS/window system memory buffer
|
||||
*/
|
||||
struct xm_buffer
|
||||
{
|
||||
struct pipe_buffer base;
|
||||
boolean userBuffer; /** Is this a user-space buffer? */
|
||||
void *data;
|
||||
void *mapped;
|
||||
|
||||
XImage *tempImage;
|
||||
#ifdef USE_XSHM
|
||||
boolean shm; /** Is this a shared memory buffer? */
|
||||
XShmSegmentInfo shminfo;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Subclass of pipe_winsys for Xlib winsys
|
||||
*/
|
||||
struct xmesa_pipe_winsys
|
||||
{
|
||||
struct pipe_winsys base;
|
||||
/* struct xmesa_visual *xm_visual; */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** Cast wrapper */
|
||||
static INLINE struct xm_buffer *
|
||||
xm_buffer( struct pipe_buffer *buf )
|
||||
{
|
||||
return (struct xm_buffer *)buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* X Shared Memory Image extension code
|
||||
*/
|
||||
|
||||
#ifdef USE_XSHM
|
||||
|
||||
static volatile int mesaXErrorFlag = 0;
|
||||
|
||||
/**
|
||||
* Catches potential Xlib errors.
|
||||
*/
|
||||
static int
|
||||
mesaHandleXError(Display *dpy, XErrorEvent *event)
|
||||
{
|
||||
(void) dpy;
|
||||
(void) event;
|
||||
mesaXErrorFlag = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static char *alloc_shm(struct xm_buffer *buf, unsigned size)
|
||||
{
|
||||
XShmSegmentInfo *const shminfo = & buf->shminfo;
|
||||
|
||||
shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
|
||||
if (shminfo->shmid < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
|
||||
if (shminfo->shmaddr == (char *) -1) {
|
||||
shmctl(shminfo->shmid, IPC_RMID, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
shminfo->readOnly = False;
|
||||
return shminfo->shmaddr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allocate a shared memory XImage back buffer for the given XMesaBuffer.
|
||||
*/
|
||||
static void
|
||||
alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
/*
|
||||
* We have to do a _lot_ of error checking here to be sure we can
|
||||
* really use the XSHM extension. It seems different servers trigger
|
||||
* errors at different points if the extension won't work. Therefore
|
||||
* we have to be very careful...
|
||||
*/
|
||||
int (*old_handler)(Display *, XErrorEvent *);
|
||||
|
||||
b->tempImage = XShmCreateImage(xmb->xm_visual->display,
|
||||
xmb->xm_visual->visinfo->visual,
|
||||
xmb->xm_visual->visinfo->depth,
|
||||
ZPixmap,
|
||||
NULL,
|
||||
&b->shminfo,
|
||||
width, height);
|
||||
if (b->tempImage == NULL) {
|
||||
b->shm = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
mesaXErrorFlag = 0;
|
||||
old_handler = XSetErrorHandler(mesaHandleXError);
|
||||
/* This may trigger the X protocol error we're ready to catch: */
|
||||
XShmAttach(xmb->xm_visual->display, &b->shminfo);
|
||||
XSync(xmb->xm_visual->display, False);
|
||||
|
||||
if (mesaXErrorFlag) {
|
||||
/* we are on a remote display, this error is normal, don't print it */
|
||||
XFlush(xmb->xm_visual->display);
|
||||
mesaXErrorFlag = 0;
|
||||
XDestroyImage(b->tempImage);
|
||||
b->tempImage = NULL;
|
||||
b->shm = FALSE;
|
||||
(void) XSetErrorHandler(old_handler);
|
||||
return;
|
||||
}
|
||||
|
||||
b->shm = TRUE;
|
||||
}
|
||||
|
||||
#endif /* USE_XSHM */
|
||||
|
||||
|
||||
|
||||
/* Most callbacks map direcly onto dri_bufmgr operations:
|
||||
*/
|
||||
static void *
|
||||
xm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
|
||||
unsigned flags)
|
||||
{
|
||||
struct xm_buffer *xm_buf = xm_buffer(buf);
|
||||
xm_buf->mapped = xm_buf->data;
|
||||
return xm_buf->mapped;
|
||||
}
|
||||
|
||||
static void
|
||||
xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
|
||||
{
|
||||
struct xm_buffer *xm_buf = xm_buffer(buf);
|
||||
xm_buf->mapped = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
xm_buffer_destroy(struct pipe_buffer *buf)
|
||||
{
|
||||
struct xm_buffer *oldBuf = xm_buffer(buf);
|
||||
|
||||
/*
|
||||
* Note oldBuf->data may point to one of three things:
|
||||
* 1. XShm shared memory image data
|
||||
* 2. User-provided (wrapped) memory, see xm_user_buffer_create()
|
||||
* 3. Regular, malloc'd memory
|
||||
* We need to be careful with freeing that data now.
|
||||
*/
|
||||
|
||||
if (oldBuf->data) {
|
||||
#ifdef USE_XSHM
|
||||
if (oldBuf->shminfo.shmid >= 0) {
|
||||
shmdt(oldBuf->shminfo.shmaddr);
|
||||
shmctl(oldBuf->shminfo.shmid, IPC_RMID, 0);
|
||||
|
||||
oldBuf->shminfo.shmid = -1;
|
||||
oldBuf->shminfo.shmaddr = (char *) -1;
|
||||
}
|
||||
|
||||
if (oldBuf->shm) {
|
||||
oldBuf->data = NULL;
|
||||
}
|
||||
|
||||
if (oldBuf->tempImage) {
|
||||
XDestroyImage(oldBuf->tempImage);
|
||||
oldBuf->tempImage = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (oldBuf->data && !oldBuf->userBuffer) {
|
||||
/* this was regular malloc'd memory */
|
||||
align_free(oldBuf->data);
|
||||
}
|
||||
|
||||
oldBuf->data = NULL;
|
||||
}
|
||||
|
||||
free(oldBuf);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Display/copy the image in the surface into the X window specified
|
||||
* by the XMesaBuffer.
|
||||
*/
|
||||
static void
|
||||
xlib_softpipe_display_surface(struct xmesa_buffer *b,
|
||||
struct pipe_surface *surf)
|
||||
{
|
||||
XImage *ximage;
|
||||
struct softpipe_texture *spt = softpipe_texture(surf->texture);
|
||||
struct xm_buffer *xm_buf = xm_buffer(spt->buffer);
|
||||
static boolean no_swap = 0;
|
||||
static boolean firsttime = 1;
|
||||
|
||||
if (firsttime) {
|
||||
no_swap = getenv("SP_NO_RAST") != NULL;
|
||||
firsttime = 0;
|
||||
}
|
||||
|
||||
if (no_swap)
|
||||
return;
|
||||
|
||||
#ifdef USE_XSHM
|
||||
if (xm_buf->shm)
|
||||
{
|
||||
if (xm_buf->tempImage == NULL)
|
||||
{
|
||||
assert(util_format_get_blockwidth(surf->texture->format) == 1);
|
||||
assert(util_format_get_blockheight(surf->texture->format) == 1);
|
||||
alloc_shm_ximage(xm_buf, b, spt->stride[surf->level] /
|
||||
util_format_get_blocksize(surf->texture->format), surf->height);
|
||||
}
|
||||
|
||||
ximage = xm_buf->tempImage;
|
||||
ximage->data = xm_buf->data;
|
||||
|
||||
/* _debug_printf("XSHM\n"); */
|
||||
XShmPutImage(b->xm_visual->display, b->drawable, b->gc,
|
||||
ximage, 0, 0, 0, 0, surf->width, surf->height, False);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* display image in Window */
|
||||
ximage = b->tempImage;
|
||||
ximage->data = xm_buf->data;
|
||||
|
||||
/* check that the XImage has been previously initialized */
|
||||
assert(ximage->format);
|
||||
assert(ximage->bitmap_unit);
|
||||
|
||||
/* update XImage's fields */
|
||||
ximage->width = surf->width;
|
||||
ximage->height = surf->height;
|
||||
ximage->bytes_per_line = spt->stride[surf->level];
|
||||
|
||||
/* _debug_printf("XPUT\n"); */
|
||||
XPutImage(b->xm_visual->display, b->drawable, b->gc,
|
||||
ximage, 0, 0, 0, 0, surf->width, surf->height);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
xm_flush_frontbuffer(struct pipe_winsys *pws,
|
||||
struct pipe_surface *surf,
|
||||
void *context_private)
|
||||
{
|
||||
/*
|
||||
* The front color buffer is actually just another XImage buffer.
|
||||
* This function copies that XImage to the actual X Window.
|
||||
*/
|
||||
XMesaContext xmctx = (XMesaContext) context_private;
|
||||
xlib_softpipe_display_surface(xmctx->xm_buffer, surf);
|
||||
xmesa_check_and_update_buffer_size(xmctx, xmctx->xm_buffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char *
|
||||
xm_get_name(struct pipe_winsys *pws)
|
||||
{
|
||||
return "Xlib";
|
||||
}
|
||||
|
||||
|
||||
static struct pipe_buffer *
|
||||
xm_buffer_create(struct pipe_winsys *pws,
|
||||
unsigned alignment,
|
||||
unsigned usage,
|
||||
unsigned size)
|
||||
{
|
||||
struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
|
||||
|
||||
pipe_reference_init(&buffer->base.reference, 1);
|
||||
buffer->base.alignment = alignment;
|
||||
buffer->base.usage = usage;
|
||||
buffer->base.size = size;
|
||||
|
||||
/* align to 16-byte multiple for Cell */
|
||||
buffer->data = align_malloc(size, max(alignment, 16));
|
||||
|
||||
return &buffer->base;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create buffer which wraps user-space data.
|
||||
*/
|
||||
static struct pipe_buffer *
|
||||
xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
|
||||
{
|
||||
struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
|
||||
pipe_reference_init(&buffer->base.reference, 1);
|
||||
buffer->base.size = bytes;
|
||||
buffer->userBuffer = TRUE;
|
||||
buffer->data = ptr;
|
||||
|
||||
return &buffer->base;
|
||||
}
|
||||
|
||||
|
||||
static struct pipe_buffer *
|
||||
xm_surface_buffer_create(struct pipe_winsys *winsys,
|
||||
unsigned width, unsigned height,
|
||||
enum pipe_format format,
|
||||
unsigned usage,
|
||||
unsigned tex_usage,
|
||||
unsigned *stride)
|
||||
{
|
||||
const unsigned alignment = 64;
|
||||
unsigned nblocksy, size;
|
||||
|
||||
nblocksy = util_format_get_nblocksy(format, height);
|
||||
*stride = align(util_format_get_stride(format, width), alignment);
|
||||
size = *stride * nblocksy;
|
||||
|
||||
#ifdef USE_XSHM
|
||||
if (!debug_get_bool_option("XLIB_NO_SHM", FALSE))
|
||||
{
|
||||
struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
|
||||
|
||||
pipe_reference_init(&buffer->base.reference, 1);
|
||||
buffer->base.alignment = alignment;
|
||||
buffer->base.usage = usage;
|
||||
buffer->base.size = size;
|
||||
buffer->userBuffer = FALSE;
|
||||
buffer->shminfo.shmid = -1;
|
||||
buffer->shminfo.shmaddr = (char *) -1;
|
||||
buffer->shm = TRUE;
|
||||
|
||||
buffer->data = alloc_shm(buffer, size);
|
||||
if (!buffer->data)
|
||||
goto out;
|
||||
|
||||
return &buffer->base;
|
||||
|
||||
out:
|
||||
if (buffer)
|
||||
FREE(buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return winsys->buffer_create(winsys, alignment,
|
||||
usage,
|
||||
size);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fence functions - basically nothing to do, as we don't create any actual
|
||||
* fence objects.
|
||||
*/
|
||||
|
||||
static void
|
||||
xm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
|
||||
struct pipe_fence_handle *fence)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
xm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
xm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct pipe_winsys *
|
||||
xlib_create_softpipe_winsys( void )
|
||||
{
|
||||
static struct xmesa_pipe_winsys *ws = NULL;
|
||||
|
||||
if (!ws) {
|
||||
ws = CALLOC_STRUCT(xmesa_pipe_winsys);
|
||||
|
||||
/* Fill in this struct with callbacks that pipe will need to
|
||||
* communicate with the window system, buffer manager, etc.
|
||||
*/
|
||||
ws->base.buffer_create = xm_buffer_create;
|
||||
ws->base.user_buffer_create = xm_user_buffer_create;
|
||||
ws->base.buffer_map = xm_buffer_map;
|
||||
ws->base.buffer_unmap = xm_buffer_unmap;
|
||||
ws->base.buffer_destroy = xm_buffer_destroy;
|
||||
|
||||
ws->base.surface_buffer_create = xm_surface_buffer_create;
|
||||
|
||||
ws->base.fence_reference = xm_fence_reference;
|
||||
ws->base.fence_signalled = xm_fence_signalled;
|
||||
ws->base.fence_finish = xm_fence_finish;
|
||||
|
||||
ws->base.flush_frontbuffer = xm_flush_frontbuffer;
|
||||
ws->base.get_name = xm_get_name;
|
||||
}
|
||||
|
||||
return &ws->base;
|
||||
}
|
||||
|
||||
#include "softpipe/sp_texture.h"
|
||||
#include "softpipe/sp_screen.h"
|
||||
#include "state_tracker/sw_winsys.h"
|
||||
|
||||
static struct pipe_screen *
|
||||
xlib_create_softpipe_screen( void )
|
||||
{
|
||||
struct pipe_winsys *winsys;
|
||||
struct sw_winsys *winsys;
|
||||
struct pipe_screen *screen;
|
||||
|
||||
winsys = xlib_create_softpipe_winsys();
|
||||
winsys = xlib_create_sw_winsys();
|
||||
if (winsys == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -498,6 +56,18 @@ fail:
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
xlib_softpipe_display_surface(struct xmesa_buffer *xm_buffer,
|
||||
struct pipe_surface *surf)
|
||||
{
|
||||
struct softpipe_texture *texture = softpipe_texture(surf->texture);
|
||||
|
||||
assert(texture->dt);
|
||||
if (texture->dt)
|
||||
xlib_sw_display(xm_buffer, texture->dt);
|
||||
}
|
||||
|
||||
|
||||
struct xm_driver xlib_softpipe_driver =
|
||||
{
|
||||
.create_pipe_screen = xlib_create_softpipe_screen,
|
||||
|
394
src/gallium/winsys/xlib/xlib_sw_winsys.c
Normal file
394
src/gallium/winsys/xlib/xlib_sw_winsys.c
Normal file
@@ -0,0 +1,394 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Keith Whitwell
|
||||
* Brian Paul
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "xm_api.h"
|
||||
|
||||
#undef ASSERT
|
||||
#undef Elements
|
||||
|
||||
#include "pipe/p_format.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_format.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "state_tracker/sw_winsys.h"
|
||||
|
||||
#include "xlib.h"
|
||||
|
||||
/**
|
||||
* Subclass of pipe_buffer for Xlib winsys.
|
||||
* Low-level OS/window system memory buffer
|
||||
*/
|
||||
struct xm_displaytarget
|
||||
{
|
||||
enum pipe_format format;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned stride;
|
||||
|
||||
void *data;
|
||||
void *mapped;
|
||||
|
||||
XImage *tempImage;
|
||||
#ifdef USE_XSHM
|
||||
int shm;
|
||||
XShmSegmentInfo shminfo;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Subclass of sw_winsys for Xlib winsys
|
||||
*/
|
||||
struct xmesa_sw_winsys
|
||||
{
|
||||
struct sw_winsys base;
|
||||
/* struct xmesa_visual *xm_visual; */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** Cast wrapper */
|
||||
static INLINE struct xm_displaytarget *
|
||||
xm_displaytarget( struct sw_displaytarget *dt )
|
||||
{
|
||||
return (struct xm_displaytarget *)dt;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* X Shared Memory Image extension code
|
||||
*/
|
||||
|
||||
#ifdef USE_XSHM
|
||||
|
||||
static volatile int mesaXErrorFlag = 0;
|
||||
|
||||
/**
|
||||
* Catches potential Xlib errors.
|
||||
*/
|
||||
static int
|
||||
mesaHandleXError(Display *dpy, XErrorEvent *event)
|
||||
{
|
||||
(void) dpy;
|
||||
(void) event;
|
||||
mesaXErrorFlag = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static char *alloc_shm(struct xm_displaytarget *buf, unsigned size)
|
||||
{
|
||||
XShmSegmentInfo *const shminfo = & buf->shminfo;
|
||||
|
||||
shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
|
||||
if (shminfo->shmid < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
|
||||
if (shminfo->shmaddr == (char *) -1) {
|
||||
shmctl(shminfo->shmid, IPC_RMID, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
shminfo->readOnly = False;
|
||||
return shminfo->shmaddr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allocate a shared memory XImage back buffer for the given XMesaBuffer.
|
||||
*/
|
||||
static void
|
||||
alloc_shm_ximage(struct xm_displaytarget *xm_buffer,
|
||||
struct xmesa_buffer *xmb,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
/*
|
||||
* We have to do a _lot_ of error checking here to be sure we can
|
||||
* really use the XSHM extension. It seems different servers trigger
|
||||
* errors at different points if the extension won't work. Therefore
|
||||
* we have to be very careful...
|
||||
*/
|
||||
int (*old_handler)(Display *, XErrorEvent *);
|
||||
|
||||
xm_buffer->tempImage = XShmCreateImage(xmb->xm_visual->display,
|
||||
xmb->xm_visual->visinfo->visual,
|
||||
xmb->xm_visual->visinfo->depth,
|
||||
ZPixmap,
|
||||
NULL,
|
||||
&xm_buffer->shminfo,
|
||||
width, height);
|
||||
if (xm_buffer->tempImage == NULL) {
|
||||
xm_buffer->shm = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
mesaXErrorFlag = 0;
|
||||
old_handler = XSetErrorHandler(mesaHandleXError);
|
||||
/* This may trigger the X protocol error we're ready to catch: */
|
||||
XShmAttach(xmb->xm_visual->display, &xm_buffer->shminfo);
|
||||
XSync(xmb->xm_visual->display, False);
|
||||
|
||||
if (mesaXErrorFlag) {
|
||||
/* we are on a remote display, this error is normal, don't print it */
|
||||
XFlush(xmb->xm_visual->display);
|
||||
mesaXErrorFlag = 0;
|
||||
XDestroyImage(xm_buffer->tempImage);
|
||||
xm_buffer->tempImage = NULL;
|
||||
xm_buffer->shm = 0;
|
||||
(void) XSetErrorHandler(old_handler);
|
||||
return;
|
||||
}
|
||||
|
||||
xm_buffer->shm = 1;
|
||||
}
|
||||
|
||||
#endif /* USE_XSHM */
|
||||
|
||||
static boolean
|
||||
xm_is_displaytarget_format_supported( struct sw_winsys *ws,
|
||||
enum pipe_format format )
|
||||
{
|
||||
/* TODO: check visuals or other sensible thing here */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
xm_displaytarget_map(struct sw_winsys *ws,
|
||||
struct sw_displaytarget *dt,
|
||||
unsigned flags)
|
||||
{
|
||||
struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
|
||||
xm_dt->mapped = xm_dt->data;
|
||||
return xm_dt->mapped;
|
||||
}
|
||||
|
||||
static void
|
||||
xm_displaytarget_unmap(struct sw_winsys *ws,
|
||||
struct sw_displaytarget *dt)
|
||||
{
|
||||
struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
|
||||
xm_dt->mapped = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
xm_displaytarget_destroy(struct sw_winsys *ws,
|
||||
struct sw_displaytarget *dt)
|
||||
{
|
||||
struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
|
||||
|
||||
if (xm_dt->data) {
|
||||
#ifdef USE_XSHM
|
||||
if (xm_dt->shminfo.shmid >= 0) {
|
||||
shmdt(xm_dt->shminfo.shmaddr);
|
||||
shmctl(xm_dt->shminfo.shmid, IPC_RMID, 0);
|
||||
|
||||
xm_dt->shminfo.shmid = -1;
|
||||
xm_dt->shminfo.shmaddr = (char *) -1;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
FREE(xm_dt->data);
|
||||
}
|
||||
|
||||
FREE(xm_dt);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Display/copy the image in the surface into the X window specified
|
||||
* by the XMesaBuffer.
|
||||
*/
|
||||
void
|
||||
xlib_sw_display(struct xmesa_buffer *xm_buffer,
|
||||
struct sw_displaytarget *dt)
|
||||
{
|
||||
XImage *ximage;
|
||||
struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
|
||||
static boolean no_swap = 0;
|
||||
static boolean firsttime = 1;
|
||||
|
||||
if (firsttime) {
|
||||
no_swap = getenv("SP_NO_RAST") != NULL;
|
||||
firsttime = 0;
|
||||
}
|
||||
|
||||
if (no_swap)
|
||||
return;
|
||||
|
||||
#ifdef USE_XSHM
|
||||
if (xm_dt->shm)
|
||||
{
|
||||
if (xm_dt->tempImage == NULL)
|
||||
{
|
||||
assert(util_format_get_blockwidth(xm_dt->format) == 1);
|
||||
assert(util_format_get_blockheight(xm_dt->format) == 1);
|
||||
alloc_shm_ximage(xm_dt, xm_buffer,
|
||||
xm_dt->stride / util_format_get_blocksize(xm_dt->format),
|
||||
xm_dt->height);
|
||||
}
|
||||
|
||||
ximage = xm_dt->tempImage;
|
||||
ximage->data = xm_dt->data;
|
||||
|
||||
/* _debug_printf("XSHM\n"); */
|
||||
XShmPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc,
|
||||
ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height, False);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* display image in Window */
|
||||
ximage = xm_dt->tempImage;
|
||||
ximage->data = xm_dt->data;
|
||||
|
||||
/* check that the XImage has been previously initialized */
|
||||
assert(ximage->format);
|
||||
assert(ximage->bitmap_unit);
|
||||
|
||||
/* update XImage's fields */
|
||||
ximage->width = xm_dt->width;
|
||||
ximage->height = xm_dt->height;
|
||||
ximage->bytes_per_line = xm_dt->stride;
|
||||
|
||||
/* _debug_printf("XPUT\n"); */
|
||||
XPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc,
|
||||
ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display/copy the image in the surface into the X window specified
|
||||
* by the XMesaBuffer.
|
||||
*/
|
||||
static void
|
||||
xm_displaytarget_display(struct sw_winsys *ws,
|
||||
struct sw_displaytarget *dt,
|
||||
void *context_private)
|
||||
{
|
||||
XMesaContext xmctx = (XMesaContext) context_private;
|
||||
struct xmesa_buffer *xm_buffer = xmctx->xm_buffer;
|
||||
xm_sw_display(xm_buffer, dt);
|
||||
}
|
||||
|
||||
|
||||
static struct sw_displaytarget *
|
||||
xm_displaytarget_create(struct sw_winsys *winsys,
|
||||
enum pipe_format format,
|
||||
unsigned width, unsigned height,
|
||||
unsigned alignment,
|
||||
unsigned *stride)
|
||||
{
|
||||
struct xm_displaytarget *xm_dt = CALLOC_STRUCT(xm_displaytarget);
|
||||
unsigned nblocksy, size;
|
||||
|
||||
xm_dt = CALLOC_STRUCT(xm_displaytarget);
|
||||
if(!xm_dt)
|
||||
goto no_xm_dt;
|
||||
|
||||
xm_dt->format = format;
|
||||
xm_dt->width = width;
|
||||
xm_dt->height = height;
|
||||
|
||||
nblocksy = util_format_get_nblocksy(format, height);
|
||||
xm_dt->stride = align(util_format_get_stride(format, width), alignment);
|
||||
size = xm_dt->stride * nblocksy;
|
||||
|
||||
#ifdef USE_XSHM
|
||||
if (!debug_get_bool_option("XLIB_NO_SHM", FALSE))
|
||||
{
|
||||
xm_dt->shminfo.shmid = -1;
|
||||
xm_dt->shminfo.shmaddr = (char *) -1;
|
||||
xm_dt->shm = TRUE;
|
||||
|
||||
xm_dt->data = alloc_shm(xm_dt, size);
|
||||
if(!xm_dt->data)
|
||||
goto no_data;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!xm_dt->data) {
|
||||
xm_dt->data = align_malloc(size, alignment);
|
||||
if(!xm_dt->data)
|
||||
goto no_data;
|
||||
}
|
||||
|
||||
*stride = xm_dt->stride;
|
||||
return (struct sw_displaytarget *)xm_dt;
|
||||
|
||||
no_data:
|
||||
FREE(xm_dt);
|
||||
no_xm_dt:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
xm_destroy( struct sw_winsys *ws )
|
||||
{
|
||||
FREE(ws);
|
||||
}
|
||||
|
||||
|
||||
struct sw_winsys *
|
||||
xlib_create_sw_winsys( void )
|
||||
{
|
||||
struct xmesa_sw_winsys *ws;
|
||||
|
||||
ws = CALLOC_STRUCT(xmesa_sw_winsys);
|
||||
if (!ws)
|
||||
return NULL;
|
||||
|
||||
ws->base.destroy = xm_destroy;
|
||||
|
||||
ws->base.is_displaytarget_format_supported = xm_is_displaytarget_format_supported;
|
||||
|
||||
ws->base.displaytarget_create = xm_displaytarget_create;
|
||||
ws->base.displaytarget_map = xm_displaytarget_map;
|
||||
ws->base.displaytarget_unmap = xm_displaytarget_unmap;
|
||||
ws->base.displaytarget_destroy = xm_displaytarget_destroy;
|
||||
|
||||
ws->base.displaytarget_display = xm_displaytarget_display;
|
||||
|
||||
return &ws->base;
|
||||
}
|
||||
|
Reference in New Issue
Block a user