gallium: add PIPE_CAP_USER_INDEX_BUFFERS and PIPE_CAP_USER_CONSTANT_BUFFERS
[mesa.git] / src / gallium / drivers / llvmpipe / lp_scene.h
index 49c5d4d577092c1ae8597eef56f659729ff02874..622c522f11a01bc72ae84e55a37078b57b255b49 100644 (file)
 #include "os/os_thread.h"
 #include "lp_tile_soa.h"
 #include "lp_rast.h"
+#include "lp_debug.h"
 
 struct lp_scene_queue;
+struct lp_rast_state;
 
 /* We're limited to 2K by 2K for 32bit fixed point rasterization.
  * Will need a 64-bit version for larger framebuffers.
@@ -48,8 +50,8 @@ struct lp_scene_queue;
 #define TILES_Y (LP_MAX_HEIGHT / TILE_SIZE)
 
 
-#define CMD_BLOCK_MAX 16
-#define DATA_BLOCK_SIZE (64 * 1024 - 2 * sizeof(void *))
+#define CMD_BLOCK_MAX 128
+#define DATA_BLOCK_SIZE (64 * 1024)
 
 /* Scene temporary storage is clamped to this size:
  */
@@ -93,6 +95,7 @@ struct data_block {
 struct cmd_bin {
    ushort x;
    ushort y;
+   const struct lp_rast_state *last_state;       /* most recent state set in bin */
    struct cmd_block *head;
    struct cmd_block *tail;
 };
@@ -205,6 +208,11 @@ lp_scene_alloc( struct lp_scene *scene, unsigned size)
    assert(size <= DATA_BLOCK_SIZE);
    assert(block != NULL);
 
+   if (LP_DEBUG & DEBUG_MEM)
+      debug_printf("alloc %u block %u/%u tot %u/%u\n",
+                  size, block->used, DATA_BLOCK_SIZE,
+                  scene->scene_size, LP_SCENE_MAX_SIZE);
+
    if (block->used + size > DATA_BLOCK_SIZE) {
       block = lp_scene_new_data_block( scene );
       if (!block) {
@@ -232,6 +240,12 @@ lp_scene_alloc_aligned( struct lp_scene *scene, unsigned size,
    struct data_block *block = list->head;
 
    assert(block != NULL);
+
+   if (LP_DEBUG & DEBUG_MEM)
+      debug_printf("alloc %u block %u/%u tot %u/%u\n",
+                  size + alignment - 1,
+                  block->used, DATA_BLOCK_SIZE,
+                  scene->scene_size, LP_SCENE_MAX_SIZE);
        
    if (block->used + size + alignment - 1 > DATA_BLOCK_SIZE) {
       block = lp_scene_new_data_block( scene );
@@ -285,7 +299,7 @@ lp_scene_bin_command( struct lp_scene *scene,
 
    assert(x < scene->tiles_x);
    assert(y < scene->tiles_y);
-   assert(cmd <= LP_RAST_OP_END_QUERY);
+   assert(cmd < LP_RAST_OP_MAX);
 
    if (tail == NULL || tail->count == CMD_BLOCK_MAX) {
       tail = lp_scene_new_cmd_block( scene, bin );
@@ -306,6 +320,30 @@ lp_scene_bin_command( struct lp_scene *scene,
 }
 
 
+static INLINE boolean
+lp_scene_bin_cmd_with_state( struct lp_scene *scene,
+                             unsigned x, unsigned y,
+                             const struct lp_rast_state *state,
+                             unsigned cmd,
+                             union lp_rast_cmd_arg arg )
+{
+   struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
+
+   if (state != bin->last_state) {
+      bin->last_state = state;
+      if (!lp_scene_bin_command(scene, x, y,
+                                LP_RAST_OP_SET_STATE,
+                                lp_rast_arg_state(state)))
+         return FALSE;
+   }
+
+   if (!lp_scene_bin_command( scene, x, y, cmd, arg ))
+      return FALSE;
+
+   return TRUE;
+}
+
+
 /* Add a command to all active bins.
  */
 static INLINE boolean