Commit 94ce4eb3 authored by Keith Whitwell's avatar Keith Whitwell

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.
parent c7f7a309
......@@ -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')
/**************************************************************************
*
* 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;
}
/**************************************************************************
*
* 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
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
......@@ -10,64 +10,46 @@
* 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 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
struct softpipe_buffer
{
struct pipe_buffer base;
boolean userBuffer; /** Is this a user-space buffer? */
void *data;
};
#include "pipe/p_defines.h"
struct pipe_screen;
struct pipe_winsys;
struct pipe_context;
struct pipe_texture;
struct pipe_buffer;
/**
* 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);
/** Cast wrapper */
static INLINE struct softpipe_buffer *
softpipe_buffer( struct pipe_buffer *buf )
{
return (struct softpipe_buffer *)buf;
}
boolean
softpipe_get_texture_buffer( struct pipe_texture *texture,
struct pipe_buffer **buf,
unsigned *stride );
void
softpipe_init_screen_buffer_funcs(struct pipe_screen *screen);
#ifdef __cplusplus
}
#endif
#endif /* SP_WINSYS_H */
#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);
}
/* Note: leave drawing surfaces mapped */
softpipe_unmap_constant_buffers(sp);
/*
* 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 */
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;
spt->buffer = screen->surface_buffer_create( screen,
spt->base.width0,