From f3fa7e3068512dde55c3f4d7c2b599ab1d7fe67f Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Mon, 22 Feb 2016 19:49:19 +0100 Subject: [PATCH] st/nine: Use WINE thread for threadpool Use present interface 1.2 function ID3DPresent_CreateThread to create the thread for threadpool. Creating the thread with WINE prevents some rarely occuring crashes. Signed-off-by: Patrick Rudolph Reviewed-by: Axel Davy --- src/gallium/state_trackers/nine/swapchain9.c | 27 ++++++++++++++++++++++++--- src/gallium/state_trackers/nine/swapchain9.h | 9 +++++++++ src/gallium/state_trackers/nine/threadpool.c | 17 ++++++++++++----- src/gallium/state_trackers/nine/threadpool.h | 11 +++++++---- 4 files changed, 52 insertions(+), 12 deletions(-) diff --git a/src/gallium/state_trackers/nine/swapchain9.c b/src/gallium/state_trackers/nine/swapchain9.c index db37660..12cad73 100644 --- a/src/gallium/state_trackers/nine/swapchain9.c +++ b/src/gallium/state_trackers/nine/swapchain9.c @@ -241,12 +241,12 @@ NineSwapChain9_Resize( struct NineSwapChain9 *This, desc.Height = pParams->BackBufferHeight; if (This->pool) { - _mesa_threadpool_destroy(This->pool); + _mesa_threadpool_destroy(This, This->pool); This->pool = NULL; } This->enable_threadpool = This->actx->thread_submit && (pParams->SwapEffect != D3DSWAPEFFECT_COPY); if (This->enable_threadpool) - This->pool = _mesa_threadpool_create(); + This->pool = _mesa_threadpool_create(This); if (!This->pool) This->enable_threadpool = FALSE; @@ -504,7 +504,7 @@ NineSwapChain9_dtor( struct NineSwapChain9 *This ) DBG("This=%p\n", This); if (This->pool) - _mesa_threadpool_destroy(This->pool); + _mesa_threadpool_destroy(This, This->pool); if (This->buffers) { for (i = 0; i < This->params.BackBufferCount; i++) { @@ -1028,3 +1028,24 @@ NineSwapChain9_ResolutionMismatch( struct NineSwapChain9 *This ) return FALSE; } + +HANDLE +NineSwapChain9_CreateThread( struct NineSwapChain9 *This, + void *pFuncAddress, + void *pParam ) +{ + if (This->base.device->minor_version_num > 1) { + return ID3DPresent_CreateThread(This->present, pFuncAddress, pParam); + } + + return NULL; +} + +void +NineSwapChain9_WaitForThread( struct NineSwapChain9 *This, + HANDLE thread ) +{ + if (This->base.device->minor_version_num > 1) { + (void) ID3DPresent_WaitForThread(This->present, thread); + } +} diff --git a/src/gallium/state_trackers/nine/swapchain9.h b/src/gallium/state_trackers/nine/swapchain9.h index 43032ce..f3efe26 100644 --- a/src/gallium/state_trackers/nine/swapchain9.h +++ b/src/gallium/state_trackers/nine/swapchain9.h @@ -145,4 +145,13 @@ NineSwapChain9_GetOccluded( struct NineSwapChain9 *This ); BOOL NineSwapChain9_ResolutionMismatch( struct NineSwapChain9 *This ); +HANDLE +NineSwapChain9_CreateThread( struct NineSwapChain9 *This, + void *pFuncAddress, + void *pParam ); + +void +NineSwapChain9_WaitForThread( struct NineSwapChain9 *This, + HANDLE thread ); + #endif /* _NINE_SWAPCHAIN9_H_ */ diff --git a/src/gallium/state_trackers/nine/threadpool.c b/src/gallium/state_trackers/nine/threadpool.c index 2a96537..cc62fd2 100644 --- a/src/gallium/state_trackers/nine/threadpool.c +++ b/src/gallium/state_trackers/nine/threadpool.c @@ -77,7 +77,7 @@ threadpool_worker(void *data) } struct threadpool * -_mesa_threadpool_create(void) +_mesa_threadpool_create(struct NineSwapChain9 *swapchain) { struct threadpool *pool = calloc(1, sizeof(*pool)); @@ -87,13 +87,16 @@ _mesa_threadpool_create(void) pthread_mutex_init(&pool->m, NULL); pthread_cond_init(&pool->new_work, NULL); - pthread_create(&pool->thread, NULL, threadpool_worker, pool); - + pool->wthread = NineSwapChain9_CreateThread(swapchain, threadpool_worker, pool); + if (!pool->wthread) { + /* using pthread as fallback */ + pthread_create(&pool->pthread, NULL, threadpool_worker, pool); + } return pool; } void -_mesa_threadpool_destroy(struct threadpool *pool) +_mesa_threadpool_destroy(struct NineSwapChain9 *swapchain, struct threadpool *pool) { if (!pool) return; @@ -103,7 +106,11 @@ _mesa_threadpool_destroy(struct threadpool *pool) pthread_cond_broadcast(&pool->new_work); pthread_mutex_unlock(&pool->m); - pthread_join(pool->thread, NULL); + if (pool->wthread) { + NineSwapChain9_WaitForThread(swapchain, pool->wthread); + } else { + pthread_join(pool->pthread, NULL); + } pthread_cond_destroy(&pool->new_work); pthread_mutex_destroy(&pool->m); diff --git a/src/gallium/state_trackers/nine/threadpool.h b/src/gallium/state_trackers/nine/threadpool.h index 00ad25e..2562c96 100644 --- a/src/gallium/state_trackers/nine/threadpool.h +++ b/src/gallium/state_trackers/nine/threadpool.h @@ -24,13 +24,16 @@ #ifndef _THREADPOOL_H_ #define _THREADPOOL_H_ +struct NineSwapChain9; + #define MAXTHREADS 1 struct threadpool { pthread_mutex_t m; pthread_cond_t new_work; - pthread_t thread; + HANDLE wthread; + pthread_t pthread; struct threadpool_task *workqueue; BOOL shutdown; }; @@ -45,11 +48,11 @@ struct threadpool_task { BOOL finished; }; -struct threadpool *_mesa_threadpool_create(void); -void _mesa_threadpool_destroy(struct threadpool *pool); +struct threadpool *_mesa_threadpool_create(struct NineSwapChain9 *swapchain); +void _mesa_threadpool_destroy(struct NineSwapChain9 *swapchain, struct threadpool *pool); struct threadpool_task *_mesa_threadpool_queue_task(struct threadpool *pool, threadpool_task_func func, void *data); void _mesa_threadpool_wait_for_task(struct threadpool *pool, struct threadpool_task **task); -#endif \ No newline at end of file +#endif -- 2.7.4