summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gallium/frontends/nine/device9.c13
-rw-r--r--src/gallium/frontends/nine/device9.h1
-rw-r--r--src/gallium/frontends/nine/nine_state.c17
-rw-r--r--src/gallium/frontends/nine/nine_state.h7
-rw-r--r--src/gallium/frontends/nine/swapchain9.c1
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;
}