summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bin.c68
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bin.h11
2 files changed, 79 insertions, 0 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_bin.c b/src/gallium/drivers/llvmpipe/lp_bin.c
index 160a8d865b..3e294e5799 100644
--- a/src/gallium/drivers/llvmpipe/lp_bin.c
+++ b/src/gallium/drivers/llvmpipe/lp_bin.c
@@ -41,9 +41,14 @@ lp_init_bins(struct lp_bins *bins)
bins->data.head =
bins->data.tail = CALLOC_STRUCT(data_block);
+
+ pipe_mutex_init(bins->mutex);
}
+/**
+ * Set bins to empty state.
+ */
void
lp_reset_bins(struct lp_bins *bins )
{
@@ -87,6 +92,9 @@ lp_reset_bins(struct lp_bins *bins )
}
+/**
+ * Free all data associated with the given bin, but don't free(bins).
+ */
void
lp_free_bin_data(struct lp_bins *bins)
{
@@ -104,6 +112,8 @@ lp_free_bin_data(struct lp_bins *bins)
FREE(bins->data.head);
bins->data.head = NULL;
+
+ pipe_mutex_destroy(bins->mutex);
}
@@ -191,3 +201,61 @@ lp_bin_state_command( struct lp_bins *bins,
}
}
}
+
+
+/** advance curr_x,y to the next bin */
+static boolean
+next_bin(struct lp_bins *bins)
+{
+ bins->curr_x++;
+ if (bins->curr_x >= bins->tiles_x) {
+ bins->curr_x = 0;
+ bins->curr_y++;
+ }
+ if (bins->curr_y >= bins->tiles_y) {
+ /* no more bins */
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+void
+lp_bin_iter_begin( struct lp_bins *bins )
+{
+ bins->curr_x = bins->curr_y = -1;
+}
+
+
+/**
+ * Return point to next bin to be rendered.
+ * The lp_bins::curr_x and ::curr_y fields will be advanced.
+ * Multiple rendering threads will call this function to get a chunk
+ * of work (a bin) to work on.
+ */
+struct cmd_bin *
+lp_bin_iter_next( struct lp_bins *bins, int *bin_x, int *bin_y )
+{
+ struct cmd_bin *bin = NULL;
+
+ pipe_mutex_lock(bins->mutex);
+
+ if (bins->curr_x < 0) {
+ /* first bin */
+ bins->curr_x = 0;
+ bins->curr_y = 0;
+ }
+ else if (!next_bin(bins)) {
+ /* no more bins left */
+ goto end;
+ }
+
+ bin = lp_get_bin(bins, bins->curr_x, bins->curr_y);
+ *bin_x = bins->curr_x;
+ *bin_y = bins->curr_y;
+
+end:
+ /*printf("return bin %p at %d, %d\n", (void *) bin, *bin_x, *bin_y);*/
+ pipe_mutex_unlock(bins->mutex);
+ return bin;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_bin.h b/src/gallium/drivers/llvmpipe/lp_bin.h
index fcbb975ad6..24e599ea66 100644
--- a/src/gallium/drivers/llvmpipe/lp_bin.h
+++ b/src/gallium/drivers/llvmpipe/lp_bin.h
@@ -35,6 +35,7 @@
#ifndef LP_BIN_H
#define LP_BIN_H
+#include "pipe/p_thread.h"
#include "lp_tile_soa.h"
#include "lp_rast.h"
@@ -110,6 +111,9 @@ struct lp_bins {
* This basically the framebuffer size divided by tile size
*/
unsigned tiles_x, tiles_y;
+
+ int curr_x, curr_y; /**< for iterating over bins */
+ pipe_mutex mutex;
};
@@ -239,4 +243,11 @@ lp_bin_state_command( struct lp_bins *bins,
const union lp_rast_cmd_arg arg );
+void
+lp_bin_iter_begin( struct lp_bins *bins );
+
+struct cmd_bin *
+lp_bin_iter_next( struct lp_bins *bins, int *bin_x, int *bin_y );
+
+
#endif /* LP_BIN_H */