diff options
-rw-r--r-- | src/gallium/frontends/nine/device9.c | 13 | ||||
-rw-r--r-- | src/gallium/frontends/nine/device9.h | 1 | ||||
-rw-r--r-- | src/gallium/frontends/nine/nine_state.c | 17 | ||||
-rw-r--r-- | src/gallium/frontends/nine/nine_state.h | 7 | ||||
-rw-r--r-- | src/gallium/frontends/nine/swapchain9.c | 1 |
5 files changed, 39 insertions, 0 deletions
diff --git a/src/gallium/frontends/nine/device9.c b/src/gallium/frontends/nine/device9.c index 9b44b9827b7..2de8d50ef68 100644 --- a/src/gallium/frontends/nine/device9.c +++ b/src/gallium/frontends/nine/device9.c @@ -2035,6 +2035,19 @@ NineDevice9_EndScene( struct NineDevice9 *This ) DBG("This=%p\n", This); user_assert(This->in_scene, D3DERR_INVALIDCALL); This->in_scene = FALSE; + This->end_scene_since_present++; + /* EndScene() is supposed to flush the GPU commands. + * The idea is to flush ahead of the Present() call. + * (Apps could take advantage of this by inserting CPU + * work between EndScene() and Present()). + * Most apps will have one EndScene per frame. + * Some will have 2 or 3. + * Some bad behaving apps do a lot of them. + * As flushing has a cost, do it only once. */ + if (This->end_scene_since_present <= 1) { + nine_context_pipe_flush(This); + nine_csmt_flush(This); + } return D3D_OK; } diff --git a/src/gallium/frontends/nine/device9.h b/src/gallium/frontends/nine/device9.h index 974251f3fe9..876728e0105 100644 --- a/src/gallium/frontends/nine/device9.h +++ b/src/gallium/frontends/nine/device9.h @@ -90,6 +90,7 @@ struct NineDevice9 boolean is_recording; boolean in_scene; + unsigned end_scene_since_present; uint16_t vs_const_size; uint16_t ps_const_size; diff --git a/src/gallium/frontends/nine/nine_state.c b/src/gallium/frontends/nine/nine_state.c index 6f57b19e1aa..0d1f670e946 100644 --- a/src/gallium/frontends/nine/nine_state.c +++ b/src/gallium/frontends/nine/nine_state.c @@ -211,6 +211,16 @@ nine_csmt_process( struct NineDevice9 *device ) nine_csmt_wait_processed(ctx); } +void +nine_csmt_flush( struct NineDevice9* device ) +{ + if (!device->csmt_active) + return; + + nine_queue_flush(device->csmt_ctx->pool); +} + + /* Destroys a CSMT context. * Waits for the worker thread to terminate. */ @@ -2648,6 +2658,13 @@ nine_context_get_query_result(struct NineDevice9 *device, struct pipe_query *que return ret; } +CSMT_ITEM_NO_WAIT(nine_context_pipe_flush) +{ + struct nine_context *context = &device->context; + + context->pipe->flush(context->pipe, NULL, PIPE_FLUSH_ASYNC); +} + /* State defaults */ static const DWORD nine_render_state_defaults[NINED3DRS_LAST + 1] = diff --git a/src/gallium/frontends/nine/nine_state.h b/src/gallium/frontends/nine/nine_state.h index cc76bef3418..d42bfbfefc9 100644 --- a/src/gallium/frontends/nine/nine_state.h +++ b/src/gallium/frontends/nine/nine_state.h @@ -604,6 +604,9 @@ nine_context_get_query_result(struct NineDevice9 *device, struct pipe_query *que unsigned *counter, boolean flush, boolean wait, union pipe_query_result *result); +void +nine_context_pipe_flush(struct NineDevice9 *device); + void nine_state_restore_non_cso(struct NineDevice9 *device); void nine_state_set_defaults(struct NineDevice9 *, const D3DCAPS9 *, boolean is_reset); @@ -648,9 +651,13 @@ nine_csmt_create( struct NineDevice9 *This ); void nine_csmt_destroy( struct NineDevice9 *This, struct csmt_context *ctx ); +/* Flushes and waits everything is executed */ void nine_csmt_process( struct NineDevice9 *This ); +/* Flushes and doesn't wait */ +void +nine_csmt_flush( struct NineDevice9 *This ); /* Get the pipe_context (should not be called from the worker thread). * All the work in the worker thread is finished before returning. */ diff --git a/src/gallium/frontends/nine/swapchain9.c b/src/gallium/frontends/nine/swapchain9.c index 39784738895..44aa75a949b 100644 --- a/src/gallium/frontends/nine/swapchain9.c +++ b/src/gallium/frontends/nine/swapchain9.c @@ -930,6 +930,7 @@ bypass_rendering: if (FAILED(hr)) { UNTESTED(3);return hr; } } + This->base.device->end_scene_since_present = 0; return D3D_OK; } |