summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Whitwell <keithw@vmware.com>2010-07-08 15:13:35 +0100
committerJosé Fonseca <jfonseca@vmware.com>2010-07-13 17:23:48 +0100
commit3bd9aedbac79eec16bfe6f5fc6f6a021eebe769a (patch)
treeed8c7d28d1d6c7b8cd33b1c68e3ac996c5b64ea8
parent6d17f00600ffca7cb39e6f66277cec018ff2c151 (diff)
llvmpipe: move fences from per-bin to per-thread
Rather than inserting an lp_rast_fence command at the end of each bin, have each rasterizer thread call this function directly once it has run out of work to do on a particular scene. This results in fewer calls to the mutex & related functions, but more importantly makes it easier to recognize empty bins.
-rw-r--r--src/gallium/drivers/llvmpipe/lp_fence.c9
-rw-r--r--src/gallium/drivers/llvmpipe/lp_fence.h18
-rw-r--r--src/gallium/drivers/llvmpipe/lp_flush.c10
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_scene.c3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_scene.h1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c39
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.h3
8 files changed, 58 insertions, 29 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_fence.c b/src/gallium/drivers/llvmpipe/lp_fence.c
index 75d8d2b8251..f9805e5d688 100644
--- a/src/gallium/drivers/llvmpipe/lp_fence.c
+++ b/src/gallium/drivers/llvmpipe/lp_fence.c
@@ -28,7 +28,6 @@
#include "pipe/p_screen.h"
#include "util/u_memory.h"
-#include "util/u_inlines.h"
#include "lp_debug.h"
#include "lp_fence.h"
@@ -59,7 +58,7 @@ lp_fence_create(unsigned rank)
/** Destroy a fence. Called when refcount hits zero. */
-static void
+void
lp_fence_destroy(struct lp_fence *fence)
{
pipe_mutex_destroy(fence->mutex);
@@ -77,12 +76,10 @@ llvmpipe_fence_reference(struct pipe_screen *screen,
struct pipe_fence_handle **ptr,
struct pipe_fence_handle *fence)
{
- struct lp_fence *old = (struct lp_fence *) *ptr;
+ struct lp_fence **old = (struct lp_fence **) ptr;
struct lp_fence *f = (struct lp_fence *) fence;
- if (pipe_reference(&old->reference, &f->reference)) {
- lp_fence_destroy(old);
- }
+ lp_fence_reference(old, f);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_fence.h b/src/gallium/drivers/llvmpipe/lp_fence.h
index d9270f5784a..13358fb99f2 100644
--- a/src/gallium/drivers/llvmpipe/lp_fence.h
+++ b/src/gallium/drivers/llvmpipe/lp_fence.h
@@ -32,6 +32,7 @@
#include "os/os_thread.h"
#include "pipe/p_state.h"
+#include "util/u_inlines.h"
struct pipe_screen;
@@ -61,4 +62,21 @@ void
llvmpipe_init_screen_fence_funcs(struct pipe_screen *screen);
+void
+lp_fence_destroy(struct lp_fence *fence);
+
+static INLINE void
+lp_fence_reference(struct lp_fence **ptr,
+ struct lp_fence *f)
+{
+ struct lp_fence *old = *ptr;
+
+ if (pipe_reference(&old->reference, &f->reference)) {
+ lp_fence_destroy(old);
+ }
+
+ *ptr = f;
+}
+
+
#endif /* LP_FENCE_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c
index 0cd288bb73a..d78656f4628 100644
--- a/src/gallium/drivers/llvmpipe/lp_flush.c
+++ b/src/gallium/drivers/llvmpipe/lp_flush.c
@@ -51,16 +51,8 @@ llvmpipe_flush( struct pipe_context *pipe,
draw_flush(llvmpipe->draw);
- if (fence) {
- /* if we're going to flush the setup/rasterization modules, emit
- * a fence.
- * XXX this (and the code below) may need fine tuning...
- */
- *fence = lp_setup_fence( llvmpipe->setup );
- }
-
/* ask the setup module to flush */
- lp_setup_flush(llvmpipe->setup, flags);
+ lp_setup_flush(llvmpipe->setup, flags, fence);
/* Enable to dump BMPs of the color/depth buffers each frame */
if (0) {
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index 1a82dd5694e..1dde327836c 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -815,6 +815,10 @@ rasterize_scene(struct lp_rasterizer_task *task,
}
}
#endif
+
+ if (scene->fence) {
+ lp_rast_fence(task, lp_rast_arg_fence(scene->fence));
+ }
}
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c b/src/gallium/drivers/llvmpipe/lp_scene.c
index e8d36bbdc50..f2226a538a5 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene.c
+++ b/src/gallium/drivers/llvmpipe/lp_scene.c
@@ -32,6 +32,7 @@
#include "util/u_simple_list.h"
#include "lp_scene.h"
#include "lp_scene_queue.h"
+#include "lp_fence.h"
/** List of texture references */
@@ -198,6 +199,8 @@ lp_scene_reset(struct lp_scene *scene )
make_empty_list(ref_list);
}
+ lp_fence_reference(&scene->fence, NULL);
+
scene->scene_size = 0;
scene->has_color_clear = FALSE;
diff --git a/src/gallium/drivers/llvmpipe/lp_scene.h b/src/gallium/drivers/llvmpipe/lp_scene.h
index 4e55d431746..fa1b311fa17 100644
--- a/src/gallium/drivers/llvmpipe/lp_scene.h
+++ b/src/gallium/drivers/llvmpipe/lp_scene.h
@@ -112,6 +112,7 @@ struct resource_ref {
*/
struct lp_scene {
struct pipe_context *pipe;
+ struct lp_fence *fence;
/** the framebuffer to render the scene into */
struct pipe_framebuffer_state fb;
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index 2bd6fcebe7f..3b83f4e7428 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -271,7 +271,8 @@ set_scene_state( struct lp_setup_context *setup,
*/
void
lp_setup_flush( struct lp_setup_context *setup,
- unsigned flags )
+ unsigned flags,
+ struct pipe_fence_handle **fence)
{
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
@@ -288,6 +289,15 @@ lp_setup_flush( struct lp_setup_context *setup,
*/
lp_scene_bin_everywhere(scene, lp_rast_store_color, dummy);
}
+
+
+ if (fence) {
+ /* if we're going to flush the setup/rasterization modules, emit
+ * a fence.
+ */
+ *fence = lp_setup_fence( setup );
+ }
+
}
set_scene_state( setup, SETUP_FLUSHED );
@@ -433,24 +443,27 @@ lp_setup_clear( struct lp_setup_context *setup,
struct pipe_fence_handle *
lp_setup_fence( struct lp_setup_context *setup )
{
- if (setup->num_threads == 0) {
+ if (setup->scene == NULL)
return NULL;
- }
- else {
+ else if (setup->num_threads == 0)
+ return NULL;
+ else
+ {
struct lp_scene *scene = lp_setup_get_current_scene(setup);
- const unsigned rank = lp_scene_get_num_bins( scene ); /* xxx */
- struct lp_fence *fence = lp_fence_create(rank);
-
- LP_DBG(DEBUG_SETUP, "%s rank %u\n", __FUNCTION__, rank);
+ const unsigned rank = setup->num_threads;
set_scene_state( setup, SETUP_ACTIVE );
+
+ assert(scene->fence == NULL);
- /* insert the fence into all command bins */
- lp_scene_bin_everywhere( scene,
- lp_rast_fence,
- lp_rast_arg_fence(fence) );
+ /* The caller gets a reference, we keep a copy too, so need to
+ * bump the refcount:
+ */
+ lp_fence_reference(&scene->fence, lp_fence_create(rank));
+
+ LP_DBG(DEBUG_SETUP, "%s rank %u\n", __FUNCTION__, rank);
- return (struct pipe_fence_handle *) fence;
+ return (struct pipe_fence_handle *) scene->fence;
}
}
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h
index 6a0dc551290..73b1c85325a 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup.h
@@ -84,7 +84,8 @@ lp_setup_fence( struct lp_setup_context *setup );
void
lp_setup_flush( struct lp_setup_context *setup,
- unsigned flags );
+ unsigned flags,
+ struct pipe_fence_handle **fence);
void