Merge branch 'mesa_7_5_branch'

This commit is contained in:
Jakob Bornecrantz 2009-07-04 07:43:01 +02:00
commit 28471cfa97
14 changed files with 380 additions and 181 deletions

View file

@ -39,6 +39,12 @@
#include <GL/gl.h>
#include <GL/glx.h>
#ifndef GLX_MESA_swap_control
#define GLX_MESA_swap_control 1
typedef int (*PFNGLXGETSWAPINTERVALMESAPROC)(void);
#endif
static int is_glx_extension_supported(Display *dpy, const char *query);
static void query_vsync(Display *dpy);
@ -592,31 +598,22 @@ query_vsync(Display *dpy)
int interval = 0;
#ifdef GLX_MESA_swap_control
if ((interval <= 0)
&& is_glx_extension_supported(dpy, "GLX_MESA_swap_control")) {
if (is_glx_extension_supported(dpy, "GLX_MESA_swap_control")) {
PFNGLXGETSWAPINTERVALMESAPROC pglXGetSwapIntervalMESA =
(PFNGLXGETSWAPINTERVALMESAPROC)
glXGetProcAddressARB((const GLubyte *) "glXGetSwapIntervalMESA");
interval = (*pglXGetSwapIntervalMESA)();
} else if (is_glx_extension_supported(dpy, "GLX_SGI_swap_control")) {
/* The default swap interval with this extension is 1. Assume that it
* is set to the default.
*
* Many Mesa-based drivers default to 0, but all of these drivers also
* export GLX_MESA_swap_control. In that case, this branch will never
* be taken, and the correct result should be reported.
*/
interval = 1;
}
#endif
#ifdef GLX_SGI_video_sync
if ((interval <= 0)
&& is_glx_extension_supported(dpy, "GLX_SGI_video_sync")) {
PFNGLXGETVIDEOSYNCSGIPROC pglXGetVideoSyncSGI =
(PFNGLXGETVIDEOSYNCSGIPROC)
glXGetProcAddressARB((const GLubyte *) "glXGetVideoSyncSGI");
unsigned count;
if ((*pglXGetVideoSyncSGI)(& count) == 0) {
interval = (int) count;
}
}
#endif
if (interval > 0) {

View file

@ -1202,6 +1202,19 @@ pipe_put_tile_z(struct pipe_transfer *pt,
}
break;
case PIPE_FORMAT_S8Z24_UNORM:
{
uint *pDest = (uint *) (map + y * pt->stride + x*4);
assert(pt->usage == PIPE_TRANSFER_READ_WRITE);
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
/* convert 32-bit Z to 24-bit Z, preserve stencil */
pDest[j] = (pDest[j] & 0xff000000) | ptrc[j] >> 8;
}
pDest += pt->stride/4;
ptrc += srcStride;
}
}
break;
case PIPE_FORMAT_X8Z24_UNORM:
{
uint *pDest = (uint *) (map + y * pt->stride + x*4);
@ -1216,13 +1229,26 @@ pipe_put_tile_z(struct pipe_transfer *pt,
}
break;
case PIPE_FORMAT_Z24S8_UNORM:
{
uint *pDest = (uint *) (map + y * pt->stride + x*4);
assert(pt->usage == PIPE_TRANSFER_READ_WRITE);
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
/* convert 32-bit Z to 24-bit Z, preserve stencil */
pDest[j] = (pDest[j] & 0xff) | (ptrc[j] & 0xffffff00);
}
pDest += pt->stride/4;
ptrc += srcStride;
}
}
break;
case PIPE_FORMAT_Z24X8_UNORM:
{
uint *pDest = (uint *) (map + y * pt->stride + x*4);
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
/* convert 32-bit Z to 24-bit Z (0 stencil) */
pDest[j] = ptrc[j] << 8;
pDest[j] = ptrc[j] & 0xffffff00;
}
pDest += pt->stride/4;
ptrc += srcStride;

View file

@ -60,8 +60,14 @@ stw_context(GLcontext *glctx)
static INLINE struct stw_context *
stw_current_context(void)
{
GET_CURRENT_CONTEXT( glctx );
return stw_context(glctx);
/* We must check if multiple threads are being used or GET_CURRENT_CONTEXT
* might return the current context of the thread first seen. */
_glapi_check_multithread();
{
GET_CURRENT_CONTEXT( glctx );
return stw_context(glctx);
}
}
BOOL
@ -74,7 +80,7 @@ stw_copy_context(
struct stw_context *dst;
BOOL ret = FALSE;
pipe_mutex_lock( stw_dev->mutex );
pipe_mutex_lock( stw_dev->ctx_mutex );
src = stw_lookup_context_locked( hglrcSrc );
dst = stw_lookup_context_locked( hglrcDst );
@ -87,7 +93,7 @@ stw_copy_context(
(void) mask;
}
pipe_mutex_unlock( stw_dev->mutex );
pipe_mutex_unlock( stw_dev->ctx_mutex );
return ret;
}
@ -101,7 +107,7 @@ stw_share_lists(
struct stw_context *ctx2;
BOOL ret = FALSE;
pipe_mutex_lock( stw_dev->mutex );
pipe_mutex_lock( stw_dev->ctx_mutex );
ctx1 = stw_lookup_context_locked( hglrc1 );
ctx2 = stw_lookup_context_locked( hglrc2 );
@ -111,7 +117,7 @@ stw_share_lists(
ret = _mesa_share_state(ctx2->st->ctx, ctx1->st->ctx);
}
pipe_mutex_unlock( stw_dev->mutex );
pipe_mutex_unlock( stw_dev->ctx_mutex );
return ret;
}
@ -124,8 +130,10 @@ stw_viewport(GLcontext * glctx, GLint x, GLint y,
struct stw_framebuffer *fb;
fb = stw_framebuffer_from_hdc( ctx->hdc );
if(fb)
if(fb) {
stw_framebuffer_update(fb);
stw_framebuffer_release(fb);
}
}
UINT_PTR
@ -189,9 +197,9 @@ stw_create_layer_context(
ctx->st->ctx->DriverCtx = ctx;
ctx->st->ctx->Driver.Viewport = stw_viewport;
pipe_mutex_lock( stw_dev->mutex );
pipe_mutex_lock( stw_dev->ctx_mutex );
ctx->hglrc = handle_table_add(stw_dev->ctx_table, ctx);
pipe_mutex_unlock( stw_dev->mutex );
pipe_mutex_unlock( stw_dev->ctx_mutex );
if (!ctx->hglrc)
goto no_hglrc;
@ -218,10 +226,10 @@ stw_delete_context(
if (!stw_dev)
return FALSE;
pipe_mutex_lock( stw_dev->mutex );
pipe_mutex_lock( stw_dev->ctx_mutex );
ctx = stw_lookup_context_locked(hglrc);
handle_table_remove(stw_dev->ctx_table, hglrc);
pipe_mutex_unlock( stw_dev->mutex );
pipe_mutex_unlock( stw_dev->ctx_mutex );
if (ctx) {
struct stw_context *curctx = stw_current_context();
@ -248,9 +256,9 @@ stw_release_context(
if (!stw_dev)
return FALSE;
pipe_mutex_lock( stw_dev->mutex );
pipe_mutex_lock( stw_dev->ctx_mutex );
ctx = stw_lookup_context_locked( hglrc );
pipe_mutex_unlock( stw_dev->mutex );
pipe_mutex_unlock( stw_dev->ctx_mutex );
if (!ctx)
return FALSE;
@ -298,9 +306,9 @@ stw_make_current(
HDC hdc,
UINT_PTR hglrc )
{
struct stw_context *curctx;
struct stw_context *ctx;
struct stw_framebuffer *fb;
struct stw_context *curctx = NULL;
struct stw_context *ctx = NULL;
struct stw_framebuffer *fb = NULL;
if (!stw_dev)
goto fail;
@ -322,13 +330,13 @@ stw_make_current(
return st_make_current( NULL, NULL, NULL );
}
pipe_mutex_lock( stw_dev->mutex );
pipe_mutex_lock( stw_dev->ctx_mutex );
ctx = stw_lookup_context_locked( hglrc );
pipe_mutex_unlock( stw_dev->ctx_mutex );
if(!ctx)
goto fail;
fb = stw_framebuffer_from_hdc_locked( hdc );
fb = stw_framebuffer_from_hdc( hdc );
if(!fb) {
/* Applications should call SetPixelFormat before creating a context,
* but not all do, and the opengl32 runtime seems to use a default pixel
@ -336,13 +344,11 @@ stw_make_current(
*/
int iPixelFormat = GetPixelFormat(hdc);
if(iPixelFormat)
fb = stw_framebuffer_create_locked( hdc, iPixelFormat );
fb = stw_framebuffer_create( hdc, iPixelFormat );
if(!fb)
goto fail;
}
pipe_mutex_unlock( stw_dev->mutex );
if(fb->iPixelFormat != ctx->iPixelFormat)
goto fail;
@ -361,12 +367,16 @@ stw_make_current(
success:
assert(fb);
if(fb)
if(fb) {
stw_framebuffer_update(fb);
stw_framebuffer_release(fb);
}
return TRUE;
fail:
if(fb)
stw_framebuffer_release(fb);
st_make_current( NULL, NULL, NULL );
return FALSE;
}

View file

@ -69,8 +69,6 @@ stw_flush_frontbuffer(struct pipe_screen *screen,
fb = stw_framebuffer_from_hdc( hdc );
/* fb can be NULL if window was destroyed already */
if (fb) {
pipe_mutex_lock( fb->mutex );
#if DEBUG
{
struct pipe_surface *surface2;
@ -94,8 +92,7 @@ stw_flush_frontbuffer(struct pipe_screen *screen,
if(fb) {
stw_framebuffer_update(fb);
pipe_mutex_unlock( fb->mutex );
stw_framebuffer_release(fb);
}
}
@ -138,7 +135,8 @@ stw_init(const struct stw_winsys *stw_winsys)
stw_dev->screen->flush_frontbuffer = &stw_flush_frontbuffer;
pipe_mutex_init( stw_dev->mutex );
pipe_mutex_init( stw_dev->ctx_mutex );
pipe_mutex_init( stw_dev->fb_mutex );
stw_dev->ctx_table = handle_table_create();
if (!stw_dev->ctx_table) {
@ -179,7 +177,7 @@ stw_cleanup(void)
if (!stw_dev)
return;
pipe_mutex_lock( stw_dev->mutex );
pipe_mutex_lock( stw_dev->ctx_mutex );
{
/* Ensure all contexts are destroyed */
i = handle_table_get_first_handle(stw_dev->ctx_table);
@ -189,11 +187,12 @@ stw_cleanup(void)
}
handle_table_destroy(stw_dev->ctx_table);
}
pipe_mutex_unlock( stw_dev->mutex );
pipe_mutex_unlock( stw_dev->ctx_mutex );
stw_framebuffer_cleanup();
pipe_mutex_destroy( stw_dev->mutex );
pipe_mutex_destroy( stw_dev->fb_mutex );
pipe_mutex_destroy( stw_dev->ctx_mutex );
stw_dev->screen->destroy(stw_dev->screen);

View file

@ -57,10 +57,10 @@ struct stw_device
unsigned pixelformat_count;
unsigned pixelformat_extended_count;
pipe_mutex mutex;
pipe_mutex ctx_mutex;
struct handle_table *ctx_table;
pipe_mutex fb_mutex;
struct stw_framebuffer *fb_head;
#ifdef DEBUG

View file

@ -45,6 +45,10 @@
#include "stw_tls.h"
/**
* Search the framebuffer with the matching HWND while holding the
* stw_dev::fb_mutex global lock.
*/
static INLINE struct stw_framebuffer *
stw_framebuffer_from_hwnd_locked(
HWND hwnd )
@ -52,13 +56,20 @@ stw_framebuffer_from_hwnd_locked(
struct stw_framebuffer *fb;
for (fb = stw_dev->fb_head; fb != NULL; fb = fb->next)
if (fb->hWnd == hwnd)
if (fb->hWnd == hwnd) {
pipe_mutex_lock(fb->mutex);
break;
}
return fb;
}
/**
* Destroy this framebuffer. Both stw_dev::fb_mutex and stw_framebuffer::mutex
* must be held, by this order. Obviously no further access to fb can be done
* after this.
*/
static INLINE void
stw_framebuffer_destroy_locked(
struct stw_framebuffer *fb )
@ -74,68 +85,24 @@ stw_framebuffer_destroy_locked(
st_unreference_framebuffer(fb->stfb);
pipe_mutex_unlock( fb->mutex );
pipe_mutex_destroy( fb->mutex );
FREE( fb );
}
/**
* @sa http://msdn.microsoft.com/en-us/library/ms644975(VS.85).aspx
* @sa http://msdn.microsoft.com/en-us/library/ms644960(VS.85).aspx
*/
LRESULT CALLBACK
stw_call_window_proc(
int nCode,
WPARAM wParam,
LPARAM lParam )
void
stw_framebuffer_release(
struct stw_framebuffer *fb)
{
struct stw_tls_data *tls_data;
PCWPSTRUCT pParams = (PCWPSTRUCT)lParam;
tls_data = stw_tls_get_data();
if(!tls_data)
return 0;
if (nCode < 0)
return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam);
if (pParams->message == WM_SIZE && pParams->wParam != SIZE_MINIMIZED) {
struct stw_framebuffer *fb;
pipe_mutex_lock( stw_dev->mutex );
fb = stw_framebuffer_from_hwnd_locked( pParams->hwnd );
pipe_mutex_unlock( stw_dev->mutex );
if(fb) {
unsigned width = LOWORD( pParams->lParam );
unsigned height = HIWORD( pParams->lParam );
pipe_mutex_lock( fb->mutex );
fb->must_resize = TRUE;
fb->width = width;
fb->height = height;
pipe_mutex_unlock( fb->mutex );
}
}
if (pParams->message == WM_DESTROY) {
struct stw_framebuffer *fb;
pipe_mutex_lock( stw_dev->mutex );
fb = stw_framebuffer_from_hwnd_locked( pParams->hwnd );
if(fb)
stw_framebuffer_destroy_locked(fb);
pipe_mutex_unlock( stw_dev->mutex );
}
return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam);
assert(fb);
pipe_mutex_unlock( fb->mutex );
}
static void
static INLINE void
stw_framebuffer_get_size( struct stw_framebuffer *fb )
{
unsigned width, height;
@ -161,10 +128,57 @@ stw_framebuffer_get_size( struct stw_framebuffer *fb )
/**
* Create a new framebuffer object which will correspond to the given HDC.
* @sa http://msdn.microsoft.com/en-us/library/ms644975(VS.85).aspx
* @sa http://msdn.microsoft.com/en-us/library/ms644960(VS.85).aspx
*/
LRESULT CALLBACK
stw_call_window_proc(
int nCode,
WPARAM wParam,
LPARAM lParam )
{
struct stw_tls_data *tls_data;
PCWPSTRUCT pParams = (PCWPSTRUCT)lParam;
struct stw_framebuffer *fb;
tls_data = stw_tls_get_data();
if(!tls_data)
return 0;
if (nCode < 0)
return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam);
if (pParams->message == WM_WINDOWPOSCHANGED) {
/* We handle WM_WINDOWPOSCHANGED instead of WM_SIZE because according to
* http://blogs.msdn.com/oldnewthing/archive/2008/01/15/7113860.aspx
* WM_SIZE is generated from WM_WINDOWPOSCHANGED by DefWindowProc so it
* can be masked out by the application. */
LPWINDOWPOS lpWindowPos = (LPWINDOWPOS)pParams->lParam;
if((lpWindowPos->flags & SWP_SHOWWINDOW) ||
!(lpWindowPos->flags & SWP_NOSIZE)) {
fb = stw_framebuffer_from_hwnd( pParams->hwnd );
if(fb) {
/* Size in WINDOWPOS includes the window frame, so get the size
* of the client area via GetClientRect. */
stw_framebuffer_get_size(fb);
stw_framebuffer_release(fb);
}
}
}
else if (pParams->message == WM_DESTROY) {
pipe_mutex_lock( stw_dev->fb_mutex );
fb = stw_framebuffer_from_hwnd_locked( pParams->hwnd );
if(fb)
stw_framebuffer_destroy_locked(fb);
pipe_mutex_unlock( stw_dev->fb_mutex );
}
return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam);
}
struct stw_framebuffer *
stw_framebuffer_create_locked(
stw_framebuffer_create(
HDC hdc,
int iPixelFormat )
{
@ -193,8 +207,16 @@ stw_framebuffer_create_locked(
pipe_mutex_init( fb->mutex );
/* This is the only case where we lock the stw_framebuffer::mutex before
* stw_dev::fb_mutex, since no other thread can know about this framebuffer
* and we must prevent any other thread from destroying it before we return.
*/
pipe_mutex_lock( fb->mutex );
pipe_mutex_lock( stw_dev->fb_mutex );
fb->next = stw_dev->fb_head;
stw_dev->fb_head = fb;
pipe_mutex_unlock( stw_dev->fb_mutex );
return fb;
}
@ -204,8 +226,8 @@ BOOL
stw_framebuffer_allocate(
struct stw_framebuffer *fb)
{
pipe_mutex_lock( fb->mutex );
assert(fb);
if(!fb->stfb) {
const struct stw_pixelformat_info *pfi = fb->pfi;
enum pipe_format colorFormat, depthFormat, stencilFormat;
@ -241,8 +263,6 @@ stw_framebuffer_allocate(
fb->must_resize = TRUE;
}
pipe_mutex_unlock( fb->mutex );
return fb->stfb ? TRUE : FALSE;
}
@ -279,24 +299,27 @@ stw_framebuffer_cleanup( void )
struct stw_framebuffer *fb;
struct stw_framebuffer *next;
pipe_mutex_lock( stw_dev->mutex );
pipe_mutex_lock( stw_dev->fb_mutex );
fb = stw_dev->fb_head;
while (fb) {
next = fb->next;
pipe_mutex_lock(fb->mutex);
stw_framebuffer_destroy_locked(fb);
fb = next;
}
stw_dev->fb_head = NULL;
pipe_mutex_unlock( stw_dev->mutex );
pipe_mutex_unlock( stw_dev->fb_mutex );
}
/**
* Given an hdc, return the corresponding stw_framebuffer.
*/
struct stw_framebuffer *
static INLINE struct stw_framebuffer *
stw_framebuffer_from_hdc_locked(
HDC hdc )
{
@ -313,8 +336,10 @@ stw_framebuffer_from_hdc_locked(
return stw_framebuffer_from_hwnd_locked(hwnd);
for (fb = stw_dev->fb_head; fb != NULL; fb = fb->next)
if (fb->hDC == hdc)
if (fb->hDC == hdc) {
pipe_mutex_lock(fb->mutex);
break;
}
return fb;
}
@ -329,9 +354,26 @@ stw_framebuffer_from_hdc(
{
struct stw_framebuffer *fb;
pipe_mutex_lock( stw_dev->mutex );
pipe_mutex_lock( stw_dev->fb_mutex );
fb = stw_framebuffer_from_hdc_locked(hdc);
pipe_mutex_unlock( stw_dev->mutex );
pipe_mutex_unlock( stw_dev->fb_mutex );
return fb;
}
/**
* Given an hdc, return the corresponding stw_framebuffer.
*/
struct stw_framebuffer *
stw_framebuffer_from_hwnd(
HWND hwnd )
{
struct stw_framebuffer *fb;
pipe_mutex_lock( stw_dev->fb_mutex );
fb = stw_framebuffer_from_hwnd_locked(hwnd);
pipe_mutex_unlock( stw_dev->fb_mutex );
return fb;
}
@ -351,22 +393,19 @@ stw_pixelformat_set(
if (index >= count)
return FALSE;
pipe_mutex_lock( stw_dev->mutex );
fb = stw_framebuffer_from_hdc_locked(hdc);
if(fb) {
/* SetPixelFormat must be called only once */
pipe_mutex_unlock( stw_dev->mutex );
stw_framebuffer_release( fb );
return FALSE;
}
fb = stw_framebuffer_create_locked(hdc, iPixelFormat);
fb = stw_framebuffer_create(hdc, iPixelFormat);
if(!fb) {
pipe_mutex_unlock( stw_dev->mutex );
return FALSE;
}
pipe_mutex_unlock( stw_dev->mutex );
stw_framebuffer_release( fb );
/* Some applications mistakenly use the undocumented wglSetPixelFormat
* function instead of SetPixelFormat, so we call SetPixelFormat here to
@ -383,13 +422,16 @@ int
stw_pixelformat_get(
HDC hdc )
{
int iPixelFormat = 0;
struct stw_framebuffer *fb;
fb = stw_framebuffer_from_hdc(hdc);
if(!fb)
return 0;
if(fb) {
iPixelFormat = fb->iPixelFormat;
stw_framebuffer_release(fb);
}
return fb->iPixelFormat;
return iPixelFormat;
}
@ -405,10 +447,10 @@ stw_swap_buffers(
if (fb == NULL)
return FALSE;
if (!(fb->pfi->pfd.dwFlags & PFD_DOUBLEBUFFER))
if (!(fb->pfi->pfd.dwFlags & PFD_DOUBLEBUFFER)) {
stw_framebuffer_release(fb);
return TRUE;
pipe_mutex_lock( fb->mutex );
}
/* If we're swapping the buffer associated with the current context
* we have to flush any pending rendering commands first.
@ -419,7 +461,7 @@ stw_swap_buffers(
if(!st_get_framebuffer_surface( fb->stfb, ST_SURFACE_BACK_LEFT, &surface )) {
/* FIXME: this shouldn't happen, but does on glean */
pipe_mutex_unlock( fb->mutex );
stw_framebuffer_release(fb);
return FALSE;
}
@ -433,8 +475,7 @@ stw_swap_buffers(
stw_dev->stw_winsys->flush_frontbuffer( screen, surface, hdc );
stw_framebuffer_update(fb);
pipe_mutex_unlock( fb->mutex );
stw_framebuffer_release(fb);
return TRUE;
}

View file

@ -41,6 +41,23 @@ struct stw_pixelformat_info;
*/
struct stw_framebuffer
{
/**
* This mutex has two purposes:
* - protect the access to the mutable data members below
* - prevent the the framebuffer from being deleted while being accessed.
*
* It is OK to lock this mutex while holding the stw_device::fb_mutex lock,
* but the opposite must never happen.
*/
pipe_mutex mutex;
/*
* Immutable members.
*
* Note that even access to immutable members implies acquiring the mutex
* above, to prevent the framebuffer from being destroyed.
*/
HDC hDC;
HWND hWnd;
@ -48,7 +65,10 @@ struct stw_framebuffer
const struct stw_pixelformat_info *pfi;
GLvisual visual;
pipe_mutex mutex;
/*
* Mutable members.
*/
struct st_framebuffer *stfb;
/* FIXME: Make this work for multiple contexts bound to the same framebuffer */
@ -56,15 +76,52 @@ struct stw_framebuffer
unsigned width;
unsigned height;
/** This is protected by stw_device::mutex, not the mutex above */
/**
* This is protected by stw_device::fb_mutex, not the mutex above.
*
* Deletions must be done by first acquiring stw_device::fb_mutex, and then
* acquiring the stw_framebuffer::mutex of the framebuffer to be deleted.
* This ensures that nobody else is reading/writing to the.
*
* It is not necessary to aquire the mutex above to navigate the linked list
* given that deletions are done with stw_device::fb_mutex held, so no other
* thread can delete.
*/
struct stw_framebuffer *next;
};
/**
* Create a new framebuffer object which will correspond to the given HDC.
*
* This function will acquire stw_framebuffer::mutex. stw_framebuffer_release
* must be called when done
*/
struct stw_framebuffer *
stw_framebuffer_create_locked(
stw_framebuffer_create(
HDC hdc,
int iPixelFormat );
/**
* Search a framebuffer with a matching HWND.
*
* This function will acquire stw_framebuffer::mutex. stw_framebuffer_release
* must be called when done
*/
struct stw_framebuffer *
stw_framebuffer_from_hwnd(
HWND hwnd );
/**
* Search a framebuffer with a matching HDC.
*
* This function will acquire stw_framebuffer::mutex. stw_framebuffer_release
* must be called when done
*/
struct stw_framebuffer *
stw_framebuffer_from_hdc(
HDC hdc );
BOOL
stw_framebuffer_allocate(
struct stw_framebuffer *fb );
@ -73,15 +130,19 @@ void
stw_framebuffer_update(
struct stw_framebuffer *fb);
/**
* Release stw_framebuffer::mutex lock. This framebuffer must not be accessed
* after calling this function, as it may have been deleted by another thread
* in the meanwhile.
*/
void
stw_framebuffer_release(
struct stw_framebuffer *fb);
/**
* Cleanup any existing framebuffers when exiting application.
*/
void
stw_framebuffer_cleanup(void);
struct stw_framebuffer *
stw_framebuffer_from_hdc_locked(
HDC hdc );
struct stw_framebuffer *
stw_framebuffer_from_hdc(
HDC hdc );
#endif /* STW_FRAMEBUFFER_H */

View file

@ -305,6 +305,7 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
drm_handle_t hFB;
int junk;
const __DRIconfig **driver_configs;
__GLcontextModes *visual;
/* DRI protocol version. */
dri_version.major = driDpy->driMajor;
@ -417,6 +418,28 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
/* Visuals with depth != screen depth are subject to automatic compositing
* in the X server, so DRI1 can't render to them properly. Mark them as
* non-conformant to prevent apps from picking them up accidentally.
*/
for (visual = psc->visuals; visual; visual = visual->next) {
XVisualInfo template;
XVisualInfo *visuals;
int num_visuals;
long mask;
template.visualid = visual->visualID;
mask = VisualIDMask;
visuals = XGetVisualInfo(dpy, mask, &template, &num_visuals);
if (visuals) {
if (num_visuals > 0 && visuals->depth != DefaultDepth(dpy, scrn))
visual->visualRating = GLX_NON_CONFORMANT_CONFIG;
XFree(visuals);
}
}
return psp;
handle_error:

View file

@ -137,22 +137,15 @@ find_translated_vp(struct st_context *st,
for (inAttr = 0; inAttr < FRAG_ATTRIB_MAX; inAttr++) {
if (fragInputsRead & (1 << inAttr)) {
stfp->input_to_slot[inAttr] = numIn;
numIn++;
if ((fragInputsRead & FRAG_BIT_FOGC)) {
if (stfp->Base.UsesPointCoord) {
stfp->input_to_slot[inAttr] = numIn;
numIn++;
/* leave placeholders for the
* extra registers we extract from fog */
if (stfp->Base.UsesFrontFacing ||
stfp->Base.UsesPointCoord) {
numIn += 2;
}
if (stfp->Base.UsesFrontFacing) {
stfp->input_to_slot[inAttr] = numIn;
numIn++;
}
if (stfp->Base.UsesFogFragCoord) {
stfp->input_to_slot[inAttr] = numIn;
numIn++;
}
} else {
stfp->input_to_slot[inAttr] = numIn;
numIn++;
}
}
else {

View file

@ -1037,10 +1037,16 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
st_cond_flush_get_tex_transfer(st, rbRead->texture, 0, 0, 0,
PIPE_TRANSFER_READ, srcx, srcy, width,
height);
struct pipe_transfer *ptTex;
enum pipe_transfer_usage transfer_usage;
struct pipe_transfer *ptTex =
st_cond_flush_get_tex_transfer(st, pt, 0, 0, 0, PIPE_TRANSFER_WRITE,
0, 0, width, height);
if (type == GL_DEPTH && pf_is_depth_and_stencil(pt->format))
transfer_usage = PIPE_TRANSFER_READ_WRITE;
else
transfer_usage = PIPE_TRANSFER_WRITE;
ptTex = st_cond_flush_get_tex_transfer(st, pt, 0, 0, 0, transfer_usage,
0, 0, width, height);
if (type == GL_COLOR) {
/* alternate path using get/put_tile() */

View file

@ -529,6 +529,7 @@ st_TexImage(GLcontext * ctx,
GLint texelBytes, sizeInBytes;
GLuint dstRowStride;
struct gl_pixelstore_attrib unpackNB;
enum pipe_transfer_usage transfer_usage;
DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(target), level, width, height, depth, border);
@ -680,8 +681,14 @@ st_TexImage(GLcontext * ctx,
}
if (stImage->pt) {
if (format == GL_DEPTH_COMPONENT &&
pf_is_depth_and_stencil(stImage->pt->format))
transfer_usage = PIPE_TRANSFER_READ_WRITE;
else
transfer_usage = PIPE_TRANSFER_WRITE;
texImage->Data = st_texture_image_map(ctx->st, stImage, 0,
PIPE_TRANSFER_WRITE, 0, 0,
transfer_usage, 0, 0,
stImage->base.Width,
stImage->base.Height);
if(stImage->transfer)
@ -742,7 +749,7 @@ st_TexImage(GLcontext * ctx,
st_texture_image_unmap(ctx->st, stImage);
/* map next slice of 3D texture */
texImage->Data = st_texture_image_map(ctx->st, stImage, i + 1,
PIPE_TRANSFER_WRITE, 0, 0,
transfer_usage, 0, 0,
stImage->base.Width,
stImage->base.Height);
src += srcImageStride;
@ -1041,6 +1048,7 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level,
_mesa_image_image_stride(packing, width, height, format, type);
GLint i;
const GLubyte *src;
enum pipe_transfer_usage transfer_usage;
DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(target),
@ -1072,10 +1080,16 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level,
* from uploading the buffer under us.
*/
if (stImage->pt) {
if (format == GL_DEPTH_COMPONENT &&
pf_is_depth_and_stencil(stImage->pt->format))
transfer_usage = PIPE_TRANSFER_READ_WRITE;
else
transfer_usage = PIPE_TRANSFER_WRITE;
st_teximage_flush_before_map(ctx->st, stImage->pt, 0, level,
PIPE_TRANSFER_WRITE);
transfer_usage);
texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset,
PIPE_TRANSFER_WRITE,
transfer_usage,
xoffset, yoffset,
width, height);
}
@ -1106,7 +1120,7 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level,
/* map next slice of 3D texture */
texImage->Data = st_texture_image_map(ctx->st, stImage,
zoffset + i + 1,
PIPE_TRANSFER_WRITE,
transfer_usage,
xoffset, yoffset,
width, height);
src += srcImageStride;
@ -1274,6 +1288,7 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level,
struct pipe_screen *screen = pipe->screen;
struct pipe_transfer *src_trans;
GLvoid *texDest;
enum pipe_transfer_usage transfer_usage;
assert(width <= MAX_WIDTH);
@ -1288,10 +1303,16 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level,
srcX, srcY,
width, height);
st_teximage_flush_before_map(ctx->st, stImage->pt, 0, 0,
PIPE_TRANSFER_WRITE);
if (baseFormat == GL_DEPTH_COMPONENT &&
pf_is_depth_and_stencil(stImage->pt->format))
transfer_usage = PIPE_TRANSFER_READ_WRITE;
else
transfer_usage = PIPE_TRANSFER_WRITE;
texDest = st_texture_image_map(ctx->st, stImage, 0, PIPE_TRANSFER_WRITE,
st_teximage_flush_before_map(ctx->st, stImage->pt, 0, 0,
transfer_usage);
texDest = st_texture_image_map(ctx->st, stImage, 0, transfer_usage,
destX, destY, width, height);
if (baseFormat == GL_DEPTH_COMPONENT ||

View file

@ -280,7 +280,8 @@ st_notify_swapbuffers(struct st_framebuffer *stfb)
PIPE_FLUSH_SWAPBUFFERS |
PIPE_FLUSH_FRAME,
NULL );
ctx->st->frontbuffer_status = FRONT_STATUS_COPY_OF_BACK;
if (st_renderbuffer(stfb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer))
ctx->st->frontbuffer_status = FRONT_STATUS_COPY_OF_BACK;
}
}

View file

@ -122,8 +122,15 @@ map_register_file_index(
SWIZZLE_X,
SWIZZLE_X,
SWIZZLE_X);
/* register after fog */
return inputMapping[index] + 1;
} else {
/* fixme: point coord */
*swizzle = MAKE_SWIZZLE4(SWIZZLE_Z,
SWIZZLE_W,
SWIZZLE_Z,
SWIZZLE_W);
/* register after frontface */
return inputMapping[index] + 2;
}
}
/* inputs are mapped according to the user-defined map */

View file

@ -453,20 +453,34 @@ st_translate_fragment_program(struct st_context *st,
stfp->input_semantic_index[slot] = 1;
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
break;
case FRAG_ATTRIB_FOGC:
if (stfp->Base.UsesPointCoord) {
stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
stfp->input_semantic_index[slot] = num_generic++;
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
} else if (stfp->Base.UsesFrontFacing) {
stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FACE;
stfp->input_semantic_index[slot] = 0;
interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
} else {
case FRAG_ATTRIB_FOGC: {
int extra_decls = 0;
if (stfp->Base.UsesFogFragCoord) {
stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
stfp->input_semantic_index[slot] = 0;
interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
input_flags[slot] = stfp->Base.Base.InputFlags[attr];
++extra_decls;
}
if (stfp->Base.UsesFrontFacing) {
GLint idx = slot + extra_decls;
stfp->input_semantic_name[idx] = TGSI_SEMANTIC_FACE;
stfp->input_semantic_index[idx] = 0;
interpMode[idx] = TGSI_INTERPOLATE_CONSTANT;
input_flags[idx] = stfp->Base.Base.InputFlags[attr];
++extra_decls;
}
if (stfp->Base.UsesPointCoord) {
GLint idx = slot + extra_decls;
stfp->input_semantic_name[idx] = TGSI_SEMANTIC_GENERIC;
stfp->input_semantic_index[idx] = num_generic++;
interpMode[idx] = TGSI_INTERPOLATE_PERSPECTIVE;
input_flags[idx] = stfp->Base.Base.InputFlags[attr];
++extra_decls;
}
fs_num_inputs += extra_decls - 1;
continue;
}
break;
case FRAG_ATTRIB_TEX0:
case FRAG_ATTRIB_TEX1: