Merge branch 'gallium-polygon-stipple'
[mesa.git] / src / mesa / drivers / dri / i965 / brw_state_batch.c
index be3989eb7db3374624b68b1d7a0b8fde9ab94f48..5a983c3d8477a6734a8f6e00a42cf9853494a7d9 100644 (file)
   *   Keith Whitwell <keith@tungstengraphics.com>
   */
      
-
-
 #include "brw_state.h"
 #include "intel_batchbuffer.h"
 #include "main/imports.h"
+#include "../glsl/ralloc.h"
 
-
-
-/* A facility similar to the data caching code above, which aims to
- * prevent identical commands being issued repeatedly.
- */
-GLboolean brw_cached_batch_struct( struct brw_context *brw,
-                                  const void *data,
-                                  GLuint sz )
+static void
+brw_track_state_batch(struct brw_context *brw,
+                     enum state_struct_type type,
+                     uint32_t offset,
+                     int size)
 {
-   struct brw_cached_batch_item *item = brw->cached_batch_items;
-   struct header *newheader = (struct header *)data;
-
-   if (brw->emit_state_always) {
-      intel_batchbuffer_data(brw->intel.batch, data, sz);
-      return GL_TRUE;
-   }
-
-   while (item) {
-      if (item->header->opcode == newheader->opcode) {
-        if (item->sz == sz && memcmp(item->header, newheader, sz) == 0)
-           return GL_FALSE;
-        if (item->sz != sz) {
-           free(item->header);
-           item->header = malloc(sz);
-           item->sz = sz;
-        }
-        goto emit;
-      }
-      item = item->next;
+   struct intel_batchbuffer *batch = &brw->intel.batch;
+
+   if (!brw->state_batch_list) {
+      /* Our structs are always aligned to at least 32 bytes, so
+       * our array doesn't need to be any larger
+       */
+      brw->state_batch_list = ralloc_size(brw, sizeof(*brw->state_batch_list) *
+                                         batch->bo->size / 32);
    }
 
-   assert(!item);
-   item = CALLOC_STRUCT(brw_cached_batch_item);
-   item->header = malloc(sz);
-   item->sz = sz;
-   item->next = brw->cached_batch_items;
-   brw->cached_batch_items = item;
-
- emit:
-   memcpy(item->header, newheader, sz);
-   intel_batchbuffer_data(brw->intel.batch, data, sz);
-   return GL_TRUE;
-}
-
-void brw_clear_batch_cache( struct brw_context *brw )
-{
-   struct brw_cached_batch_item *item = brw->cached_batch_items;
-
-   while (item) {
-      struct brw_cached_batch_item *next = item->next;
-      free((void *)item->header);
-      free(item);
-      item = next;
-   }
-
-   brw->cached_batch_items = NULL;
-}
-
-void brw_destroy_batch_cache( struct brw_context *brw )
-{
-   brw_clear_batch_cache(brw);
+   brw->state_batch_list[brw->state_batch_count].offset = offset;
+   brw->state_batch_list[brw->state_batch_count].size = size;
+   brw->state_batch_list[brw->state_batch_count].type = type;
+   brw->state_batch_count++;
 }
 
 /**
@@ -114,15 +72,15 @@ void brw_destroy_batch_cache( struct brw_context *brw )
  */
 void *
 brw_state_batch(struct brw_context *brw,
+               enum state_struct_type type,
                int size,
                int alignment,
-               drm_intel_bo **out_bo,
                uint32_t *out_offset)
 {
-   struct intel_batchbuffer *batch = brw->intel.batch;
+   struct intel_batchbuffer *batch = &brw->intel.batch;
    uint32_t offset;
 
-   assert(size < batch->buf->size);
+   assert(size < batch->bo->size);
    offset = ROUND_DOWN_TO(batch->state_batch_offset - size, alignment);
 
    /* If allocating from the top would wrap below the batchbuffer, or
@@ -130,19 +88,16 @@ brw_state_batch(struct brw_context *brw,
     * space, then flush and try again.
     */
    if (batch->state_batch_offset < size ||
-       offset < batch->ptr - batch->map + batch->reserved_space) {
-      intel_batchbuffer_flush(batch);
+       offset < 4*batch->used + batch->reserved_space) {
+      intel_batchbuffer_flush(&brw->intel);
       offset = ROUND_DOWN_TO(batch->state_batch_offset - size, alignment);
    }
 
    batch->state_batch_offset = offset;
 
-   if (*out_bo != batch->buf) {
-      drm_intel_bo_unreference(*out_bo);
-      drm_intel_bo_reference(batch->buf);
-      *out_bo = batch->buf;
-   }
+   if (unlikely(INTEL_DEBUG & DEBUG_BATCH))
+      brw_track_state_batch(brw, type, offset, size);
 
    *out_offset = offset;
-   return batch->map + offset;
+   return batch->map + (offset>>2);
 }