From 192f06adca5e79b4824d92dc41186592ed57f71e Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Wed, 17 Mar 2010 10:11:22 +0800 Subject: [PATCH] st/wgl: Switch from st_public.h to st_api.h. [V2] This is only compile tested with crossmingw. V2: - reference count stw_framebuffer --- src/gallium/state_trackers/wgl/SConscript | 1 + src/gallium/state_trackers/wgl/stw_context.c | 125 ++++--- src/gallium/state_trackers/wgl/stw_context.h | 10 +- src/gallium/state_trackers/wgl/stw_device.c | 43 +-- src/gallium/state_trackers/wgl/stw_device.h | 5 + .../state_trackers/wgl/stw_ext_pixelformat.c | 4 +- .../state_trackers/wgl/stw_framebuffer.c | 99 +++--- .../state_trackers/wgl/stw_framebuffer.h | 18 +- .../state_trackers/wgl/stw_pixelformat.c | 47 +-- .../state_trackers/wgl/stw_pixelformat.h | 11 +- src/gallium/state_trackers/wgl/stw_st.c | 306 ++++++++++++++++++ src/gallium/state_trackers/wgl/stw_st.h | 47 +++ 12 files changed, 519 insertions(+), 197 deletions(-) create mode 100644 src/gallium/state_trackers/wgl/stw_st.c create mode 100644 src/gallium/state_trackers/wgl/stw_st.h diff --git a/src/gallium/state_trackers/wgl/SConscript b/src/gallium/state_trackers/wgl/SConscript index 352c087475e..f59f3a9638a 100644 --- a/src/gallium/state_trackers/wgl/SConscript +++ b/src/gallium/state_trackers/wgl/SConscript @@ -28,6 +28,7 @@ if env['platform'] in ['windows']: 'stw_framebuffer.c', 'stw_getprocaddress.c', 'stw_pixelformat.c', + 'stw_st.c', 'stw_tls.c', 'stw_wgl.c', ] diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c index 1f11b649c3e..663d8b8090c 100644 --- a/src/gallium/state_trackers/wgl/stw_context.c +++ b/src/gallium/state_trackers/wgl/stw_context.c @@ -27,12 +27,13 @@ #include -#include "main/mtypes.h" -#include "main/context.h" #include "pipe/p_compiler.h" #include "pipe/p_context.h" +#include "state_tracker/st_api.h" + +/* for _mesa_share_state */ #include "state_tracker/st_context.h" -#include "state_tracker/st_public.h" +#include "main/context.h" #include "stw_icd.h" #include "stw_device.h" @@ -43,26 +44,14 @@ #include "stw_tls.h" -static INLINE struct stw_context * -stw_context(GLcontext *glctx) -{ - if(!glctx) - return NULL; - assert(glctx->DriverCtx); - return (struct stw_context *)glctx->DriverCtx; -} - static INLINE struct stw_context * stw_current_context(void) { - /* 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(); + struct st_context_iface *st; - { - GET_CURRENT_CONTEXT( glctx ); - return stw_context(glctx); - } + st = (stw_dev) ? stw_dev->stapi->get_current(stw_dev->stapi) : NULL; + + return (struct stw_context *) ((st) ? st->st_manager_private : NULL); } BOOL APIENTRY @@ -114,7 +103,11 @@ DrvShareLists( ctx2 = stw_lookup_context_locked( dhglrc2 ); if (ctx1 && ctx2) { - ret = _mesa_share_state(ctx2->st->ctx, ctx1->st->ctx); + struct st_context *st1, *st2; + + st1 = (struct st_context *) ctx1->st; + st2 = (struct st_context *) ctx2->st; + ret = _mesa_share_state(st2->ctx, st1->ctx); } pipe_mutex_unlock( stw_dev->ctx_mutex ); @@ -122,20 +115,6 @@ DrvShareLists( return ret; } -static void -stw_viewport(GLcontext * glctx, GLint x, GLint y, - GLsizei width, GLsizei height) -{ - struct stw_context *ctx = (struct stw_context *)glctx->DriverCtx; - struct stw_framebuffer *fb; - - fb = stw_framebuffer_from_hdc( ctx->hdc ); - if(fb) { - stw_framebuffer_update(fb); - stw_framebuffer_release(fb); - } -} - DHGLRC APIENTRY DrvCreateContext( HDC hdc ) @@ -150,9 +129,7 @@ DrvCreateLayerContext( { int iPixelFormat; const struct stw_pixelformat_info *pfi; - GLvisual visual; struct stw_context *ctx = NULL; - struct pipe_context *pipe = NULL; if(!stw_dev) return 0; @@ -165,7 +142,6 @@ DrvCreateLayerContext( return 0; pfi = stw_pixelformat_get_info( iPixelFormat - 1 ); - stw_pixelformat_visual(&visual, pfi); ctx = CALLOC_STRUCT( stw_context ); if (ctx == NULL) @@ -174,18 +150,12 @@ DrvCreateLayerContext( ctx->hdc = hdc; ctx->iPixelFormat = iPixelFormat; - /* priv == hdc, pass to stw_flush_frontbuffer as context_private - */ - pipe = stw_dev->screen->context_create( stw_dev->screen, hdc ); - if (pipe == NULL) - goto no_pipe; - - ctx->st = st_create_context( pipe, &visual, NULL ); + ctx->st = stw_dev->stapi->create_context(stw_dev->stapi, + stw_dev->smapi, &pfi->stvis, NULL); if (ctx->st == NULL) goto no_st_ctx; - ctx->st->ctx->DriverCtx = ctx; - ctx->st->ctx->Driver.Viewport = stw_viewport; + ctx->st->st_manager_private = (void *) ctx; pipe_mutex_lock( stw_dev->ctx_mutex ); ctx->dhglrc = handle_table_add(stw_dev->ctx_table, ctx); @@ -196,11 +166,8 @@ DrvCreateLayerContext( return ctx->dhglrc; no_hglrc: - st_destroy_context(ctx->st); - goto no_pipe; /* st_context_destroy already destroys pipe */ + ctx->st->destroy(ctx->st); no_st_ctx: - pipe->destroy( pipe ); -no_pipe: FREE(ctx); no_ctx: return 0; @@ -226,9 +193,9 @@ DrvDeleteContext( /* Unbind current if deleting current context. */ if (curctx == ctx) - st_make_current( NULL, NULL, NULL, NULL ); + stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL); - st_destroy_context(ctx->st); + ctx->st->destroy(ctx->st); FREE(ctx); ret = TRUE; @@ -306,7 +273,7 @@ stw_make_current( curctx = stw_current_context(); if (curctx != NULL) { if (curctx->dhglrc != dhglrc) - st_flush(curctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + curctx->st->flush(curctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); /* Return if already current. */ if (curctx->dhglrc == dhglrc && curctx->hdc == hdc) { @@ -314,10 +281,12 @@ stw_make_current( fb = stw_framebuffer_from_hdc( hdc ); goto success; } + + stw_framebuffer_reference(&curctx->current_framebuffer, NULL); } if (hdc == NULL || dhglrc == 0) { - return st_make_current( NULL, NULL, NULL, NULL ); + return stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL); } pipe_mutex_lock( stw_dev->ctx_mutex ); @@ -327,7 +296,10 @@ stw_make_current( goto fail; fb = stw_framebuffer_from_hdc( hdc ); - if(!fb) { + if (fb) { + stw_framebuffer_update(fb); + } + else { /* Applications should call SetPixelFormat before creating a context, * but not all do, and the opengl32 runtime seems to use a default pixel * format in some cases, so we must create a framebuffer for those here @@ -342,23 +314,17 @@ stw_make_current( if(fb->iPixelFormat != ctx->iPixelFormat) goto fail; - /* Lazy allocation of the frame buffer */ - if(!stw_framebuffer_allocate(fb)) - goto fail; - /* Bind the new framebuffer */ ctx->hdc = hdc; - /* pass to stw_flush_frontbuffer as context_private */ - ctx->st->pipe->priv = hdc; - - if(!st_make_current( ctx->st, fb->stfb, fb->stfb, hdc )) + if (!stw_dev->stapi->make_current(stw_dev->stapi, ctx->st, fb->stfb, fb->stfb)) goto fail; + stw_framebuffer_reference(&curctx->current_framebuffer, fb); + success: assert(fb); if(fb) { - stw_framebuffer_update(fb); stw_framebuffer_release(fb); } @@ -367,10 +333,39 @@ success: fail: if(fb) stw_framebuffer_release(fb); - st_make_current( NULL, NULL, NULL, NULL ); + stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL); return FALSE; } +/** + * Flush the current context if it is bound to the framebuffer. + */ +void +stw_flush_current_locked( struct stw_framebuffer *fb ) +{ + struct stw_context *ctx = stw_current_context(); + + if (ctx && ctx->current_framebuffer == fb) { + ctx->st->flush(ctx->st, + PIPE_FLUSH_RENDER_CACHE | + PIPE_FLUSH_SWAPBUFFERS | + PIPE_FLUSH_FRAME, + NULL); + } +} + +/** + * Notify the current context that the framebuffer has become invalid. + */ +void +stw_notify_current_locked( struct stw_framebuffer *fb ) +{ + struct stw_context *ctx = stw_current_context(); + + if (ctx && ctx->current_framebuffer == fb) + ctx->st->notify_invalid_framebuffer(ctx->st, fb->stfb); +} + /** * Although WGL allows different dispatch entrypoints per context */ diff --git a/src/gallium/state_trackers/wgl/stw_context.h b/src/gallium/state_trackers/wgl/stw_context.h index 256c27e21ef..0bbed84104a 100644 --- a/src/gallium/state_trackers/wgl/stw_context.h +++ b/src/gallium/state_trackers/wgl/stw_context.h @@ -30,14 +30,17 @@ #include -struct st_context; +struct stw_framebuffer; +struct st_context_iface; struct stw_context { - struct st_context *st; + struct st_context_iface *st; DHGLRC dhglrc; int iPixelFormat; HDC hdc; + + struct stw_framebuffer *current_framebuffer; }; DHGLRC stw_get_current_context( void ); @@ -46,4 +49,7 @@ HDC stw_get_current_dc( void ); BOOL stw_make_current( HDC hdc, DHGLRC dhglrc ); +void stw_flush_current_locked( struct stw_framebuffer *fb ); +void stw_notify_current_locked( struct stw_framebuffer *fb ); + #endif /* STW_CONTEXT_H */ diff --git a/src/gallium/state_trackers/wgl/stw_device.c b/src/gallium/state_trackers/wgl/stw_device.c index ea300f27cb5..61b207525ca 100644 --- a/src/gallium/state_trackers/wgl/stw_device.c +++ b/src/gallium/state_trackers/wgl/stw_device.c @@ -30,8 +30,8 @@ #include "glapi/glthread.h" #include "util/u_debug.h" #include "util/u_math.h" +#include "util/u_memory.h" #include "pipe/p_screen.h" -#include "state_tracker/st_public.h" #include "stw_device.h" #include "stw_winsys.h" @@ -39,6 +39,7 @@ #include "stw_icd.h" #include "stw_tls.h" #include "stw_framebuffer.h" +#include "stw_st.h" #ifdef WIN32_THREADS extern _glthread_Mutex OneTimeLock; @@ -48,28 +49,6 @@ extern _glthread_Mutex OneTimeLock; struct stw_device *stw_dev = NULL; -/** - * XXX: Dispatch pipe_screen::flush_front_buffer to our - * stw_winsys::flush_front_buffer. - */ -static void -stw_flush_frontbuffer(struct pipe_screen *screen, - struct pipe_surface *surface, - void *context_private ) -{ - HDC hdc = (HDC)context_private; - struct stw_framebuffer *fb; - - fb = stw_framebuffer_from_hdc( hdc ); - if (!fb) { - /* fb can be NULL if window was destroyed already */ - return; - } - - stw_framebuffer_present_locked(hdc, fb, surface); -} - - boolean stw_init(const struct stw_winsys *stw_winsys) { @@ -95,6 +74,11 @@ stw_init(const struct stw_winsys *stw_winsys) _glthread_INIT_MUTEX(OneTimeLock); #endif + stw_dev->stapi = stw_st_create_api(); + stw_dev->smapi = CALLOC_STRUCT(st_manager); + if (!stw_dev->stapi || !stw_dev->smapi) + goto error1; + screen = stw_winsys->create_screen(); if(!screen) goto error1; @@ -102,12 +86,9 @@ stw_init(const struct stw_winsys *stw_winsys) if(stw_winsys->get_adapter_luid) stw_winsys->get_adapter_luid(screen, &stw_dev->AdapterLuid); + stw_dev->smapi->screen = screen; stw_dev->screen = screen; - /* XXX - */ - stw_dev->screen->flush_frontbuffer = &stw_flush_frontbuffer; - pipe_mutex_init( stw_dev->ctx_mutex ); pipe_mutex_init( stw_dev->fb_mutex ); @@ -121,6 +102,11 @@ stw_init(const struct stw_winsys *stw_winsys) return TRUE; error1: + if (stw_dev->smapi) + FREE(stw_dev->smapi); + if (stw_dev->stapi) + stw_dev->stapi->destroy(stw_dev->stapi); + stw_dev = NULL; return FALSE; } @@ -170,6 +156,9 @@ stw_cleanup(void) pipe_mutex_destroy( stw_dev->fb_mutex ); pipe_mutex_destroy( stw_dev->ctx_mutex ); + FREE(stw_dev->smapi); + stw_dev->stapi->destroy(stw_dev->stapi); + stw_dev->screen->destroy(stw_dev->screen); #ifdef WIN32_THREADS diff --git a/src/gallium/state_trackers/wgl/stw_device.h b/src/gallium/state_trackers/wgl/stw_device.h index 2e9ba197dfa..1b836960d0d 100644 --- a/src/gallium/state_trackers/wgl/stw_device.h +++ b/src/gallium/state_trackers/wgl/stw_device.h @@ -40,6 +40,8 @@ struct pipe_screen; +struct st_api; +struct st_manager; struct stw_framebuffer; struct stw_device @@ -48,6 +50,9 @@ struct stw_device struct pipe_screen *screen; + struct st_api *stapi; + struct st_manager *smapi; + LUID AdapterLuid; struct stw_pixelformat_info pixelformats[STW_MAX_PIXELFORMATS]; diff --git a/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c b/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c index 8a9995aba8e..ab56800e28d 100644 --- a/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c +++ b/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c @@ -227,11 +227,11 @@ stw_query_attrib( break; case WGL_SAMPLE_BUFFERS_ARB: - *pvalue = pfi->numSampleBuffers; + *pvalue = 1; break; case WGL_SAMPLES_ARB: - *pvalue = pfi->numSamples; + *pvalue = pfi->stvis.samples; break; default: diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.c b/src/gallium/state_trackers/wgl/stw_framebuffer.c index 4f1629de2f2..259b22f22c7 100644 --- a/src/gallium/state_trackers/wgl/stw_framebuffer.c +++ b/src/gallium/state_trackers/wgl/stw_framebuffer.c @@ -27,18 +27,19 @@ #include -#include "main/context.h" #include "pipe/p_format.h" #include "pipe/p_screen.h" #include "util/u_format.h" -#include "state_tracker/st_context.h" -#include "state_tracker/st_public.h" +#include "util/u_memory.h" +#include "state_tracker/st_api.h" #include "stw_icd.h" #include "stw_framebuffer.h" #include "stw_device.h" #include "stw_winsys.h" #include "stw_tls.h" +#include "stw_context.h" +#include "stw_st.h" /** @@ -63,8 +64,8 @@ stw_framebuffer_from_hwnd_locked( /** * 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. + * must be held, by this order. If there are still references to the + * framebuffer, nothing will happen. */ static INLINE void stw_framebuffer_destroy_locked( @@ -72,6 +73,13 @@ stw_framebuffer_destroy_locked( { struct stw_framebuffer **link; + /* check the reference count */ + fb->refcnt--; + if (fb->refcnt) { + pipe_mutex_unlock( fb->mutex ); + return; + } + link = &stw_dev->fb_head; while (*link != fb) link = &(*link)->next; @@ -82,7 +90,7 @@ stw_framebuffer_destroy_locked( if(fb->shared_surface) stw_dev->stw_winsys->shared_surface_close(stw_dev->screen, fb->shared_surface); - st_unreference_framebuffer(fb->stfb); + stw_st_destroy_framebuffer_locked(fb->stfb); pipe_mutex_unlock( fb->mutex ); @@ -230,9 +238,14 @@ stw_framebuffer_create( fb->iPixelFormat = iPixelFormat; fb->pfi = pfi = stw_pixelformat_get_info( iPixelFormat - 1 ); + fb->stfb = stw_st_create_framebuffer( fb ); + if (!fb->stfb) { + FREE( fb ); + return NULL; + } + + fb->refcnt = 1; - stw_pixelformat_visual(&fb->visual, pfi); - stw_framebuffer_get_size(fb); pipe_mutex_init( fb->mutex ); @@ -251,47 +264,31 @@ stw_framebuffer_create( return fb; } - -BOOL -stw_framebuffer_allocate( +/** + * Have ptr reference fb. The referenced framebuffer should be locked. + */ +void +stw_framebuffer_reference( + struct stw_framebuffer **ptr, struct stw_framebuffer *fb) { - assert(fb); - - if(!fb->stfb) { - const struct stw_pixelformat_info *pfi = fb->pfi; - enum pipe_format colorFormat, depthFormat, stencilFormat; + struct stw_framebuffer *old_fb = *ptr; - colorFormat = pfi->color_format; + if (old_fb == fb) + return; - if(util_format_get_component_bits(pfi->depth_stencil_format, UTIL_FORMAT_COLORSPACE_ZS, 0)) - depthFormat = pfi->depth_stencil_format; - else - depthFormat = PIPE_FORMAT_NONE; - - if(util_format_get_component_bits(pfi->depth_stencil_format, UTIL_FORMAT_COLORSPACE_ZS, 1)) - stencilFormat = pfi->depth_stencil_format; - else - stencilFormat = PIPE_FORMAT_NONE; - - assert(fb->must_resize); - assert(fb->width); - assert(fb->height); - - fb->stfb = st_create_framebuffer( - &fb->visual, - colorFormat, - depthFormat, - stencilFormat, - fb->width, - fb->height, - (void *) fb ); - - // to notify the context - fb->must_resize = TRUE; + if (fb) + fb->refcnt++; + if (old_fb) { + pipe_mutex_lock(stw_dev->fb_mutex); + + pipe_mutex_lock(old_fb->mutex); + stw_framebuffer_destroy_locked(old_fb); + + pipe_mutex_unlock(stw_dev->fb_mutex); } - - return fb->stfb ? TRUE : FALSE; + + *ptr = fb; } @@ -313,11 +310,6 @@ stw_framebuffer_update( * to know of their existing without using the not very portable PSAPI. */ stw_framebuffer_get_size(fb); - - if(fb->must_resize) { - st_resize_framebuffer(fb->stfb, fb->width, fb->height); - fb->must_resize = FALSE; - } } @@ -516,6 +508,7 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data) } stw_framebuffer_update(fb); + stw_notify_current_locked(fb); stw_framebuffer_release(fb); @@ -544,6 +537,7 @@ stw_framebuffer_present_locked(HDC hdc, data.rect = fb->client_rect; data.pPrivateData = (void *)surface; + stw_notify_current_locked(fb); stw_framebuffer_release(fb); return stw_dev->callbacks.wglCbPresentBuffers(hdc, &data); @@ -554,7 +548,7 @@ stw_framebuffer_present_locked(HDC hdc, stw_dev->stw_winsys->present( screen, surface, hdc ); stw_framebuffer_update(fb); - + stw_notify_current_locked(fb); stw_framebuffer_release(fb); return TRUE; @@ -567,7 +561,6 @@ DrvSwapBuffers( HDC hdc ) { struct stw_framebuffer *fb; - struct pipe_surface *surface = NULL; if (!stw_dev) return FALSE; @@ -581,9 +574,9 @@ DrvSwapBuffers( return TRUE; } - st_swapbuffers(fb->stfb, &surface, NULL); + stw_flush_current_locked(fb); - return stw_framebuffer_present_locked(hdc, fb, surface); + return stw_st_swap_framebuffer_locked(fb->stfb); } diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.h b/src/gallium/state_trackers/wgl/stw_framebuffer.h index e61e9bf9c26..89d12300e67 100644 --- a/src/gallium/state_trackers/wgl/stw_framebuffer.h +++ b/src/gallium/state_trackers/wgl/stw_framebuffer.h @@ -30,11 +30,10 @@ #include -#include "main/mtypes.h" - #include "os/os_thread.h" struct pipe_surface; +struct st_framebuffer_iface; struct stw_pixelformat_info; /** @@ -64,13 +63,15 @@ struct stw_framebuffer int iPixelFormat; const struct stw_pixelformat_info *pfi; - GLvisual visual; + + struct st_framebuffer_iface *stfb; /* * Mutable members. */ - struct st_framebuffer *stfb; + unsigned refcnt; + /* FIXME: Make this work for multiple contexts bound to the same framebuffer */ boolean must_resize; @@ -114,6 +115,11 @@ stw_framebuffer_create( HDC hdc, int iPixelFormat ); +void +stw_framebuffer_reference( + struct stw_framebuffer **ptr, + struct stw_framebuffer *fb); + /** * Search a framebuffer with a matching HWND. * @@ -134,10 +140,6 @@ struct stw_framebuffer * stw_framebuffer_from_hdc( HDC hdc ); -BOOL -stw_framebuffer_allocate( - struct stw_framebuffer *fb ); - BOOL stw_framebuffer_present_locked(HDC hdc, struct stw_framebuffer *fb, diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c index a07de994ca1..11e779d25f8 100644 --- a/src/gallium/state_trackers/wgl/stw_pixelformat.c +++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c @@ -142,9 +142,6 @@ stw_pixelformat_add( memset(pfi, 0, sizeof *pfi); - pfi->color_format = color->format; - pfi->depth_stencil_format = depth->format; - pfi->pfd.nSize = sizeof pfi->pfd; pfi->pfd.nVersion = 1; @@ -184,11 +181,22 @@ stw_pixelformat_add( pfi->pfd.dwVisibleMask = 0; pfi->pfd.dwDamageMask = 0; - if(samples) { - pfi->numSampleBuffers = 1; - pfi->numSamples = samples; - extended = TRUE; - } + /* + * since state trackers can allocate depth/stencil/accum buffers, we provide + * only color buffers here + */ + pfi->stvis.buffer_mask = ST_ATTACHMENT_FRONT_LEFT_MASK; + if (doublebuffer) + pfi->stvis.buffer_mask = ST_ATTACHMENT_BACK_LEFT_MASK; + + pfi->stvis.color_format = color->format; + pfi->stvis.depth_stencil_format = depth->format; + + pfi->stvis.accum_format = (accum) ? + PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE; + + pfi->stvis.samples = samples; + pfi->stvis.render_buffer = ST_ATTACHMENT_INVALID; ++stw_dev->pixelformat_extended_count; @@ -264,29 +272,6 @@ stw_pixelformat_get_info( uint index ) } -void -stw_pixelformat_visual(GLvisual *visual, - const struct stw_pixelformat_info *pfi ) -{ - memset(visual, 0, sizeof *visual); - _mesa_initialize_visual( - visual, - (pfi->pfd.dwFlags & PFD_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE, - (pfi->pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE, - pfi->pfd.cRedBits, - pfi->pfd.cGreenBits, - pfi->pfd.cBlueBits, - pfi->pfd.cAlphaBits, - pfi->pfd.cDepthBits, - pfi->pfd.cStencilBits, - pfi->pfd.cAccumRedBits, - pfi->pfd.cAccumGreenBits, - pfi->pfd.cAccumBlueBits, - pfi->pfd.cAccumAlphaBits, - pfi->numSamples ); -} - - LONG APIENTRY DrvDescribePixelFormat( HDC hdc, diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.h b/src/gallium/state_trackers/wgl/stw_pixelformat.h index 3a690b35bad..d405172773c 100644 --- a/src/gallium/state_trackers/wgl/stw_pixelformat.h +++ b/src/gallium/state_trackers/wgl/stw_pixelformat.h @@ -38,16 +38,13 @@ #include "pipe/p_compiler.h" #include "pipe/p_format.h" +#include "state_tracker/st_api.h" struct stw_pixelformat_info { - enum pipe_format color_format; - enum pipe_format depth_stencil_format; - PIXELFORMATDESCRIPTOR pfd; - unsigned numSampleBuffers; - unsigned numSamples; + struct st_visual stvis; }; void @@ -62,10 +59,6 @@ stw_pixelformat_get_extended_count( void ); const struct stw_pixelformat_info * stw_pixelformat_get_info( uint index ); -void -stw_pixelformat_visual(GLvisual *visual, - const struct stw_pixelformat_info *pfi ); - int stw_pixelformat_choose( HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd ); diff --git a/src/gallium/state_trackers/wgl/stw_st.c b/src/gallium/state_trackers/wgl/stw_st.c new file mode 100644 index 00000000000..6c71f2ac452 --- /dev/null +++ b/src/gallium/state_trackers/wgl/stw_st.c @@ -0,0 +1,306 @@ +/* + * 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 + */ + +#include "util/u_memory.h" +#include "util/u_inlines.h" +#include "state_tracker/st_manager.h" /* for st_manager_create_api */ + +#include "stw_st.h" +#include "stw_device.h" +#include "stw_framebuffer.h" +#include "stw_pixelformat.h" + +struct stw_st_framebuffer { + struct st_framebuffer_iface base; + + struct stw_framebuffer *fb; + struct st_visual stvis; + + struct pipe_texture *textures[ST_ATTACHMENT_COUNT]; + unsigned texture_width, texture_height; + unsigned texture_mask; + + struct pipe_surface *front_surface, *back_surface; +}; + +static INLINE struct stw_st_framebuffer * +stw_st_framebuffer(struct st_framebuffer_iface *stfb) +{ + return (struct stw_st_framebuffer *) stfb; +} + +/** + * Remove outdated textures and create the requested ones. + */ +static void +stw_st_framebuffer_validate_locked(struct st_framebuffer_iface *stfb, + unsigned width, unsigned height, + unsigned mask) +{ + struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb); + struct pipe_texture templ; + unsigned i; + + /* remove outdated textures */ + if (stwfb->texture_width != width || stwfb->texture_height != height) { + for (i = 0; i < ST_ATTACHMENT_COUNT; i++) + pipe_texture_reference(&stwfb->textures[i], NULL); + } + + memset(&templ, 0, sizeof(templ)); + templ.target = PIPE_TEXTURE_2D; + templ.width0 = width; + templ.height0 = height; + templ.depth0 = 1; + templ.last_level = 0; + + for (i = 0; i < ST_ATTACHMENT_COUNT; i++) { + enum pipe_format format; + unsigned tex_usage; + + /* the texture already exists or not requested */ + if (stwfb->textures[i] || !(mask & (1 << i))) { + /* remember the texture */ + if (stwfb->textures[i]) + mask |= (1 << i); + continue; + } + + switch (i) { + case ST_ATTACHMENT_FRONT_LEFT: + case ST_ATTACHMENT_BACK_LEFT: + format = stwfb->stvis.color_format; + tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET | + PIPE_TEXTURE_USAGE_RENDER_TARGET; + break; + case ST_ATTACHMENT_DEPTH_STENCIL: + format = stwfb->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; + + stwfb->textures[i] = + stw_dev->screen->texture_create(stw_dev->screen, &templ); + } + } + + stwfb->texture_width = width; + stwfb->texture_height = height; + stwfb->texture_mask = mask; +} + +static boolean +stw_st_framebuffer_validate(struct st_framebuffer_iface *stfb, + const enum st_attachment_type *statts, + unsigned count, + struct pipe_texture **out) +{ + struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb); + unsigned statt_mask, i; + + statt_mask = 0x0; + for (i = 0; i < count; i++) + statt_mask |= 1 << statts[i]; + + pipe_mutex_lock(stwfb->fb->mutex); + + if (stwfb->fb->must_resize || (statt_mask & ~stwfb->texture_mask)) { + stw_st_framebuffer_validate_locked(&stwfb->base, + statt_mask, stwfb->fb->width, stwfb->fb->height); + stwfb->fb->must_resize = FALSE; + } + + for (i = 0; i < count; i++) { + out[i] = NULL; + pipe_texture_reference(&out[i], stwfb->textures[statts[i]]); + } + + stw_framebuffer_release(stwfb->fb); + + return TRUE; +} + +static struct pipe_surface * +get_present_surface_locked(struct st_framebuffer_iface *stfb, + enum st_attachment_type statt) +{ + struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb); + struct pipe_texture *ptex; + struct pipe_surface *psurf, **cache; + + ptex = stwfb->textures[statt]; + if (!ptex) + return NULL; + + psurf = NULL; + + switch (statt) { + case ST_ATTACHMENT_FRONT_LEFT: + cache = &stwfb->front_surface; + break; + case ST_ATTACHMENT_BACK_LEFT: + cache = &stwfb->back_surface; + break; + default: + cache = &psurf; + break; + } + + if (!*cache) { + *cache = stw_dev->screen->get_tex_surface(stw_dev->screen, + ptex, 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ); + } + + if (psurf != *cache) + pipe_surface_reference(&psurf, *cache); + + return psurf; +} + +/** + * Present an attachment of the framebuffer. + */ +static boolean +stw_st_framebuffer_present_locked(struct st_framebuffer_iface *stfb, + enum st_attachment_type statt) +{ + struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb); + struct pipe_surface *psurf; + + psurf = get_present_surface_locked(&stwfb->base, statt); + if (psurf) { + stw_framebuffer_present_locked(stwfb->fb->hDC, stwfb->fb, psurf); + pipe_surface_reference(&psurf, NULL); + } + + return TRUE; +} + +static boolean +stw_st_framebuffer_flush_front(struct st_framebuffer_iface *stfb, + enum st_attachment_type statt) +{ + struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb); + + pipe_mutex_lock(stwfb->fb->mutex); + + return stw_st_framebuffer_present_locked(&stwfb->base, statt); +} + +/** + * Create a framebuffer interface. + */ +struct st_framebuffer_iface * +stw_st_create_framebuffer(struct stw_framebuffer *fb) +{ + struct stw_st_framebuffer *stwfb; + + stwfb = CALLOC_STRUCT(stw_st_framebuffer); + if (!stwfb) + return NULL; + + stwfb->fb = fb; + stwfb->stvis = fb->pfi->stvis; + + stwfb->base.visual = &stwfb->stvis; + stwfb->base.flush_front = stw_st_framebuffer_flush_front; + stwfb->base.validate = stw_st_framebuffer_validate; + + return &stwfb->base; +} + +/** + * Destroy a framebuffer interface. + */ +void +stw_st_destroy_framebuffer_locked(struct st_framebuffer_iface *stfb) +{ + struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb); + int i; + + pipe_surface_reference(&stwfb->front_surface, NULL); + pipe_surface_reference(&stwfb->back_surface, NULL); + + for (i = 0; i < ST_ATTACHMENT_COUNT; i++) + pipe_texture_reference(&stwfb->textures[i], NULL); + + FREE(stwfb); +} + +/** + * Swap the buffers of the given framebuffer. + */ +boolean +stw_st_swap_framebuffer_locked(struct st_framebuffer_iface *stfb) +{ + struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb); + unsigned front = ST_ATTACHMENT_FRONT_LEFT, back = ST_ATTACHMENT_BACK_LEFT; + struct pipe_texture *ptex; + struct pipe_surface *psurf; + unsigned mask; + + /* swap the textures */ + ptex = stwfb->textures[front]; + stwfb->textures[front] = stwfb->textures[back]; + stwfb->textures[back] = ptex; + + /* swap the surfaces */ + psurf = stwfb->front_surface; + stwfb->front_surface = stwfb->back_surface; + stwfb->back_surface = psurf; + + /* convert to mask */ + front = 1 << front; + back = 1 << back; + + /* swap the bits in mask */ + mask = stwfb->texture_mask & ~(front | back); + if (stwfb->texture_mask & front) + mask |= back; + if (stwfb->texture_mask & back) + mask |= front; + stwfb->texture_mask = mask; + + front = ST_ATTACHMENT_FRONT_LEFT; + return stw_st_framebuffer_present_locked(&stwfb->base, front); +} + +/** + * Create an st_api of the state tracker. + */ +struct st_api * +stw_st_create_api(void) +{ + return st_manager_create_api(); +} diff --git a/src/gallium/state_trackers/wgl/stw_st.h b/src/gallium/state_trackers/wgl/stw_st.h new file mode 100644 index 00000000000..23771d8bef6 --- /dev/null +++ b/src/gallium/state_trackers/wgl/stw_st.h @@ -0,0 +1,47 @@ +/* + * 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 + */ + +#ifndef STW_ST_H +#define STW_ST_H + +#include "state_tracker/st_api.h" + +struct stw_framebuffer; + +struct st_api * +stw_st_create_api(void); + +struct st_framebuffer_iface * +stw_st_create_framebuffer(struct stw_framebuffer *fb); + +void +stw_st_destroy_framebuffer_locked(struct st_framebuffer_iface *stfb); + +boolean +stw_st_swap_framebuffer_locked(struct st_framebuffer_iface *stfb); + +#endif /* STW_ST_H */ -- 2.30.2