st/glx: Use st_api.h instead of st_public.h.

This commit is contained in:
Chia-I Wu
2010-03-10 17:22:56 +08:00
parent a924dd18c3
commit 576d9af505
6 changed files with 470 additions and 165 deletions
+2 -1
View File
@@ -11,6 +11,7 @@ C_SOURCES = \
glx_api.c \
glx_getproc.c \
glx_usefont.c \
xm_api.c
xm_api.c \
xm_st.c
include ../../../Makefile.template
@@ -35,12 +35,9 @@
#include "xm_api.h"
#include "main/context.h"
#include "main/config.h"
#include "main/macros.h"
#include "main/imports.h"
#include "main/version.h"
#include "state_tracker/st_context.h"
#include "state_tracker/st_public.h"
/* This indicates the client-side GLX API and GLX encoder version. */
@@ -1304,7 +1301,7 @@ glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
if (MakeCurrent_PrevContext == src) {
_mesa_Flush();
}
st_copy_context_state( xm_src->st, xm_dst->st, (GLuint) mask );
XMesaCopyContext(xm_src, xm_dst, mask);
}
+132 -133
View File
@@ -54,11 +54,9 @@
#endif
#include "xm_api.h"
#include "main/context.h"
#include "main/framebuffer.h"
#include "xm_st.h"
#include "state_tracker/st_public.h"
#include "state_tracker/st_context.h"
#include "main/context.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
#include "pipe/p_context.h"
@@ -84,6 +82,8 @@ void xmesa_set_driver( const struct xm_driver *templ )
pipe_mutex _xmesa_lock;
static struct pipe_screen *screen = NULL;
static struct st_api *stapi = NULL;
static struct st_manager *smapi = NULL;
/**********************************************************************/
@@ -273,49 +273,49 @@ choose_pixel_format(XMesaVisual v)
return 0;
}
/**
* Query the default gallium screen for a Z/Stencil format that
* at least matches the given depthBits and stencilBits.
* Choose a depth/stencil format for the given depth and stencil sizes.
*/
static void
xmesa_choose_z_stencil_format(int depthBits, int stencilBits,
enum pipe_format *depthFormat,
enum pipe_format *stencilFormat)
static enum pipe_format
choose_depth_stencil_format(int depth, int stencil)
{
const enum pipe_texture_target target = PIPE_TEXTURE_2D;
const unsigned tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
const unsigned geom_flags = (PIPE_TEXTURE_GEOM_NON_SQUARE |
PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO);
static enum pipe_format formats[] = {
PIPE_FORMAT_S8Z24_UNORM,
PIPE_FORMAT_Z24S8_UNORM,
PIPE_FORMAT_Z16_UNORM,
PIPE_FORMAT_Z32_UNORM
};
int i;
enum pipe_format formats[8], fmt;
int count, i;
assert(screen);
*depthFormat = *stencilFormat = PIPE_FORMAT_NONE;
count = 0;
switch (depth) {
case 16:
if (!stencil)
formats[count++] = PIPE_FORMAT_Z16_UNORM;
break;
case 24:
formats[count++] = PIPE_FORMAT_S8Z24_UNORM;
formats[count++] = PIPE_FORMAT_Z24S8_UNORM;
break;
case 32:
if (!stencil)
formats[count++] = PIPE_FORMAT_Z32_UNORM;
break;
default:
break;
}
/* search for supported format */
for (i = 0; i < Elements(formats); i++) {
fmt = PIPE_FORMAT_NONE;
for (i = 0; i < count; i++) {
if (screen->is_format_supported(screen, formats[i],
target, tex_usage, geom_flags)) {
*depthFormat = formats[i];
fmt = formats[i];
break;
}
}
if (stencilBits) {
*stencilFormat = *depthFormat;
}
/* XXX we should check that he chosen format has at least as many bits
* as what was requested.
*/
return fmt;
}
@@ -343,12 +343,14 @@ create_xmesa_buffer(Drawable d, BufferType type,
XMesaVisual vis, Colormap cmap)
{
XMesaBuffer b;
GLframebuffer *fb;
enum pipe_format colorFormat, depthFormat, stencilFormat;
uint width, height;
ASSERT(type == WINDOW || type == PIXMAP || type == PBUFFER);
xmesa_init(vis->display);
if (!screen)
return NULL;
b = (XMesaBuffer) CALLOC_STRUCT(xmesa_buffer);
if (!b)
return NULL;
@@ -361,24 +363,12 @@ create_xmesa_buffer(Drawable d, BufferType type,
b->type = type;
b->cmap = cmap;
/* determine PIPE_FORMATs for buffers */
colorFormat = choose_pixel_format(vis);
xmesa_choose_z_stencil_format(vis->mesa_visual.depthBits,
vis->mesa_visual.stencilBits,
&depthFormat, &stencilFormat);
get_drawable_size(vis->display, d, &width, &height);
/*
* Create framebuffer, but we'll plug in our own renderbuffers below.
*/
b->stfb = st_create_framebuffer(&vis->mesa_visual,
colorFormat, depthFormat, stencilFormat,
width, height,
(void *) b);
fb = &b->stfb->Base;
b->stfb = xmesa_create_st_framebuffer(screen, b);
/* GLX_EXT_texture_from_pixmap */
b->TextureTarget = 0;
@@ -422,24 +412,21 @@ xmesa_free_buffer(XMesaBuffer buffer)
for (b = XMesaBufferList; b; b = b->Next) {
if (b == buffer) {
struct gl_framebuffer *fb = &buffer->stfb->Base;
/* unlink buffer from list */
if (prev)
prev->Next = buffer->Next;
else
XMesaBufferList = buffer->Next;
/* mark as delete pending */
fb->DeletePending = GL_TRUE;
/* Since the X window for the XMesaBuffer is going away, we don't
* want to dereference this pointer in the future.
*/
b->ws.drawable = 0;
/* Unreference. If count = zero we'll really delete the buffer */
_mesa_reference_framebuffer(&fb, NULL);
/* XXX we should move the buffer to a delete-pending list and destroy
* the buffer until it is no longer current.
*/
xmesa_destroy_st_framebuffer(buffer->stfb);
free(buffer);
@@ -681,6 +668,26 @@ XMesaVisual XMesaCreateVisual( Display *display,
accum_blue_size, accum_alpha_size,
0 );
v->stvis.buffer_mask = ST_ATTACHMENT_FRONT_LEFT_MASK;
if (db_flag)
v->stvis.buffer_mask = ST_ATTACHMENT_BACK_LEFT_MASK;
if (stereo_flag) {
v->stvis.buffer_mask = ST_ATTACHMENT_FRONT_RIGHT_MASK;
if (db_flag)
v->stvis.buffer_mask = ST_ATTACHMENT_BACK_RIGHT_MASK;
}
v->stvis.color_format = choose_pixel_format(v);
v->stvis.depth_stencil_format =
choose_depth_stencil_format(depth_size, stencil_size);
v->stvis.accum_format = (accum_red_size +
accum_green_size + accum_blue_size + accum_alpha_size) ?
PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;
v->stvis.samples = num_samples;
v->stvis.render_buffer = ST_ATTACHMENT_INVALID;
/* XXX minor hack */
v->mesa_visual.level = level;
return v;
@@ -705,6 +712,26 @@ xmesa_init( Display *display )
if (firstTime) {
pipe_mutex_init(_xmesa_lock);
screen = driver.create_pipe_screen( display );
stapi = xmesa_create_st_api();
smapi = CALLOC_STRUCT(st_manager);
if (smapi)
smapi->screen = screen;
if (!screen || !stapi || !smapi) {
if (screen) {
screen->destroy(screen);
screen = NULL;
}
if (stapi) {
stapi->destroy(stapi);
stapi = NULL;
}
if (smapi) {
FREE(smapi);
smapi = NULL;
}
}
firstTime = GL_FALSE;
}
}
@@ -720,10 +747,7 @@ xmesa_init( Display *display )
PUBLIC
XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
{
struct pipe_context *pipe = NULL;
XMesaContext c;
GLcontext *mesaCtx;
uint pf;
xmesa_init( v->display );
@@ -732,9 +756,6 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
if (!c)
return NULL;
pf = choose_pixel_format(v);
assert(pf);
c->xm_visual = v;
c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */
c->xm_read_buffer = NULL;
@@ -742,29 +763,18 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
if (screen == NULL)
goto fail;
/* Trace screen knows how to properly wrap context creation in the
* wrapped screen, so nothing special to do here:
*/
pipe = screen->context_create(screen, (void *) c);
if (pipe == NULL)
goto fail;
c->st = st_create_context(pipe,
&v->mesa_visual,
share_list ? share_list->st : NULL);
c->st = stapi->create_context(stapi, smapi,
&v->stvis, (share_list) ? share_list->st : NULL);
if (c->st == NULL)
goto fail;
mesaCtx = c->st->ctx;
c->st->ctx->DriverCtx = c;
c->st->st_manager_private = (void *) c;
return c;
fail:
if (c->st)
st_destroy_context(c->st);
else if (pipe)
pipe->destroy(pipe);
c->st->destroy(c->st);
free(c);
return NULL;
@@ -775,7 +785,7 @@ fail:
PUBLIC
void XMesaDestroyContext( XMesaContext c )
{
st_destroy_context(c->st);
c->st->destroy(c->st);
/* FIXME: We should destroy the screen here, but if we do so, surfaces may
* outlive it, causing segfaults
@@ -881,7 +891,6 @@ XMesaCreatePixmapTextureBuffer(XMesaVisual v, Pixmap p,
{
GET_CURRENT_CONTEXT(ctx);
XMesaBuffer b;
GLuint width, height;
assert(v);
@@ -889,19 +898,18 @@ XMesaCreatePixmapTextureBuffer(XMesaVisual v, Pixmap p,
if (!b)
return NULL;
/* get pixmap size, update framebuffer/renderbuffer dims */
xmesa_get_window_size(v->display, b, &width, &height);
_mesa_resize_framebuffer(NULL, &(b->stfb->Base), width, height);
/* get pixmap size */
xmesa_get_window_size(v->display, b, &b->width, &b->height);
if (target == 0) {
/* examine dims */
if (ctx->Extensions.ARB_texture_non_power_of_two) {
target = GLX_TEXTURE_2D_EXT;
}
else if ( _mesa_bitcount(width) == 1
&& _mesa_bitcount(height) == 1) {
else if ( _mesa_bitcount(b->width) == 1
&& _mesa_bitcount(b->height) == 1) {
/* power of two size */
if (height == 1) {
if (b->height == 1) {
target = GLX_TEXTURE_1D_EXT;
}
else {
@@ -974,25 +982,22 @@ XMesaDestroyBuffer(XMesaBuffer b)
/**
* Query the current window size and update the corresponding GLframebuffer
* and all attached renderbuffers.
* Called when:
* 1. the first time a buffer is bound to a context.
* 2. SwapBuffers. XXX probabaly from xm_flush_frontbuffer() too...
* Note: it's possible (and legal) for xmctx to be NULL. That can happen
* when resizing a buffer when no rendering context is bound.
* Query the current drawable size and notify the binding context.
*/
void
xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer)
xmesa_check_buffer_size(XMesaBuffer b)
{
GLuint width, height;
xmesa_get_window_size(drawBuffer->xm_visual->display, drawBuffer, &width, &height);
st_resize_framebuffer(drawBuffer->stfb, width, height);
XMesaContext xmctx = XMesaGetCurrentContext();
if (b->type == PBUFFER)
return;
xmesa_get_window_size(b->xm_visual->display, b, &b->width, &b->height);
if (xmctx && xmctx->xm_buffer == b)
xmctx->st->notify_invalid_framebuffer(xmctx->st, b->stfb);
}
/*
* Bind buffer b to context c and make c the current rendering context.
*/
@@ -1017,22 +1022,21 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer,
c->xm_read_buffer == readBuffer)
return GL_TRUE;
xmesa_check_buffer_size(drawBuffer);
if (readBuffer != drawBuffer)
xmesa_check_buffer_size(readBuffer);
c->xm_buffer = drawBuffer;
c->xm_read_buffer = readBuffer;
st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb,
&drawBuffer->ws);
xmesa_check_and_update_buffer_size(c, drawBuffer);
if (readBuffer != drawBuffer)
xmesa_check_and_update_buffer_size(c, readBuffer);
stapi->make_current(stapi, c->st, drawBuffer->stfb, readBuffer->stfb);
/* Solution to Stephane Rehel's problem with glXReleaseBuffersMESA(): */
drawBuffer->wasCurrent = GL_TRUE;
}
else {
/* Detach */
st_make_current( NULL, NULL, NULL, NULL );
stapi->make_current(stapi, NULL, NULL, NULL);
}
return GL_TRUE;
@@ -1051,14 +1055,8 @@ GLboolean XMesaUnbindContext( XMesaContext c )
XMesaContext XMesaGetCurrentContext( void )
{
GET_CURRENT_CONTEXT(ctx);
if (ctx) {
XMesaContext xmesa = xmesa_context(ctx);
return xmesa;
}
else {
return 0;
}
struct st_context_iface *st = stapi->get_current(stapi);
return (XMesaContext) (st) ? st->st_manager_private : NULL;
}
@@ -1070,17 +1068,17 @@ XMesaContext XMesaGetCurrentContext( void )
PUBLIC
void XMesaSwapBuffers( XMesaBuffer b )
{
struct pipe_surface *frontLeftSurf;
XMesaContext xmctx = XMesaGetCurrentContext();
st_swapbuffers(b->stfb, &frontLeftSurf, NULL);
if (frontLeftSurf) {
screen->flush_frontbuffer( screen,
frontLeftSurf,
&b->ws );
if (xmctx && xmctx->xm_buffer == b) {
xmctx->st->flush( xmctx->st,
PIPE_FLUSH_RENDER_CACHE |
PIPE_FLUSH_SWAPBUFFERS |
PIPE_FLUSH_FRAME,
NULL);
}
xmesa_check_and_update_buffer_size(NULL, b);
xmesa_swap_st_framebuffer(b->stfb);
}
@@ -1090,21 +1088,9 @@ void XMesaSwapBuffers( XMesaBuffer b )
*/
void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
{
struct pipe_surface *surf_front;
struct pipe_surface *surf_back;
struct pipe_context *pipe = NULL; /* XXX fix */
st_get_framebuffer_surface(b->stfb, ST_SURFACE_FRONT_LEFT, &surf_front);
st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT, &surf_back);
if (!surf_front || !surf_back)
return;
assert(pipe);
pipe->surface_copy(pipe,
surf_front, x, y, /* dest */
surf_back, x, y, /* src */
width, height);
xmesa_copy_st_framebuffer(b->stfb,
ST_ATTACHMENT_BACK_LEFT, ST_ATTACHMENT_FRONT_LEFT,
x, y, width, height);
}
@@ -1112,7 +1098,13 @@ void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height )
void XMesaFlush( XMesaContext c )
{
if (c && c->xm_visual->display) {
st_finish(c->st);
struct pipe_fence_handle *fence = NULL;
c->st->flush(c->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence);
if (fence) {
screen->fence_finish(screen, fence, 0);
screen->fence_reference(screen, &fence, NULL);
}
XSync( c->xm_visual->display, False );
}
}
@@ -1186,3 +1178,10 @@ XMesaReleaseTexImage(Display *dpy, XMesaBuffer drawable, int buffer)
{
}
void
XMesaCopyContext(XMesaContext src, XMesaContext dst, unsigned long mask)
{
if (dst->st->copy)
dst->st->copy(dst->st, src->st, mask);
}
+12 -27
View File
@@ -58,8 +58,7 @@ and create a window, you must do the following to use the X/Mesa interface:
#include "main/mtypes.h"
#include "state_tracker/st_context.h"
#include "state_tracker/st_public.h"
#include "state_tracker/st_api.h"
#include "os/os_thread.h"
#include "state_tracker/xlib_sw_winsys.h"
@@ -258,6 +257,8 @@ XMesaCreatePixmapTextureBuffer(XMesaVisual v, Pixmap p,
int format, int target, int mipmap);
extern void
XMesaCopyContext(XMesaContext src, XMesaContext dst, unsigned long mask);
/***********************************************************************
@@ -280,6 +281,8 @@ struct xmesa_visual {
GLint BitsPerPixel; /* True bits per pixel for XImages */
GLboolean ximage_flag; /* Use XImage for back buffer (not pixmap)? */
struct st_visual stvis;
};
@@ -288,7 +291,7 @@ struct xmesa_visual {
* Basically corresponds to a GLXContext.
*/
struct xmesa_context {
struct st_context *st;
struct st_context_iface *st;
XMesaVisual xm_visual; /** pixel format info */
XMesaBuffer xm_buffer; /** current drawbuffer */
XMesaBuffer xm_read_buffer; /** current readbuffer */
@@ -311,7 +314,7 @@ typedef enum {
* Basically corresponds to a GLXDrawable.
*/
struct xmesa_buffer {
struct st_framebuffer *stfb;
struct st_framebuffer_iface *stfb;
struct xlib_drawable ws;
GLboolean wasCurrent; /* was ever the current buffer? */
@@ -335,33 +338,15 @@ struct xmesa_buffer {
GLint TextureMipmap; /** 0 or 1 */
struct xmesa_buffer *Next; /* Linked list pointer: */
unsigned width, height;
};
/** cast wrapper */
static INLINE XMesaContext
xmesa_context(GLcontext *ctx)
{
return (XMesaContext) ctx->DriverCtx;
}
/** cast wrapper */
static INLINE XMesaBuffer
xmesa_buffer(GLframebuffer *fb)
{
struct st_framebuffer *stfb = (struct st_framebuffer *) fb;
return (XMesaBuffer) st_framebuffer_private(stfb);
}
extern void
xmesa_init(Display *dpy);
extern void
xmesa_delete_framebuffer(struct gl_framebuffer *fb);
extern XMesaBuffer
xmesa_find_buffer(Display *dpy, Colormap cmap, XMesaBuffer notThis);
@@ -370,7 +355,7 @@ xmesa_get_window_size(Display *dpy, XMesaBuffer b,
GLuint *width, GLuint *height);
extern void
xmesa_check_and_update_buffer_size(XMesaContext xmctx, XMesaBuffer drawBuffer);
xmesa_check_buffer_size(XMesaBuffer b);
extern void
xmesa_destroy_buffers_on_display(Display *dpy);
@@ -378,13 +363,13 @@ xmesa_destroy_buffers_on_display(Display *dpy);
static INLINE GLuint
xmesa_buffer_width(XMesaBuffer b)
{
return b->stfb->Base.Width;
return b->width;
}
static INLINE GLuint
xmesa_buffer_height(XMesaBuffer b)
{
return b->stfb->Base.Height;
return b->height;
}
+269
View File
@@ -0,0 +1,269 @@
/*
* Mesa 3-D graphics library
* Version: 7.9
*
* Copyright (C) 2010 LunarG Inc.
*
* 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, sublicense,
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL 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.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "xm_api.h"
#include "xm_st.h"
/* support OpenGL by default */
#ifndef XMESA_ST_MODULE
#define XMESA_ST_MODULE st_module_OpenGL
#endif
struct xmesa_st_framebuffer {
struct pipe_screen *screen;
XMesaBuffer buffer;
struct st_visual stvis;
unsigned texture_width, texture_height;
struct pipe_texture *textures[ST_ATTACHMENT_COUNT];
struct pipe_surface *display_surface;
};
static INLINE struct xmesa_st_framebuffer *
xmesa_st_framebuffer(struct st_framebuffer_iface *stfbi)
{
return (struct xmesa_st_framebuffer *) stfbi->st_manager_private;
}
/**
* Display an attachment to the xlib_drawable of the framebuffer.
*/
static boolean
xmesa_st_framebuffer_display(struct st_framebuffer_iface *stfbi,
enum st_attachment_type statt)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
struct pipe_texture *ptex = xstfb->textures[statt];
struct pipe_surface *psurf;
if (!ptex)
return TRUE;
psurf = xstfb->display_surface;
/* (re)allocate the surface for the texture to be displayed */
if (!psurf || psurf->texture != ptex) {
pipe_surface_reference(&xstfb->display_surface, NULL);
psurf = xstfb->screen->get_tex_surface(xstfb->screen,
ptex, 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ);
if (!psurf)
return FALSE;
xstfb->display_surface = psurf;
}
xstfb->screen->flush_frontbuffer(xstfb->screen, psurf, &xstfb->buffer->ws);
return TRUE;
}
/**
* Remove outdated textures and create the requested ones.
*/
static void
xmesa_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
const enum st_attachment_type *statts,
unsigned count)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
struct pipe_texture templ;
unsigned request_mask, i;
request_mask = 0;
for (i = 0; i < count; i++)
request_mask |= 1 << statts[i];
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
templ.width0 = xstfb->texture_width;
templ.height0 = xstfb->texture_height;
templ.depth0 = 1;
templ.last_level = 0;
for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
struct pipe_texture *ptex = xstfb->textures[i];
enum pipe_format format;
unsigned tex_usage;
/* remove outdated textures */
if (ptex && (ptex->width0 != xstfb->texture_width ||
ptex->height0 != xstfb->texture_height)) {
pipe_texture_reference(&xstfb->textures[i], NULL);
ptex = NULL;
}
/* the texture already exists or not requested */
if (ptex || !(request_mask & (1 << i)))
continue;
switch (i) {
case ST_ATTACHMENT_FRONT_LEFT:
case ST_ATTACHMENT_BACK_LEFT:
case ST_ATTACHMENT_FRONT_RIGHT:
case ST_ATTACHMENT_BACK_RIGHT:
format = xstfb->stvis.color_format;
tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_RENDER_TARGET;
break;
case ST_ATTACHMENT_DEPTH_STENCIL:
format = xstfb->stvis.depth_stencil_format;
tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL;
break;
default:
format = PIPE_FORMAT_NONE;
break;
}
if (format != PIPE_FORMAT_NONE) {
templ.format = format;
templ.tex_usage = tex_usage;
xstfb->textures[i] =
xstfb->screen->texture_create(xstfb->screen, &templ);
}
}
}
static boolean
xmesa_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
const enum st_attachment_type *statts,
unsigned count,
struct pipe_texture **out)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
unsigned i;
/* revalidate textures */
if (xstfb->buffer->width != xstfb->texture_width ||
xstfb->buffer->height != xstfb->texture_height) {
xstfb->texture_width = xstfb->buffer->width;
xstfb->texture_height = xstfb->buffer->height;
xmesa_st_framebuffer_validate_textures(stfbi, statts, count);
}
for (i = 0; i < count; i++) {
out[i] = NULL;
pipe_texture_reference(&out[i], xstfb->textures[statts[i]]);
}
return TRUE;
}
static boolean
xmesa_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi,
enum st_attachment_type statt)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
boolean ret;
ret = xmesa_st_framebuffer_flush_front(stfbi, statt);
if (ret)
xmesa_check_buffer_size(xstfb->buffer);
return ret;
}
struct st_framebuffer_iface *
xmesa_create_st_framebuffer(struct pipe_screen *screen, XMesaBuffer b)
{
struct st_framebuffer_iface *stfbi;
struct xmesa_st_framebuffer *xstfb;
stfbi = CALLOC_STRUCT(st_framebuffer_iface);
xstfb = CALLOC_STRUCT(xmesa_st_framebuffer);
if (!stfbi || !xstfb) {
if (stfbi)
FREE(stfbi);
if (xstfb)
FREE(xstfb);
return NULL;
}
xstfb->screen = screen;
xstfb->buffer = b;
xstfb->stvis = b->xm_visual->stvis;
stfbi->visual = &xstfb->stvis;
stfbi->flush_front = xmesa_st_framebuffer_flush_front;
stfbi->validate = xmesa_st_framebuffer_validate;
stfbi->st_manager_private = (void *) xstfb;
return stfbi;
}
void
xmesa_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
FREE(xstfb);
FREE(stfbi);
}
void
xmesa_swap_st_framebuffer(struct st_framebuffer_iface *stfbi)
{
struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi);
boolean ret;
ret = xmesa_st_framebuffer_display(stfbi, ST_ATTACHMENT_BACK_LEFT);
if (ret) {
struct pipe_texture **front, **back, *tmp;
front = &xstfb->textures[ST_ATTACHMENT_FRONT_LEFT];
back = &xstfb->textures[ST_ATTACHMENT_BACK_LEFT];
/* swap textures only if the front texture has been allocated */
if (*front) {
tmp = *front;
*front = *back;
*back = tmp;
}
xmesa_check_buffer_size(xstfb->buffer);
}
}
void
xmesa_copy_st_framebuffer(struct st_framebuffer_iface *stfbi,
enum st_attachment_type src,
enum st_attachment_type dst,
int x, int y, int w, int h)
{
/* TODO */
}
struct st_api *
xmesa_create_st_api(void)
{
return XMESA_ST_MODULE.create_api();
}
@@ -0,0 +1,54 @@
/*
* Mesa 3-D graphics library
* Version: 7.9
*
* Copyright (C) 2010 LunarG Inc.
*
* 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, sublicense,
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL 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.
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
*/
#ifndef _XM_ST_H_
#define _XM_ST_H_
#include "pipe/p_compiler.h"
#include "state_tracker/st_api.h"
#include "xm_api.h"
struct st_api *
xmesa_create_st_api(void);
struct st_framebuffer_iface *
xmesa_create_st_framebuffer(struct pipe_screen *screen, XMesaBuffer b);
void
xmesa_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi);
void
xmesa_swap_st_framebuffer(struct st_framebuffer_iface *stfbi);
void
xmesa_copy_st_framebuffer(struct st_framebuffer_iface *stfbi,
enum st_attachment_type src,
enum st_attachment_type dst,
int x, int y, int w, int h);
#endif /* _XM_ST_H_ */