st/nine: Use WINE thread for threadpool
authorPatrick Rudolph <siro@das-labor.org>
Mon, 22 Feb 2016 18:49:19 +0000 (19:49 +0100)
committerAxel Davy <axel.davy@ens.fr>
Wed, 18 May 2016 21:37:14 +0000 (23:37 +0200)
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 <siro@das-labor.org>
Reviewed-by: Axel Davy <axel.davy@ens.fr>
src/gallium/state_trackers/nine/swapchain9.c
src/gallium/state_trackers/nine/swapchain9.h
src/gallium/state_trackers/nine/threadpool.c
src/gallium/state_trackers/nine/threadpool.h

index db3766063a5edc6747684f5123aa4c56db5ea064..12cad73d72290251e402f6f33dc6deb2acfd8e53 100644 (file)
@@ -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);
+    }
+}
index 43032ce8543decb53ca7a901d504af4f467b5522..f3efe268239e7219db0cb4400dfc36338dbe3776 100644 (file)
@@ -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_ */
index 2a96537430567414ffc98a6fad248cd211a70817..cc62fd25799b479e81f9ea266566f5cd692f237c 100644 (file)
@@ -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);
index 00ad25e1b13476563b9b111d57affd340a929b4b..2562c96f256402000a4fc32e2f2203ed9ff1eeb5 100644 (file)
 #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