i965: Move the remaining intel code to the i965 directory. 83/7183/1
authorEric Anholt <eric@anholt.net>
Thu, 20 Jun 2013 23:07:07 +0000 (16:07 -0700)
committerEric Anholt <eric@anholt.net>
Wed, 26 Jun 2013 19:28:26 +0000 (12:28 -0700)
Now that i915's forked off, they don't need to live in a shared directory.

Acked-by: Kenneth Graunke <kenneth@whitecape.org>
Acked-by: Chad Versace <chad.versace@linux.intel.com>
Acked-by: Adam Jackson <ajax@redhat.com>
(and I hear second hand that idr is OK with it, too)

67 files changed:
src/mesa/drivers/dri/i965/Makefile.am
src/mesa/drivers/dri/i965/intel_batchbuffer.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_batchbuffer.h [moved from src/mesa/drivers/dri/intel/intel_batchbuffer.h with 100% similarity]
src/mesa/drivers/dri/i965/intel_blit.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_blit.h [moved from src/mesa/drivers/dri/intel/intel_blit.h with 100% similarity]
src/mesa/drivers/dri/i965/intel_buffer_objects.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_buffer_objects.h [moved from src/mesa/drivers/dri/intel/intel_buffer_objects.h with 100% similarity]
src/mesa/drivers/dri/i965/intel_buffers.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_buffers.h [moved from src/mesa/drivers/dri/intel/intel_buffers.h with 100% similarity]
src/mesa/drivers/dri/i965/intel_chipset.h [moved from src/mesa/drivers/dri/intel/intel_chipset.h with 100% similarity]
src/mesa/drivers/dri/i965/intel_clear.h [moved from src/mesa/drivers/dri/intel/intel_clear.h with 100% similarity]
src/mesa/drivers/dri/i965/intel_context.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_context.h [moved from src/mesa/drivers/dri/intel/intel_context.h with 100% similarity]
src/mesa/drivers/dri/i965/intel_extensions.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_extensions.h [moved from src/mesa/drivers/dri/intel/intel_extensions.h with 100% similarity]
src/mesa/drivers/dri/i965/intel_fbo.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_fbo.h [moved from src/mesa/drivers/dri/intel/intel_fbo.h with 100% similarity]
src/mesa/drivers/dri/i965/intel_mipmap_tree.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_mipmap_tree.h [moved from src/mesa/drivers/dri/intel/intel_mipmap_tree.h with 100% similarity]
src/mesa/drivers/dri/i965/intel_pixel.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_pixel.h [moved from src/mesa/drivers/dri/intel/intel_pixel.h with 100% similarity]
src/mesa/drivers/dri/i965/intel_pixel_bitmap.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_pixel_copy.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_pixel_draw.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_pixel_read.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_reg.h [moved from src/mesa/drivers/dri/intel/intel_reg.h with 100% similarity]
src/mesa/drivers/dri/i965/intel_regions.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_regions.h [moved from src/mesa/drivers/dri/intel/intel_regions.h with 100% similarity]
src/mesa/drivers/dri/i965/intel_resolve_map.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_resolve_map.h [moved from src/mesa/drivers/dri/intel/intel_resolve_map.h with 100% similarity]
src/mesa/drivers/dri/i965/intel_screen.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_screen.h [moved from src/mesa/drivers/dri/intel/intel_screen.h with 100% similarity]
src/mesa/drivers/dri/i965/intel_state.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_syncobj.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_tex.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_tex.h [moved from src/mesa/drivers/dri/intel/intel_tex.h with 100% similarity]
src/mesa/drivers/dri/i965/intel_tex_copy.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_tex_image.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_tex_layout.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_tex_layout.h [moved from src/mesa/drivers/dri/intel/intel_tex_layout.h with 100% similarity]
src/mesa/drivers/dri/i965/intel_tex_obj.h [moved from src/mesa/drivers/dri/intel/intel_tex_obj.h with 100% similarity]
src/mesa/drivers/dri/i965/intel_tex_subimage.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/i965/intel_tex_validate.c [changed from symlink to file mode: 0644]
src/mesa/drivers/dri/intel/intel_batchbuffer.c [deleted file]
src/mesa/drivers/dri/intel/intel_blit.c [deleted file]
src/mesa/drivers/dri/intel/intel_buffer_objects.c [deleted file]
src/mesa/drivers/dri/intel/intel_buffers.c [deleted file]
src/mesa/drivers/dri/intel/intel_context.c [deleted file]
src/mesa/drivers/dri/intel/intel_extensions.c [deleted file]
src/mesa/drivers/dri/intel/intel_fbo.c [deleted file]
src/mesa/drivers/dri/intel/intel_mipmap_tree.c [deleted file]
src/mesa/drivers/dri/intel/intel_pixel.c [deleted file]
src/mesa/drivers/dri/intel/intel_pixel_bitmap.c [deleted file]
src/mesa/drivers/dri/intel/intel_pixel_copy.c [deleted file]
src/mesa/drivers/dri/intel/intel_pixel_draw.c [deleted file]
src/mesa/drivers/dri/intel/intel_pixel_read.c [deleted file]
src/mesa/drivers/dri/intel/intel_regions.c [deleted file]
src/mesa/drivers/dri/intel/intel_resolve_map.c [deleted file]
src/mesa/drivers/dri/intel/intel_screen.c [deleted file]
src/mesa/drivers/dri/intel/intel_state.c [deleted file]
src/mesa/drivers/dri/intel/intel_syncobj.c [deleted file]
src/mesa/drivers/dri/intel/intel_tex.c [deleted file]
src/mesa/drivers/dri/intel/intel_tex_copy.c [deleted file]
src/mesa/drivers/dri/intel/intel_tex_image.c [deleted file]
src/mesa/drivers/dri/intel/intel_tex_layout.c [deleted file]
src/mesa/drivers/dri/intel/intel_tex_subimage.c [deleted file]
src/mesa/drivers/dri/intel/intel_tex_validate.c [deleted file]

index 32b041a..27c67d1 100644 (file)
@@ -31,7 +31,6 @@ AM_CFLAGS = \
        -I$(top_srcdir)/src/mapi \
        -I$(top_srcdir)/src/mesa/ \
        -I$(top_srcdir)/src/mesa/drivers/dri/common \
-       -I$(top_srcdir)/src/mesa/drivers/dri/intel \
        -I$(top_srcdir)/src/mesa/drivers/dri/intel/server \
        -I$(top_srcdir)/src/gtest/include \
        -I$(top_builddir)/src/mesa/drivers/dri/common \
deleted file mode 120000 (symlink)
index d38cdf31cc6c2d95a6f2970a9bbba75736bf2e3c..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_batchbuffer.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..8c6524e71af72205411a6d65487bacbbd52eb80c
--- /dev/null
@@ -0,0 +1,560 @@
+/**************************************************************************
+ * 
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#include "intel_context.h"
+#include "intel_batchbuffer.h"
+#include "intel_buffer_objects.h"
+#include "intel_reg.h"
+#include "intel_bufmgr.h"
+#include "intel_buffers.h"
+
+static void
+intel_batchbuffer_reset(struct intel_context *intel);
+
+struct cached_batch_item {
+   struct cached_batch_item *next;
+   uint16_t header;
+   uint16_t size;
+};
+
+static void clear_cache( struct intel_context *intel )
+{
+   struct cached_batch_item *item = intel->batch.cached_items;
+
+   while (item) {
+      struct cached_batch_item *next = item->next;
+      free(item);
+      item = next;
+   }
+
+   intel->batch.cached_items = NULL;
+}
+
+void
+intel_batchbuffer_init(struct intel_context *intel)
+{
+   intel_batchbuffer_reset(intel);
+
+   if (intel->gen >= 6) {
+      /* We can't just use brw_state_batch to get a chunk of space for
+       * the gen6 workaround because it involves actually writing to
+       * the buffer, and the kernel doesn't let us write to the batch.
+       */
+      intel->batch.workaround_bo = drm_intel_bo_alloc(intel->bufmgr,
+                                                     "pipe_control workaround",
+                                                     4096, 4096);
+   }
+
+   if (!intel->has_llc) {
+      intel->batch.cpu_map = malloc(intel->maxBatchSize);
+      intel->batch.map = intel->batch.cpu_map;
+   }
+}
+
+static void
+intel_batchbuffer_reset(struct intel_context *intel)
+{
+   if (intel->batch.last_bo != NULL) {
+      drm_intel_bo_unreference(intel->batch.last_bo);
+      intel->batch.last_bo = NULL;
+   }
+   intel->batch.last_bo = intel->batch.bo;
+
+   clear_cache(intel);
+
+   intel->batch.bo = drm_intel_bo_alloc(intel->bufmgr, "batchbuffer",
+                                       intel->maxBatchSize, 4096);
+   if (intel->has_llc) {
+      drm_intel_bo_map(intel->batch.bo, true);
+      intel->batch.map = intel->batch.bo->virtual;
+   }
+
+   intel->batch.reserved_space = BATCH_RESERVED;
+   intel->batch.state_batch_offset = intel->batch.bo->size;
+   intel->batch.used = 0;
+   intel->batch.needs_sol_reset = false;
+}
+
+void
+intel_batchbuffer_save_state(struct intel_context *intel)
+{
+   intel->batch.saved.used = intel->batch.used;
+   intel->batch.saved.reloc_count =
+      drm_intel_gem_bo_get_reloc_count(intel->batch.bo);
+}
+
+void
+intel_batchbuffer_reset_to_saved(struct intel_context *intel)
+{
+   drm_intel_gem_bo_clear_relocs(intel->batch.bo, intel->batch.saved.reloc_count);
+
+   intel->batch.used = intel->batch.saved.used;
+
+   /* Cached batch state is dead, since we just cleared some unknown part of the
+    * batchbuffer.  Assume that the caller resets any other state necessary.
+    */
+   clear_cache(intel);
+}
+
+void
+intel_batchbuffer_free(struct intel_context *intel)
+{
+   free(intel->batch.cpu_map);
+   drm_intel_bo_unreference(intel->batch.last_bo);
+   drm_intel_bo_unreference(intel->batch.bo);
+   drm_intel_bo_unreference(intel->batch.workaround_bo);
+   clear_cache(intel);
+}
+
+static void
+do_batch_dump(struct intel_context *intel)
+{
+   struct drm_intel_decode *decode;
+   struct intel_batchbuffer *batch = &intel->batch;
+   int ret;
+
+   decode = drm_intel_decode_context_alloc(intel->intelScreen->deviceID);
+   if (!decode)
+      return;
+
+   ret = drm_intel_bo_map(batch->bo, false);
+   if (ret == 0) {
+      drm_intel_decode_set_batch_pointer(decode,
+                                        batch->bo->virtual,
+                                        batch->bo->offset,
+                                        batch->used);
+   } else {
+      fprintf(stderr,
+             "WARNING: failed to map batchbuffer (%s), "
+             "dumping uploaded data instead.\n", strerror(ret));
+
+      drm_intel_decode_set_batch_pointer(decode,
+                                        batch->map,
+                                        batch->bo->offset,
+                                        batch->used);
+   }
+
+   drm_intel_decode(decode);
+
+   drm_intel_decode_context_free(decode);
+
+   if (ret == 0) {
+      drm_intel_bo_unmap(batch->bo);
+
+      if (intel->vtbl.debug_batch != NULL)
+        intel->vtbl.debug_batch(intel);
+   }
+}
+
+/* TODO: Push this whole function into bufmgr.
+ */
+static int
+do_flush_locked(struct intel_context *intel)
+{
+   struct intel_batchbuffer *batch = &intel->batch;
+   int ret = 0;
+
+   if (intel->has_llc) {
+      drm_intel_bo_unmap(batch->bo);
+   } else {
+      ret = drm_intel_bo_subdata(batch->bo, 0, 4*batch->used, batch->map);
+      if (ret == 0 && batch->state_batch_offset != batch->bo->size) {
+        ret = drm_intel_bo_subdata(batch->bo,
+                                   batch->state_batch_offset,
+                                   batch->bo->size - batch->state_batch_offset,
+                                   (char *)batch->map + batch->state_batch_offset);
+      }
+   }
+
+   if (!intel->intelScreen->no_hw) {
+      int flags;
+
+      if (intel->gen < 6 || !batch->is_blit) {
+        flags = I915_EXEC_RENDER;
+      } else {
+        flags = I915_EXEC_BLT;
+      }
+
+      if (batch->needs_sol_reset)
+        flags |= I915_EXEC_GEN7_SOL_RESET;
+
+      if (ret == 0) {
+         if (unlikely(INTEL_DEBUG & DEBUG_AUB) && intel->vtbl.annotate_aub)
+            intel->vtbl.annotate_aub(intel);
+        if (intel->hw_ctx == NULL || batch->is_blit) {
+           ret = drm_intel_bo_mrb_exec(batch->bo, 4 * batch->used, NULL, 0, 0,
+                                       flags);
+        } else {
+           ret = drm_intel_gem_bo_context_exec(batch->bo, intel->hw_ctx,
+                                               4 * batch->used, flags);
+        }
+      }
+   }
+
+   if (unlikely(INTEL_DEBUG & DEBUG_BATCH))
+      do_batch_dump(intel);
+
+   if (ret != 0) {
+      fprintf(stderr, "intel_do_flush_locked failed: %s\n", strerror(-ret));
+      exit(1);
+   }
+   intel->vtbl.new_batch(intel);
+
+   return ret;
+}
+
+int
+_intel_batchbuffer_flush(struct intel_context *intel,
+                        const char *file, int line)
+{
+   int ret;
+
+   if (intel->batch.used == 0)
+      return 0;
+
+   if (intel->first_post_swapbuffers_batch == NULL) {
+      intel->first_post_swapbuffers_batch = intel->batch.bo;
+      drm_intel_bo_reference(intel->first_post_swapbuffers_batch);
+   }
+
+   if (unlikely(INTEL_DEBUG & DEBUG_BATCH))
+      fprintf(stderr, "%s:%d: Batchbuffer flush with %db used\n", file, line,
+             4*intel->batch.used);
+
+   intel->batch.reserved_space = 0;
+
+   if (intel->vtbl.finish_batch)
+      intel->vtbl.finish_batch(intel);
+
+   /* Mark the end of the buffer. */
+   intel_batchbuffer_emit_dword(intel, MI_BATCH_BUFFER_END);
+   if (intel->batch.used & 1) {
+      /* Round batchbuffer usage to 2 DWORDs. */
+      intel_batchbuffer_emit_dword(intel, MI_NOOP);
+   }
+
+   intel_upload_finish(intel);
+
+   /* Check that we didn't just wrap our batchbuffer at a bad time. */
+   assert(!intel->no_batch_wrap);
+
+   ret = do_flush_locked(intel);
+
+   if (unlikely(INTEL_DEBUG & DEBUG_SYNC)) {
+      fprintf(stderr, "waiting for idle\n");
+      drm_intel_bo_wait_rendering(intel->batch.bo);
+   }
+
+   /* Reset the buffer:
+    */
+   intel_batchbuffer_reset(intel);
+
+   return ret;
+}
+
+
+/*  This is the only way buffers get added to the validate list.
+ */
+bool
+intel_batchbuffer_emit_reloc(struct intel_context *intel,
+                             drm_intel_bo *buffer,
+                             uint32_t read_domains, uint32_t write_domain,
+                            uint32_t delta)
+{
+   int ret;
+
+   ret = drm_intel_bo_emit_reloc(intel->batch.bo, 4*intel->batch.used,
+                                buffer, delta,
+                                read_domains, write_domain);
+   assert(ret == 0);
+   (void)ret;
+
+   /*
+    * Using the old buffer offset, write in what the right data would be, in case
+    * the buffer doesn't move and we can short-circuit the relocation processing
+    * in the kernel
+    */
+   intel_batchbuffer_emit_dword(intel, buffer->offset + delta);
+
+   return true;
+}
+
+bool
+intel_batchbuffer_emit_reloc_fenced(struct intel_context *intel,
+                                   drm_intel_bo *buffer,
+                                   uint32_t read_domains,
+                                   uint32_t write_domain,
+                                   uint32_t delta)
+{
+   int ret;
+
+   ret = drm_intel_bo_emit_reloc_fence(intel->batch.bo, 4*intel->batch.used,
+                                      buffer, delta,
+                                      read_domains, write_domain);
+   assert(ret == 0);
+   (void)ret;
+
+   /*
+    * Using the old buffer offset, write in what the right data would
+    * be, in case the buffer doesn't move and we can short-circuit the
+    * relocation processing in the kernel
+    */
+   intel_batchbuffer_emit_dword(intel, buffer->offset + delta);
+
+   return true;
+}
+
+void
+intel_batchbuffer_data(struct intel_context *intel,
+                       const void *data, GLuint bytes, bool is_blit)
+{
+   assert((bytes & 3) == 0);
+   intel_batchbuffer_require_space(intel, bytes, is_blit);
+   __memcpy(intel->batch.map + intel->batch.used, data, bytes);
+   intel->batch.used += bytes >> 2;
+}
+
+void
+intel_batchbuffer_cached_advance(struct intel_context *intel)
+{
+   struct cached_batch_item **prev = &intel->batch.cached_items, *item;
+   uint32_t sz = (intel->batch.used - intel->batch.emit) * sizeof(uint32_t);
+   uint32_t *start = intel->batch.map + intel->batch.emit;
+   uint16_t op = *start >> 16;
+
+   while (*prev) {
+      uint32_t *old;
+
+      item = *prev;
+      old = intel->batch.map + item->header;
+      if (op == *old >> 16) {
+        if (item->size == sz && memcmp(old, start, sz) == 0) {
+           if (prev != &intel->batch.cached_items) {
+              *prev = item->next;
+              item->next = intel->batch.cached_items;
+              intel->batch.cached_items = item;
+           }
+           intel->batch.used = intel->batch.emit;
+           return;
+        }
+
+        goto emit;
+      }
+      prev = &item->next;
+   }
+
+   item = malloc(sizeof(struct cached_batch_item));
+   if (item == NULL)
+      return;
+
+   item->next = intel->batch.cached_items;
+   intel->batch.cached_items = item;
+
+emit:
+   item->size = sz;
+   item->header = intel->batch.emit;
+}
+
+/**
+ * Restriction [DevSNB, DevIVB]:
+ *
+ * Prior to changing Depth/Stencil Buffer state (i.e. any combination of
+ * 3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS, 3DSTATE_STENCIL_BUFFER,
+ * 3DSTATE_HIER_DEPTH_BUFFER) SW must first issue a pipelined depth stall
+ * (PIPE_CONTROL with Depth Stall bit set), followed by a pipelined depth
+ * cache flush (PIPE_CONTROL with Depth Flush Bit set), followed by
+ * another pipelined depth stall (PIPE_CONTROL with Depth Stall bit set),
+ * unless SW can otherwise guarantee that the pipeline from WM onwards is
+ * already flushed (e.g., via a preceding MI_FLUSH).
+ */
+void
+intel_emit_depth_stall_flushes(struct intel_context *intel)
+{
+   assert(intel->gen >= 6 && intel->gen <= 7);
+
+   BEGIN_BATCH(4);
+   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
+   OUT_BATCH(PIPE_CONTROL_DEPTH_STALL);
+   OUT_BATCH(0); /* address */
+   OUT_BATCH(0); /* write data */
+   ADVANCE_BATCH()
+
+   BEGIN_BATCH(4);
+   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
+   OUT_BATCH(PIPE_CONTROL_DEPTH_CACHE_FLUSH);
+   OUT_BATCH(0); /* address */
+   OUT_BATCH(0); /* write data */
+   ADVANCE_BATCH();
+
+   BEGIN_BATCH(4);
+   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
+   OUT_BATCH(PIPE_CONTROL_DEPTH_STALL);
+   OUT_BATCH(0); /* address */
+   OUT_BATCH(0); /* write data */
+   ADVANCE_BATCH();
+}
+
+/**
+ * From the BSpec, volume 2a.03: VS Stage Input / State:
+ * "[DevIVB] A PIPE_CONTROL with Post-Sync Operation set to 1h and a depth
+ *  stall needs to be sent just prior to any 3DSTATE_VS, 3DSTATE_URB_VS,
+ *  3DSTATE_CONSTANT_VS, 3DSTATE_BINDING_TABLE_POINTER_VS,
+ *  3DSTATE_SAMPLER_STATE_POINTER_VS command.  Only one PIPE_CONTROL needs
+ *  to be sent before any combination of VS associated 3DSTATE."
+ */
+void
+gen7_emit_vs_workaround_flush(struct intel_context *intel)
+{
+   assert(intel->gen == 7);
+
+   BEGIN_BATCH(4);
+   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
+   OUT_BATCH(PIPE_CONTROL_DEPTH_STALL | PIPE_CONTROL_WRITE_IMMEDIATE);
+   OUT_RELOC(intel->batch.workaround_bo,
+            I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, 0);
+   OUT_BATCH(0); /* write data */
+   ADVANCE_BATCH();
+}
+
+/**
+ * Emits a PIPE_CONTROL with a non-zero post-sync operation, for
+ * implementing two workarounds on gen6.  From section 1.4.7.1
+ * "PIPE_CONTROL" of the Sandy Bridge PRM volume 2 part 1:
+ *
+ * [DevSNB-C+{W/A}] Before any depth stall flush (including those
+ * produced by non-pipelined state commands), software needs to first
+ * send a PIPE_CONTROL with no bits set except Post-Sync Operation !=
+ * 0.
+ *
+ * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache Flush Enable
+ * =1, a PIPE_CONTROL with any non-zero post-sync-op is required.
+ *
+ * And the workaround for these two requires this workaround first:
+ *
+ * [Dev-SNB{W/A}]: Pipe-control with CS-stall bit set must be sent
+ * BEFORE the pipe-control with a post-sync op and no write-cache
+ * flushes.
+ *
+ * And this last workaround is tricky because of the requirements on
+ * that bit.  From section 1.4.7.2.3 "Stall" of the Sandy Bridge PRM
+ * volume 2 part 1:
+ *
+ *     "1 of the following must also be set:
+ *      - Render Target Cache Flush Enable ([12] of DW1)
+ *      - Depth Cache Flush Enable ([0] of DW1)
+ *      - Stall at Pixel Scoreboard ([1] of DW1)
+ *      - Depth Stall ([13] of DW1)
+ *      - Post-Sync Operation ([13] of DW1)
+ *      - Notify Enable ([8] of DW1)"
+ *
+ * The cache flushes require the workaround flush that triggered this
+ * one, so we can't use it.  Depth stall would trigger the same.
+ * Post-sync nonzero is what triggered this second workaround, so we
+ * can't use that one either.  Notify enable is IRQs, which aren't
+ * really our business.  That leaves only stall at scoreboard.
+ */
+void
+intel_emit_post_sync_nonzero_flush(struct intel_context *intel)
+{
+   if (!intel->batch.need_workaround_flush)
+      return;
+
+   BEGIN_BATCH(4);
+   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
+   OUT_BATCH(PIPE_CONTROL_CS_STALL |
+            PIPE_CONTROL_STALL_AT_SCOREBOARD);
+   OUT_BATCH(0); /* address */
+   OUT_BATCH(0); /* write data */
+   ADVANCE_BATCH();
+
+   BEGIN_BATCH(4);
+   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
+   OUT_BATCH(PIPE_CONTROL_WRITE_IMMEDIATE);
+   OUT_RELOC(intel->batch.workaround_bo,
+            I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, 0);
+   OUT_BATCH(0); /* write data */
+   ADVANCE_BATCH();
+
+   intel->batch.need_workaround_flush = false;
+}
+
+/* Emit a pipelined flush to either flush render and texture cache for
+ * reading from a FBO-drawn texture, or flush so that frontbuffer
+ * render appears on the screen in DRI1.
+ *
+ * This is also used for the always_flush_cache driconf debug option.
+ */
+void
+intel_batchbuffer_emit_mi_flush(struct intel_context *intel)
+{
+   if (intel->gen >= 6) {
+      if (intel->batch.is_blit) {
+        BEGIN_BATCH_BLT(4);
+        OUT_BATCH(MI_FLUSH_DW);
+        OUT_BATCH(0);
+        OUT_BATCH(0);
+        OUT_BATCH(0);
+        ADVANCE_BATCH();
+      } else {
+        if (intel->gen == 6) {
+           /* Hardware workaround: SNB B-Spec says:
+            *
+            * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache
+            * Flush Enable =1, a PIPE_CONTROL with any non-zero
+            * post-sync-op is required.
+            */
+           intel_emit_post_sync_nonzero_flush(intel);
+        }
+
+        BEGIN_BATCH(4);
+        OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
+        OUT_BATCH(PIPE_CONTROL_INSTRUCTION_FLUSH |
+                  PIPE_CONTROL_WRITE_FLUSH |
+                  PIPE_CONTROL_DEPTH_CACHE_FLUSH |
+                   PIPE_CONTROL_VF_CACHE_INVALIDATE |
+                  PIPE_CONTROL_TC_FLUSH |
+                  PIPE_CONTROL_NO_WRITE |
+                   PIPE_CONTROL_CS_STALL);
+        OUT_BATCH(0); /* write address */
+        OUT_BATCH(0); /* write data */
+        ADVANCE_BATCH();
+      }
+   } else if (intel->gen >= 4) {
+      BEGIN_BATCH(4);
+      OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2) |
+               PIPE_CONTROL_WRITE_FLUSH |
+               PIPE_CONTROL_NO_WRITE);
+      OUT_BATCH(0); /* write address */
+      OUT_BATCH(0); /* write data */
+      OUT_BATCH(0); /* write data */
+      ADVANCE_BATCH();
+   } else {
+      BEGIN_BATCH(1);
+      OUT_BATCH(MI_FLUSH);
+      ADVANCE_BATCH();
+   }
+}
deleted file mode 120000 (symlink)
index dd6c8d17c2802ce43ddd3e96f326963284d2d6f6..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_blit.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..da56f55c4df323082c347c7b744eb709cabf3689
--- /dev/null
@@ -0,0 +1,770 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+
+#include "main/mtypes.h"
+#include "main/context.h"
+#include "main/enums.h"
+#include "main/colormac.h"
+#include "main/fbobject.h"
+
+#include "intel_blit.h"
+#include "intel_buffers.h"
+#include "intel_context.h"
+#include "intel_fbo.h"
+#include "intel_reg.h"
+#include "intel_regions.h"
+#include "intel_batchbuffer.h"
+#include "intel_mipmap_tree.h"
+
+#define FILE_DEBUG_FLAG DEBUG_BLIT
+
+static void
+intel_miptree_set_alpha_to_one(struct intel_context *intel,
+                               struct intel_mipmap_tree *mt,
+                               int x, int y, int width, int height);
+
+static GLuint translate_raster_op(GLenum logicop)
+{
+   switch(logicop) {
+   case GL_CLEAR: return 0x00;
+   case GL_AND: return 0x88;
+   case GL_AND_REVERSE: return 0x44;
+   case GL_COPY: return 0xCC;
+   case GL_AND_INVERTED: return 0x22;
+   case GL_NOOP: return 0xAA;
+   case GL_XOR: return 0x66;
+   case GL_OR: return 0xEE;
+   case GL_NOR: return 0x11;
+   case GL_EQUIV: return 0x99;
+   case GL_INVERT: return 0x55;
+   case GL_OR_REVERSE: return 0xDD;
+   case GL_COPY_INVERTED: return 0x33;
+   case GL_OR_INVERTED: return 0xBB;
+   case GL_NAND: return 0x77;
+   case GL_SET: return 0xFF;
+   default: return 0;
+   }
+}
+
+static uint32_t
+br13_for_cpp(int cpp)
+{
+   switch (cpp) {
+   case 4:
+      return BR13_8888;
+      break;
+   case 2:
+      return BR13_565;
+      break;
+   case 1:
+      return BR13_8;
+      break;
+   default:
+      assert(0);
+      return 0;
+   }
+}
+
+/**
+ * Emits the packet for switching the blitter from X to Y tiled or back.
+ *
+ * This has to be called in a single BEGIN_BATCH_BLT_TILED() /
+ * ADVANCE_BATCH_TILED().  This is because BCS_SWCTRL is saved and restored as
+ * part of the power context, not a render context, and if the batchbuffer was
+ * to get flushed between setting and blitting, or blitting and restoring, our
+ * tiling state would leak into other unsuspecting applications (like the X
+ * server).
+ */
+static void
+set_blitter_tiling(struct intel_context *intel,
+                   bool dst_y_tiled, bool src_y_tiled)
+{
+   assert(intel->gen >= 6);
+
+   /* Idle the blitter before we update how tiling is interpreted. */
+   OUT_BATCH(MI_FLUSH_DW);
+   OUT_BATCH(0);
+   OUT_BATCH(0);
+   OUT_BATCH(0);
+
+   OUT_BATCH(MI_LOAD_REGISTER_IMM | (3 - 2));
+   OUT_BATCH(BCS_SWCTRL);
+   OUT_BATCH((BCS_SWCTRL_DST_Y | BCS_SWCTRL_SRC_Y) << 16 |
+             (dst_y_tiled ? BCS_SWCTRL_DST_Y : 0) |
+             (src_y_tiled ? BCS_SWCTRL_SRC_Y : 0));
+}
+
+#define BEGIN_BATCH_BLT_TILED(n, dst_y_tiled, src_y_tiled) do {         \
+      BEGIN_BATCH_BLT(n + ((dst_y_tiled || src_y_tiled) ? 14 : 0));     \
+      if (dst_y_tiled || src_y_tiled)                                   \
+         set_blitter_tiling(intel, dst_y_tiled, src_y_tiled);           \
+   } while (0)
+
+#define ADVANCE_BATCH_TILED(dst_y_tiled, src_y_tiled) do {              \
+      if (dst_y_tiled || src_y_tiled)                                   \
+         set_blitter_tiling(intel, false, false);                       \
+      ADVANCE_BATCH();                                                  \
+   } while (0)
+
+/**
+ * Implements a rectangular block transfer (blit) of pixels between two
+ * miptrees.
+ *
+ * Our blitter can operate on 1, 2, or 4-byte-per-pixel data, with generous,
+ * but limited, pitches and sizes allowed.
+ *
+ * The src/dst coordinates are relative to the given level/slice of the
+ * miptree.
+ *
+ * If @src_flip or @dst_flip is set, then the rectangle within that miptree
+ * will be inverted (including scanline order) when copying.  This is common
+ * in GL when copying between window system and user-created
+ * renderbuffers/textures.
+ */
+bool
+intel_miptree_blit(struct intel_context *intel,
+                   struct intel_mipmap_tree *src_mt,
+                   int src_level, int src_slice,
+                   uint32_t src_x, uint32_t src_y, bool src_flip,
+                   struct intel_mipmap_tree *dst_mt,
+                   int dst_level, int dst_slice,
+                   uint32_t dst_x, uint32_t dst_y, bool dst_flip,
+                   uint32_t width, uint32_t height,
+                   GLenum logicop)
+{
+   /* No sRGB decode or encode is done by the hardware blitter, which is
+    * consistent with what we want in the callers (glCopyTexSubImage(),
+    * glBlitFramebuffer(), texture validation, etc.).
+    */
+   gl_format src_format = _mesa_get_srgb_format_linear(src_mt->format);
+   gl_format dst_format = _mesa_get_srgb_format_linear(dst_mt->format);
+
+   /* The blitter doesn't support doing any format conversions.  We do also
+    * support blitting ARGB8888 to XRGB8888 (trivial, the values dropped into
+    * the X channel don't matter), and XRGB8888 to ARGB8888 by setting the A
+    * channel to 1.0 at the end.
+    */
+   if (src_format != dst_format &&
+      ((src_format != MESA_FORMAT_ARGB8888 &&
+        src_format != MESA_FORMAT_XRGB8888) ||
+       (dst_format != MESA_FORMAT_ARGB8888 &&
+        dst_format != MESA_FORMAT_XRGB8888))) {
+      perf_debug("%s: Can't use hardware blitter from %s to %s, "
+                 "falling back.\n", __FUNCTION__,
+                 _mesa_get_format_name(src_format),
+                 _mesa_get_format_name(dst_format));
+      return false;
+   }
+
+   /* According to the Ivy Bridge PRM, Vol1 Part4, section 1.2.1.2 (Graphics
+    * Data Size Limitations):
+    *
+    *    The BLT engine is capable of transferring very large quantities of
+    *    graphics data. Any graphics data read from and written to the
+    *    destination is permitted to represent a number of pixels that
+    *    occupies up to 65,536 scan lines and up to 32,768 bytes per scan line
+    *    at the destination. The maximum number of pixels that may be
+    *    represented per scan line’s worth of graphics data depends on the
+    *    color depth.
+    *
+    * Furthermore, intelEmitCopyBlit (which is called below) uses a signed
+    * 16-bit integer to represent buffer pitch, so it can only handle buffer
+    * pitches < 32k.
+    *
+    * As a result of these two limitations, we can only use the blitter to do
+    * this copy when the region's pitch is less than 32k.
+    */
+   if (src_mt->region->pitch > 32768 ||
+       dst_mt->region->pitch > 32768) {
+      perf_debug("Falling back due to >32k pitch\n");
+      return false;
+   }
+
+   /* The blitter has no idea about HiZ or fast color clears, so we need to
+    * resolve the miptrees before we do anything.
+    */
+   intel_miptree_slice_resolve_depth(intel, src_mt, src_level, src_slice);
+   intel_miptree_slice_resolve_depth(intel, dst_mt, dst_level, dst_slice);
+   intel_miptree_resolve_color(intel, src_mt);
+   intel_miptree_resolve_color(intel, dst_mt);
+
+   if (src_flip)
+      src_y = src_mt->level[src_level].height - src_y - height;
+
+   if (dst_flip)
+      dst_y = dst_mt->level[dst_level].height - dst_y - height;
+
+   int src_pitch = src_mt->region->pitch;
+   if (src_flip != dst_flip)
+      src_pitch = -src_pitch;
+
+   uint32_t src_image_x, src_image_y;
+   intel_miptree_get_image_offset(src_mt, src_level, src_slice,
+                                  &src_image_x, &src_image_y);
+   src_x += src_image_x;
+   src_y += src_image_y;
+
+   uint32_t dst_image_x, dst_image_y;
+   intel_miptree_get_image_offset(dst_mt, dst_level, dst_slice,
+                                  &dst_image_x, &dst_image_y);
+   dst_x += dst_image_x;
+   dst_y += dst_image_y;
+
+   if (!intelEmitCopyBlit(intel,
+                          src_mt->cpp,
+                          src_pitch,
+                          src_mt->region->bo, src_mt->offset,
+                          src_mt->region->tiling,
+                          dst_mt->region->pitch,
+                          dst_mt->region->bo, dst_mt->offset,
+                          dst_mt->region->tiling,
+                          src_x, src_y,
+                          dst_x, dst_y,
+                          width, height,
+                          logicop)) {
+      return false;
+   }
+
+   if (src_mt->format == MESA_FORMAT_XRGB8888 &&
+       dst_mt->format == MESA_FORMAT_ARGB8888) {
+      intel_miptree_set_alpha_to_one(intel, dst_mt,
+                                     dst_x, dst_y,
+                                     width, height);
+   }
+
+   return true;
+}
+
+/* Copy BitBlt
+ */
+bool
+intelEmitCopyBlit(struct intel_context *intel,
+                 GLuint cpp,
+                 GLshort src_pitch,
+                 drm_intel_bo *src_buffer,
+                 GLuint src_offset,
+                 uint32_t src_tiling,
+                 GLshort dst_pitch,
+                 drm_intel_bo *dst_buffer,
+                 GLuint dst_offset,
+                 uint32_t dst_tiling,
+                 GLshort src_x, GLshort src_y,
+                 GLshort dst_x, GLshort dst_y,
+                 GLshort w, GLshort h,
+                 GLenum logic_op)
+{
+   GLuint CMD, BR13, pass = 0;
+   int dst_y2 = dst_y + h;
+   int dst_x2 = dst_x + w;
+   drm_intel_bo *aper_array[3];
+   bool dst_y_tiled = dst_tiling == I915_TILING_Y;
+   bool src_y_tiled = src_tiling == I915_TILING_Y;
+   BATCH_LOCALS;
+
+   if (dst_tiling != I915_TILING_NONE) {
+      if (dst_offset & 4095)
+        return false;
+   }
+   if (src_tiling != I915_TILING_NONE) {
+      if (src_offset & 4095)
+        return false;
+   }
+   if ((dst_y_tiled || src_y_tiled) && intel->gen < 6)
+      return false;
+
+   /* do space check before going any further */
+   do {
+       aper_array[0] = intel->batch.bo;
+       aper_array[1] = dst_buffer;
+       aper_array[2] = src_buffer;
+
+       if (dri_bufmgr_check_aperture_space(aper_array, 3) != 0) {
+           intel_batchbuffer_flush(intel);
+           pass++;
+       } else
+           break;
+   } while (pass < 2);
+
+   if (pass >= 2)
+      return false;
+
+   intel_batchbuffer_require_space(intel, 8 * 4, true);
+   DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
+       __FUNCTION__,
+       src_buffer, src_pitch, src_offset, src_x, src_y,
+       dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h);
+
+   /* Blit pitch must be dword-aligned.  Otherwise, the hardware appears to drop
+    * the low bits.
+    */
+   if (src_pitch % 4 != 0 || dst_pitch % 4 != 0)
+      return false;
+
+   /* For big formats (such as floating point), do the copy using 16 or 32bpp
+    * and multiply the coordinates.
+    */
+   if (cpp > 4) {
+      if (cpp % 4 == 2) {
+         dst_x *= cpp / 2;
+         dst_x2 *= cpp / 2;
+         src_x *= cpp / 2;
+         cpp = 2;
+      } else {
+         assert(cpp % 4 == 0);
+         dst_x *= cpp / 4;
+         dst_x2 *= cpp / 4;
+         src_x *= cpp / 4;
+         cpp = 4;
+      }
+   }
+
+   BR13 = br13_for_cpp(cpp) | translate_raster_op(logic_op) << 16;
+
+   switch (cpp) {
+   case 1:
+   case 2:
+      CMD = XY_SRC_COPY_BLT_CMD;
+      break;
+   case 4:
+      CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
+      break;
+   default:
+      return false;
+   }
+
+#ifndef I915
+   if (dst_tiling != I915_TILING_NONE) {
+      CMD |= XY_DST_TILED;
+      dst_pitch /= 4;
+   }
+   if (src_tiling != I915_TILING_NONE) {
+      CMD |= XY_SRC_TILED;
+      src_pitch /= 4;
+   }
+#endif
+
+   if (dst_y2 <= dst_y || dst_x2 <= dst_x) {
+      return true;
+   }
+
+   assert(dst_x < dst_x2);
+   assert(dst_y < dst_y2);
+
+   BEGIN_BATCH_BLT_TILED(8, dst_y_tiled, src_y_tiled);
+
+   OUT_BATCH(CMD | (8 - 2));
+   OUT_BATCH(BR13 | (uint16_t)dst_pitch);
+   OUT_BATCH((dst_y << 16) | dst_x);
+   OUT_BATCH((dst_y2 << 16) | dst_x2);
+   OUT_RELOC_FENCED(dst_buffer,
+                   I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
+                   dst_offset);
+   OUT_BATCH((src_y << 16) | src_x);
+   OUT_BATCH((uint16_t)src_pitch);
+   OUT_RELOC_FENCED(src_buffer,
+                   I915_GEM_DOMAIN_RENDER, 0,
+                   src_offset);
+
+   ADVANCE_BATCH_TILED(dst_y_tiled, src_y_tiled);
+
+   intel_batchbuffer_emit_mi_flush(intel);
+
+   return true;
+}
+
+
+/**
+ * Use blitting to clear the renderbuffers named by 'flags'.
+ * Note: we can't use the ctx->DrawBuffer->_ColorDrawBufferIndexes field
+ * since that might include software renderbuffers or renderbuffers
+ * which we're clearing with triangles.
+ * \param mask  bitmask of BUFFER_BIT_* values indicating buffers to clear
+ */
+GLbitfield
+intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct gl_framebuffer *fb = ctx->DrawBuffer;
+   GLuint clear_depth_value, clear_depth_mask;
+   GLint cx, cy, cw, ch;
+   GLbitfield fail_mask = 0;
+   BATCH_LOCALS;
+
+   /* Note: we don't use this function on Gen7+ hardware, so we can safely
+    * ignore fast color clear issues.
+    */
+   assert(intel->gen < 7);
+
+   /*
+    * Compute values for clearing the buffers.
+    */
+   clear_depth_value = 0;
+   clear_depth_mask = 0;
+   if (mask & BUFFER_BIT_DEPTH) {
+      clear_depth_value = (GLuint) (fb->_DepthMax * ctx->Depth.Clear);
+      clear_depth_mask = XY_BLT_WRITE_RGB;
+   }
+   if (mask & BUFFER_BIT_STENCIL) {
+      clear_depth_value |= (ctx->Stencil.Clear & 0xff) << 24;
+      clear_depth_mask |= XY_BLT_WRITE_ALPHA;
+   }
+
+   cx = fb->_Xmin;
+   if (_mesa_is_winsys_fbo(fb))
+      cy = ctx->DrawBuffer->Height - fb->_Ymax;
+   else
+      cy = fb->_Ymin;
+   cw = fb->_Xmax - fb->_Xmin;
+   ch = fb->_Ymax - fb->_Ymin;
+
+   if (cw == 0 || ch == 0)
+      return 0;
+
+   /* Loop over all renderbuffers */
+   mask &= (1 << BUFFER_COUNT) - 1;
+   while (mask) {
+      GLuint buf = ffs(mask) - 1;
+      bool is_depth_stencil = buf == BUFFER_DEPTH || buf == BUFFER_STENCIL;
+      struct intel_renderbuffer *irb;
+      int x1, y1, x2, y2;
+      uint32_t clear_val;
+      uint32_t BR13, CMD;
+      struct intel_region *region;
+      int pitch, cpp;
+      drm_intel_bo *aper_array[2];
+
+      mask &= ~(1 << buf);
+
+      irb = intel_get_renderbuffer(fb, buf);
+      if (irb && irb->mt) {
+        region = irb->mt->region;
+        assert(region);
+        assert(region->bo);
+      } else {
+         fail_mask |= 1 << buf;
+         continue;
+      }
+
+      /* OK, clear this renderbuffer */
+      x1 = cx + irb->draw_x;
+      y1 = cy + irb->draw_y;
+      x2 = cx + cw + irb->draw_x;
+      y2 = cy + ch + irb->draw_y;
+
+      pitch = region->pitch;
+      cpp = region->cpp;
+
+      DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n",
+         __FUNCTION__,
+         region->bo, pitch,
+         x1, y1, x2 - x1, y2 - y1);
+
+      BR13 = 0xf0 << 16;
+      CMD = XY_COLOR_BLT_CMD;
+
+      /* Setup the blit command */
+      if (cpp == 4) {
+        if (is_depth_stencil) {
+           CMD |= clear_depth_mask;
+        } else {
+           /* clearing RGBA */
+           CMD |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
+        }
+      }
+
+      assert(region->tiling != I915_TILING_Y);
+
+#ifndef I915
+      if (region->tiling != I915_TILING_NONE) {
+        CMD |= XY_DST_TILED;
+        pitch /= 4;
+      }
+#endif
+      BR13 |= pitch;
+
+      if (is_depth_stencil) {
+        clear_val = clear_depth_value;
+      } else {
+        uint8_t clear[4];
+        GLfloat *color = ctx->Color.ClearColor.f;
+
+        _mesa_unclamped_float_rgba_to_ubyte(clear, color);
+
+        switch (intel_rb_format(irb)) {
+        case MESA_FORMAT_ARGB8888:
+        case MESA_FORMAT_XRGB8888:
+           clear_val = PACK_COLOR_8888(clear[3], clear[0],
+                                       clear[1], clear[2]);
+           break;
+        case MESA_FORMAT_RGB565:
+           clear_val = PACK_COLOR_565(clear[0], clear[1], clear[2]);
+           break;
+        case MESA_FORMAT_ARGB4444:
+           clear_val = PACK_COLOR_4444(clear[3], clear[0],
+                                       clear[1], clear[2]);
+           break;
+        case MESA_FORMAT_ARGB1555:
+           clear_val = PACK_COLOR_1555(clear[3], clear[0],
+                                       clear[1], clear[2]);
+           break;
+        case MESA_FORMAT_A8:
+           clear_val = PACK_COLOR_8888(clear[3], clear[3],
+                                       clear[3], clear[3]);
+           break;
+        default:
+           fail_mask |= 1 << buf;
+           continue;
+        }
+      }
+
+      BR13 |= br13_for_cpp(cpp);
+
+      assert(x1 < x2);
+      assert(y1 < y2);
+
+      /* do space check before going any further */
+      aper_array[0] = intel->batch.bo;
+      aper_array[1] = region->bo;
+
+      if (drm_intel_bufmgr_check_aperture_space(aper_array,
+                                               ARRAY_SIZE(aper_array)) != 0) {
+        intel_batchbuffer_flush(intel);
+      }
+
+      BEGIN_BATCH_BLT(6);
+      OUT_BATCH(CMD | (6 - 2));
+      OUT_BATCH(BR13);
+      OUT_BATCH((y1 << 16) | x1);
+      OUT_BATCH((y2 << 16) | x2);
+      OUT_RELOC_FENCED(region->bo,
+                      I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
+                      0);
+      OUT_BATCH(clear_val);
+      ADVANCE_BATCH();
+
+      if (intel->always_flush_cache)
+        intel_batchbuffer_emit_mi_flush(intel);
+
+      if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL)
+        mask &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
+   }
+
+   return fail_mask;
+}
+
+bool
+intelEmitImmediateColorExpandBlit(struct intel_context *intel,
+                                 GLuint cpp,
+                                 GLubyte *src_bits, GLuint src_size,
+                                 GLuint fg_color,
+                                 GLshort dst_pitch,
+                                 drm_intel_bo *dst_buffer,
+                                 GLuint dst_offset,
+                                 uint32_t dst_tiling,
+                                 GLshort x, GLshort y,
+                                 GLshort w, GLshort h,
+                                 GLenum logic_op)
+{
+   int dwords = ALIGN(src_size, 8) / 4;
+   uint32_t opcode, br13, blit_cmd;
+
+   if (dst_tiling != I915_TILING_NONE) {
+      if (dst_offset & 4095)
+        return false;
+      if (dst_tiling == I915_TILING_Y)
+        return false;
+   }
+
+   assert( logic_op - GL_CLEAR >= 0 );
+   assert( logic_op - GL_CLEAR < 0x10 );
+   assert(dst_pitch > 0);
+
+   if (w < 0 || h < 0)
+      return true;
+
+   DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d, %d bytes %d dwords\n",
+       __FUNCTION__,
+       dst_buffer, dst_pitch, dst_offset, x, y, w, h, src_size, dwords);
+
+   intel_batchbuffer_require_space(intel,
+                                  (8 * 4) +
+                                  (3 * 4) +
+                                  dwords * 4, true);
+
+   opcode = XY_SETUP_BLT_CMD;
+   if (cpp == 4)
+      opcode |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
+#ifndef I915
+   if (dst_tiling != I915_TILING_NONE) {
+      opcode |= XY_DST_TILED;
+      dst_pitch /= 4;
+   }
+#endif
+
+   br13 = dst_pitch | (translate_raster_op(logic_op) << 16) | (1 << 29);
+   br13 |= br13_for_cpp(cpp);
+
+   blit_cmd = XY_TEXT_IMMEDIATE_BLIT_CMD | XY_TEXT_BYTE_PACKED; /* packing? */
+   if (dst_tiling != I915_TILING_NONE)
+      blit_cmd |= XY_DST_TILED;
+
+   BEGIN_BATCH_BLT(8 + 3);
+   OUT_BATCH(opcode | (8 - 2));
+   OUT_BATCH(br13);
+   OUT_BATCH((0 << 16) | 0); /* clip x1, y1 */
+   OUT_BATCH((100 << 16) | 100); /* clip x2, y2 */
+   OUT_RELOC_FENCED(dst_buffer,
+                   I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
+                   dst_offset);
+   OUT_BATCH(0); /* bg */
+   OUT_BATCH(fg_color); /* fg */
+   OUT_BATCH(0); /* pattern base addr */
+
+   OUT_BATCH(blit_cmd | ((3 - 2) + dwords));
+   OUT_BATCH((y << 16) | x);
+   OUT_BATCH(((y + h) << 16) | (x + w));
+   ADVANCE_BATCH();
+
+   intel_batchbuffer_data(intel, src_bits, dwords * 4, true);
+
+   intel_batchbuffer_emit_mi_flush(intel);
+
+   return true;
+}
+
+/* We don't have a memmove-type blit like some other hardware, so we'll do a
+ * rectangular blit covering a large space, then emit 1-scanline blit at the
+ * end to cover the last if we need.
+ */
+void
+intel_emit_linear_blit(struct intel_context *intel,
+                      drm_intel_bo *dst_bo,
+                      unsigned int dst_offset,
+                      drm_intel_bo *src_bo,
+                      unsigned int src_offset,
+                      unsigned int size)
+{
+   struct gl_context *ctx = &intel->ctx;
+   GLuint pitch, height;
+   bool ok;
+
+   /* The pitch given to the GPU must be DWORD aligned, and
+    * we want width to match pitch. Max width is (1 << 15 - 1),
+    * rounding that down to the nearest DWORD is 1 << 15 - 4
+    */
+   pitch = ROUND_DOWN_TO(MIN2(size, (1 << 15) - 1), 4);
+   height = (pitch == 0) ? 1 : size / pitch;
+   ok = intelEmitCopyBlit(intel, 1,
+                         pitch, src_bo, src_offset, I915_TILING_NONE,
+                         pitch, dst_bo, dst_offset, I915_TILING_NONE,
+                         0, 0, /* src x/y */
+                         0, 0, /* dst x/y */
+                         pitch, height, /* w, h */
+                         GL_COPY);
+   if (!ok)
+      _mesa_problem(ctx, "Failed to linear blit %dx%d\n", pitch, height);
+
+   src_offset += pitch * height;
+   dst_offset += pitch * height;
+   size -= pitch * height;
+   assert (size < (1 << 15));
+   pitch = ALIGN(size, 4);
+   if (size != 0) {
+      ok = intelEmitCopyBlit(intel, 1,
+                            pitch, src_bo, src_offset, I915_TILING_NONE,
+                            pitch, dst_bo, dst_offset, I915_TILING_NONE,
+                            0, 0, /* src x/y */
+                            0, 0, /* dst x/y */
+                            size, 1, /* w, h */
+                            GL_COPY);
+      if (!ok)
+         _mesa_problem(ctx, "Failed to linear blit %dx%d\n", size, 1);
+   }
+}
+
+/**
+ * Used to initialize the alpha value of an ARGB8888 miptree after copying
+ * into it from an XRGB8888 source.
+ *
+ * This is very common with glCopyTexImage2D().  Note that the coordinates are
+ * relative to the start of the miptree, not relative to a slice within the
+ * miptree.
+ */
+static void
+intel_miptree_set_alpha_to_one(struct intel_context *intel,
+                              struct intel_mipmap_tree *mt,
+                              int x, int y, int width, int height)
+{
+   struct intel_region *region = mt->region;
+   uint32_t BR13, CMD;
+   int pitch, cpp;
+   drm_intel_bo *aper_array[2];
+   BATCH_LOCALS;
+
+   pitch = region->pitch;
+   cpp = region->cpp;
+
+   DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n",
+       __FUNCTION__, region->bo, pitch, x, y, width, height);
+
+   BR13 = br13_for_cpp(cpp) | 0xf0 << 16;
+   CMD = XY_COLOR_BLT_CMD;
+   CMD |= XY_BLT_WRITE_ALPHA;
+
+#ifndef I915
+   if (region->tiling != I915_TILING_NONE) {
+      CMD |= XY_DST_TILED;
+      pitch /= 4;
+   }
+#endif
+   BR13 |= pitch;
+
+   /* do space check before going any further */
+   aper_array[0] = intel->batch.bo;
+   aper_array[1] = region->bo;
+
+   if (drm_intel_bufmgr_check_aperture_space(aper_array,
+                                            ARRAY_SIZE(aper_array)) != 0) {
+      intel_batchbuffer_flush(intel);
+   }
+
+   bool dst_y_tiled = region->tiling == I915_TILING_Y;
+
+   BEGIN_BATCH_BLT_TILED(6, dst_y_tiled, false);
+   OUT_BATCH(CMD | (6 - 2));
+   OUT_BATCH(BR13);
+   OUT_BATCH((y << 16) | x);
+   OUT_BATCH(((y + height) << 16) | (x + width));
+   OUT_RELOC_FENCED(region->bo,
+                   I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
+                   0);
+   OUT_BATCH(0xffffffff); /* white, but only alpha gets written */
+   ADVANCE_BATCH_TILED(dst_y_tiled, false);
+
+   intel_batchbuffer_emit_mi_flush(intel);
+}
deleted file mode 120000 (symlink)
index e06dd3c8d3c54014cf16e795a8c3d139b2ebfb59..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_buffer_objects.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..f568864f4b4c38b73dbc6a7055a8bccbd169cf87
--- /dev/null
@@ -0,0 +1,853 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+
+#include "main/imports.h"
+#include "main/mtypes.h"
+#include "main/macros.h"
+#include "main/bufferobj.h"
+
+#include "intel_blit.h"
+#include "intel_buffer_objects.h"
+#include "intel_batchbuffer.h"
+#include "intel_context.h"
+#include "intel_fbo.h"
+#include "intel_mipmap_tree.h"
+#include "intel_regions.h"
+
+#ifndef I915
+#include "brw_context.h"
+#endif
+
+static GLboolean
+intel_bufferobj_unmap(struct gl_context * ctx, struct gl_buffer_object *obj);
+
+/** Allocates a new drm_intel_bo to store the data for the buffer object. */
+static void
+intel_bufferobj_alloc_buffer(struct intel_context *intel,
+                            struct intel_buffer_object *intel_obj)
+{
+   intel_obj->buffer = drm_intel_bo_alloc(intel->bufmgr, "bufferobj",
+                                         intel_obj->Base.Size, 64);
+
+#ifndef I915
+   /* the buffer might be bound as a uniform buffer, need to update it
+    */
+   {
+      struct brw_context *brw = brw_context(&intel->ctx);
+      brw->state.dirty.brw |= BRW_NEW_UNIFORM_BUFFER;
+   }
+#endif
+}
+
+static void
+release_buffer(struct intel_buffer_object *intel_obj)
+{
+   drm_intel_bo_unreference(intel_obj->buffer);
+   intel_obj->buffer = NULL;
+   intel_obj->offset = 0;
+   intel_obj->source = 0;
+}
+
+/**
+ * There is some duplication between mesa's bufferobjects and our
+ * bufmgr buffers.  Both have an integer handle and a hashtable to
+ * lookup an opaque structure.  It would be nice if the handles and
+ * internal structure where somehow shared.
+ */
+static struct gl_buffer_object *
+intel_bufferobj_alloc(struct gl_context * ctx, GLuint name, GLenum target)
+{
+   struct intel_buffer_object *obj = CALLOC_STRUCT(intel_buffer_object);
+
+   _mesa_initialize_buffer_object(ctx, &obj->Base, name, target);
+
+   obj->buffer = NULL;
+
+   return &obj->Base;
+}
+
+/**
+ * Deallocate/free a vertex/pixel buffer object.
+ * Called via glDeleteBuffersARB().
+ */
+static void
+intel_bufferobj_free(struct gl_context * ctx, struct gl_buffer_object *obj)
+{
+   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
+
+   assert(intel_obj);
+
+   /* Buffer objects are automatically unmapped when deleting according
+    * to the spec, but Mesa doesn't do UnmapBuffer for us at context destroy
+    * (though it does if you call glDeleteBuffers)
+    */
+   if (obj->Pointer)
+      intel_bufferobj_unmap(ctx, obj);
+
+   free(intel_obj->sys_buffer);
+
+   drm_intel_bo_unreference(intel_obj->buffer);
+   free(intel_obj);
+}
+
+
+
+/**
+ * Allocate space for and store data in a buffer object.  Any data that was
+ * previously stored in the buffer object is lost.  If data is NULL,
+ * memory will be allocated, but no copy will occur.
+ * Called via ctx->Driver.BufferData().
+ * \return true for success, false if out of memory
+ */
+static GLboolean
+intel_bufferobj_data(struct gl_context * ctx,
+                     GLenum target,
+                     GLsizeiptrARB size,
+                     const GLvoid * data,
+                     GLenum usage, struct gl_buffer_object *obj)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
+
+   /* Part of the ABI, but this function doesn't use it.
+    */
+#ifndef I915
+   (void) target;
+#endif
+
+   intel_obj->Base.Size = size;
+   intel_obj->Base.Usage = usage;
+
+   assert(!obj->Pointer); /* Mesa should have unmapped it */
+
+   if (intel_obj->buffer != NULL)
+      release_buffer(intel_obj);
+
+   free(intel_obj->sys_buffer);
+   intel_obj->sys_buffer = NULL;
+
+   if (size != 0) {
+#ifdef I915
+      /* On pre-965, stick VBOs in system memory, as we're always doing
+       * swtnl with their contents anyway.
+       */
+      if (target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER) {
+        intel_obj->sys_buffer = malloc(size);
+        if (intel_obj->sys_buffer != NULL) {
+           if (data != NULL)
+              memcpy(intel_obj->sys_buffer, data, size);
+           return true;
+        }
+      }
+#endif
+      intel_bufferobj_alloc_buffer(intel, intel_obj);
+      if (!intel_obj->buffer)
+         return false;
+
+      if (data != NULL)
+        drm_intel_bo_subdata(intel_obj->buffer, 0, size, data);
+   }
+
+   return true;
+}
+
+
+/**
+ * Replace data in a subrange of buffer object.  If the data range
+ * specified by size + offset extends beyond the end of the buffer or
+ * if data is NULL, no copy is performed.
+ * Called via glBufferSubDataARB().
+ */
+static void
+intel_bufferobj_subdata(struct gl_context * ctx,
+                        GLintptrARB offset,
+                        GLsizeiptrARB size,
+                        const GLvoid * data, struct gl_buffer_object *obj)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
+   bool busy;
+
+   if (size == 0)
+      return;
+
+   assert(intel_obj);
+
+   /* If we have a single copy in system memory, update that */
+   if (intel_obj->sys_buffer) {
+      if (intel_obj->source)
+        release_buffer(intel_obj);
+
+      if (intel_obj->buffer == NULL) {
+        memcpy((char *)intel_obj->sys_buffer + offset, data, size);
+        return;
+      }
+
+      free(intel_obj->sys_buffer);
+      intel_obj->sys_buffer = NULL;
+   }
+
+   /* Otherwise we need to update the copy in video memory. */
+   busy =
+      drm_intel_bo_busy(intel_obj->buffer) ||
+      drm_intel_bo_references(intel->batch.bo, intel_obj->buffer);
+
+   if (busy) {
+      if (size == intel_obj->Base.Size) {
+        /* Replace the current busy bo with fresh data. */
+        drm_intel_bo_unreference(intel_obj->buffer);
+        intel_bufferobj_alloc_buffer(intel, intel_obj);
+        drm_intel_bo_subdata(intel_obj->buffer, 0, size, data);
+      } else {
+         perf_debug("Using a blit copy to avoid stalling on %ldb "
+                    "glBufferSubData() to a busy buffer object.\n",
+                    (long)size);
+        drm_intel_bo *temp_bo =
+           drm_intel_bo_alloc(intel->bufmgr, "subdata temp", size, 64);
+
+        drm_intel_bo_subdata(temp_bo, 0, size, data);
+
+        intel_emit_linear_blit(intel,
+                               intel_obj->buffer, offset,
+                               temp_bo, 0,
+                               size);
+
+        drm_intel_bo_unreference(temp_bo);
+      }
+   } else {
+      drm_intel_bo_subdata(intel_obj->buffer, offset, size, data);
+   }
+}
+
+
+/**
+ * Called via glGetBufferSubDataARB().
+ */
+static void
+intel_bufferobj_get_subdata(struct gl_context * ctx,
+                            GLintptrARB offset,
+                            GLsizeiptrARB size,
+                            GLvoid * data, struct gl_buffer_object *obj)
+{
+   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
+   struct intel_context *intel = intel_context(ctx);
+
+   assert(intel_obj);
+   if (intel_obj->sys_buffer)
+      memcpy(data, (char *)intel_obj->sys_buffer + offset, size);
+   else {
+      if (drm_intel_bo_references(intel->batch.bo, intel_obj->buffer)) {
+        intel_batchbuffer_flush(intel);
+      }
+      drm_intel_bo_get_subdata(intel_obj->buffer, offset, size, data);
+   }
+}
+
+
+
+/**
+ * Called via glMapBufferRange and glMapBuffer
+ *
+ * The goal of this extension is to allow apps to accumulate their rendering
+ * at the same time as they accumulate their buffer object.  Without it,
+ * you'd end up blocking on execution of rendering every time you mapped
+ * the buffer to put new data in.
+ *
+ * We support it in 3 ways: If unsynchronized, then don't bother
+ * flushing the batchbuffer before mapping the buffer, which can save blocking
+ * in many cases.  If we would still block, and they allow the whole buffer
+ * to be invalidated, then just allocate a new buffer to replace the old one.
+ * If not, and we'd block, and they allow the subrange of the buffer to be
+ * invalidated, then we can make a new little BO, let them write into that,
+ * and blit it into the real BO at unmap time.
+ */
+static void *
+intel_bufferobj_map_range(struct gl_context * ctx,
+                         GLintptr offset, GLsizeiptr length,
+                         GLbitfield access, struct gl_buffer_object *obj)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
+
+   assert(intel_obj);
+
+   /* _mesa_MapBufferRange (GL entrypoint) sets these, but the vbo module also
+    * internally uses our functions directly.
+    */
+   obj->Offset = offset;
+   obj->Length = length;
+   obj->AccessFlags = access;
+
+   if (intel_obj->sys_buffer) {
+      const bool read_only =
+        (access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == GL_MAP_READ_BIT;
+
+      if (!read_only && intel_obj->source)
+        release_buffer(intel_obj);
+
+      if (!intel_obj->buffer || intel_obj->source) {
+        obj->Pointer = intel_obj->sys_buffer + offset;
+        return obj->Pointer;
+      }
+
+      free(intel_obj->sys_buffer);
+      intel_obj->sys_buffer = NULL;
+   }
+
+   if (intel_obj->buffer == NULL) {
+      obj->Pointer = NULL;
+      return NULL;
+   }
+
+   /* If the access is synchronized (like a normal buffer mapping), then get
+    * things flushed out so the later mapping syncs appropriately through GEM.
+    * If the user doesn't care about existing buffer contents and mapping would
+    * cause us to block, then throw out the old buffer.
+    *
+    * If they set INVALIDATE_BUFFER, we can pitch the current contents to
+    * achieve the required synchronization.
+    */
+   if (!(access & GL_MAP_UNSYNCHRONIZED_BIT)) {
+      if (drm_intel_bo_references(intel->batch.bo, intel_obj->buffer)) {
+        if (access & GL_MAP_INVALIDATE_BUFFER_BIT) {
+           drm_intel_bo_unreference(intel_obj->buffer);
+           intel_bufferobj_alloc_buffer(intel, intel_obj);
+        } else {
+            perf_debug("Stalling on the GPU for mapping a busy buffer "
+                       "object\n");
+           intel_flush(ctx);
+        }
+      } else if (drm_intel_bo_busy(intel_obj->buffer) &&
+                (access & GL_MAP_INVALIDATE_BUFFER_BIT)) {
+        drm_intel_bo_unreference(intel_obj->buffer);
+        intel_bufferobj_alloc_buffer(intel, intel_obj);
+      }
+   }
+
+   /* If the user is mapping a range of an active buffer object but
+    * doesn't require the current contents of that range, make a new
+    * BO, and we'll copy what they put in there out at unmap or
+    * FlushRange time.
+    */
+   if ((access & GL_MAP_INVALIDATE_RANGE_BIT) &&
+       drm_intel_bo_busy(intel_obj->buffer)) {
+      if (access & GL_MAP_FLUSH_EXPLICIT_BIT) {
+        intel_obj->range_map_buffer = malloc(length);
+        obj->Pointer = intel_obj->range_map_buffer;
+      } else {
+        intel_obj->range_map_bo = drm_intel_bo_alloc(intel->bufmgr,
+                                                     "range map",
+                                                     length, 64);
+        if (!(access & GL_MAP_READ_BIT)) {
+           drm_intel_gem_bo_map_gtt(intel_obj->range_map_bo);
+        } else {
+           drm_intel_bo_map(intel_obj->range_map_bo,
+                            (access & GL_MAP_WRITE_BIT) != 0);
+        }
+        obj->Pointer = intel_obj->range_map_bo->virtual;
+      }
+      return obj->Pointer;
+   }
+
+   if (access & GL_MAP_UNSYNCHRONIZED_BIT)
+      drm_intel_gem_bo_map_unsynchronized(intel_obj->buffer);
+   else if (!(access & GL_MAP_READ_BIT)) {
+      drm_intel_gem_bo_map_gtt(intel_obj->buffer);
+   } else {
+      drm_intel_bo_map(intel_obj->buffer, (access & GL_MAP_WRITE_BIT) != 0);
+   }
+
+   obj->Pointer = intel_obj->buffer->virtual + offset;
+   return obj->Pointer;
+}
+
+/* Ideally we'd use a BO to avoid taking up cache space for the temporary
+ * data, but FlushMappedBufferRange may be followed by further writes to
+ * the pointer, so we would have to re-map after emitting our blit, which
+ * would defeat the point.
+ */
+static void
+intel_bufferobj_flush_mapped_range(struct gl_context *ctx,
+                                  GLintptr offset, GLsizeiptr length,
+                                  struct gl_buffer_object *obj)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
+   drm_intel_bo *temp_bo;
+
+   /* Unless we're in the range map using a temporary system buffer,
+    * there's no work to do.
+    */
+   if (intel_obj->range_map_buffer == NULL)
+      return;
+
+   if (length == 0)
+      return;
+
+   temp_bo = drm_intel_bo_alloc(intel->bufmgr, "range map flush", length, 64);
+
+   drm_intel_bo_subdata(temp_bo, 0, length, intel_obj->range_map_buffer);
+
+   intel_emit_linear_blit(intel,
+                         intel_obj->buffer, obj->Offset + offset,
+                         temp_bo, 0,
+                         length);
+
+   drm_intel_bo_unreference(temp_bo);
+}
+
+
+/**
+ * Called via glUnmapBuffer().
+ */
+static GLboolean
+intel_bufferobj_unmap(struct gl_context * ctx, struct gl_buffer_object *obj)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
+
+   assert(intel_obj);
+   assert(obj->Pointer);
+   if (intel_obj->sys_buffer != NULL) {
+      /* always keep the mapping around. */
+   } else if (intel_obj->range_map_buffer != NULL) {
+      /* Since we've emitted some blits to buffers that will (likely) be used
+       * in rendering operations in other cache domains in this batch, emit a
+       * flush.  Once again, we wish for a domain tracker in libdrm to cover
+       * usage inside of a batchbuffer.
+       */
+      intel_batchbuffer_emit_mi_flush(intel);
+      free(intel_obj->range_map_buffer);
+      intel_obj->range_map_buffer = NULL;
+   } else if (intel_obj->range_map_bo != NULL) {
+      drm_intel_bo_unmap(intel_obj->range_map_bo);
+
+      intel_emit_linear_blit(intel,
+                            intel_obj->buffer, obj->Offset,
+                            intel_obj->range_map_bo, 0,
+                            obj->Length);
+
+      /* Since we've emitted some blits to buffers that will (likely) be used
+       * in rendering operations in other cache domains in this batch, emit a
+       * flush.  Once again, we wish for a domain tracker in libdrm to cover
+       * usage inside of a batchbuffer.
+       */
+      intel_batchbuffer_emit_mi_flush(intel);
+
+      drm_intel_bo_unreference(intel_obj->range_map_bo);
+      intel_obj->range_map_bo = NULL;
+   } else if (intel_obj->buffer != NULL) {
+      drm_intel_bo_unmap(intel_obj->buffer);
+   }
+   obj->Pointer = NULL;
+   obj->Offset = 0;
+   obj->Length = 0;
+
+   return true;
+}
+
+drm_intel_bo *
+intel_bufferobj_buffer(struct intel_context *intel,
+                       struct intel_buffer_object *intel_obj,
+                      GLuint flag)
+{
+   if (intel_obj->source)
+      release_buffer(intel_obj);
+
+   if (intel_obj->buffer == NULL) {
+      intel_bufferobj_alloc_buffer(intel, intel_obj);
+      drm_intel_bo_subdata(intel_obj->buffer,
+                          0, intel_obj->Base.Size,
+                          intel_obj->sys_buffer);
+
+      free(intel_obj->sys_buffer);
+      intel_obj->sys_buffer = NULL;
+      intel_obj->offset = 0;
+   }
+
+   return intel_obj->buffer;
+}
+
+#define INTEL_UPLOAD_SIZE (64*1024)
+
+void
+intel_upload_finish(struct intel_context *intel)
+{
+   if (!intel->upload.bo)
+          return;
+
+   if (intel->upload.buffer_len) {
+          drm_intel_bo_subdata(intel->upload.bo,
+                               intel->upload.buffer_offset,
+                               intel->upload.buffer_len,
+                               intel->upload.buffer);
+          intel->upload.buffer_len = 0;
+   }
+
+   drm_intel_bo_unreference(intel->upload.bo);
+   intel->upload.bo = NULL;
+}
+
+static void wrap_buffers(struct intel_context *intel, GLuint size)
+{
+   intel_upload_finish(intel);
+
+   if (size < INTEL_UPLOAD_SIZE)
+      size = INTEL_UPLOAD_SIZE;
+
+   intel->upload.bo = drm_intel_bo_alloc(intel->bufmgr, "upload", size, 0);
+   intel->upload.offset = 0;
+}
+
+void intel_upload_data(struct intel_context *intel,
+                      const void *ptr, GLuint size, GLuint align,
+                      drm_intel_bo **return_bo,
+                      GLuint *return_offset)
+{
+   GLuint base, delta;
+
+   base = (intel->upload.offset + align - 1) / align * align;
+   if (intel->upload.bo == NULL || base + size > intel->upload.bo->size) {
+      wrap_buffers(intel, size);
+      base = 0;
+   }
+
+   drm_intel_bo_reference(intel->upload.bo);
+   *return_bo = intel->upload.bo;
+   *return_offset = base;
+
+   delta = base - intel->upload.offset;
+   if (intel->upload.buffer_len &&
+       intel->upload.buffer_len + delta + size > sizeof(intel->upload.buffer))
+   {
+      drm_intel_bo_subdata(intel->upload.bo,
+                          intel->upload.buffer_offset,
+                          intel->upload.buffer_len,
+                          intel->upload.buffer);
+      intel->upload.buffer_len = 0;
+   }
+
+   if (size < sizeof(intel->upload.buffer))
+   {
+      if (intel->upload.buffer_len == 0)
+        intel->upload.buffer_offset = base;
+      else
+        intel->upload.buffer_len += delta;
+
+      memcpy(intel->upload.buffer + intel->upload.buffer_len, ptr, size);
+      intel->upload.buffer_len += size;
+   }
+   else
+   {
+      drm_intel_bo_subdata(intel->upload.bo, base, size, ptr);
+   }
+
+   intel->upload.offset = base + size;
+}
+
+void *intel_upload_map(struct intel_context *intel, GLuint size, GLuint align)
+{
+   GLuint base, delta;
+   char *ptr;
+
+   base = (intel->upload.offset + align - 1) / align * align;
+   if (intel->upload.bo == NULL || base + size > intel->upload.bo->size) {
+      wrap_buffers(intel, size);
+      base = 0;
+   }
+
+   delta = base - intel->upload.offset;
+   if (intel->upload.buffer_len &&
+       intel->upload.buffer_len + delta + size > sizeof(intel->upload.buffer))
+   {
+      drm_intel_bo_subdata(intel->upload.bo,
+                          intel->upload.buffer_offset,
+                          intel->upload.buffer_len,
+                          intel->upload.buffer);
+      intel->upload.buffer_len = 0;
+   }
+
+   if (size <= sizeof(intel->upload.buffer)) {
+      if (intel->upload.buffer_len == 0)
+        intel->upload.buffer_offset = base;
+      else
+        intel->upload.buffer_len += delta;
+
+      ptr = intel->upload.buffer + intel->upload.buffer_len;
+      intel->upload.buffer_len += size;
+   } else
+      ptr = malloc(size);
+
+   return ptr;
+}
+
+void intel_upload_unmap(struct intel_context *intel,
+                       const void *ptr, GLuint size, GLuint align,
+                       drm_intel_bo **return_bo,
+                       GLuint *return_offset)
+{
+   GLuint base;
+
+   base = (intel->upload.offset + align - 1) / align * align;
+   if (size > sizeof(intel->upload.buffer)) {
+      drm_intel_bo_subdata(intel->upload.bo, base, size, ptr);
+      free((void*)ptr);
+   }
+
+   drm_intel_bo_reference(intel->upload.bo);
+   *return_bo = intel->upload.bo;
+   *return_offset = base;
+
+   intel->upload.offset = base + size;
+}
+
+drm_intel_bo *
+intel_bufferobj_source(struct intel_context *intel,
+                       struct intel_buffer_object *intel_obj,
+                      GLuint align, GLuint *offset)
+{
+   if (intel_obj->buffer == NULL) {
+      intel_upload_data(intel,
+                       intel_obj->sys_buffer, intel_obj->Base.Size, align,
+                       &intel_obj->buffer, &intel_obj->offset);
+      intel_obj->source = 1;
+   }
+
+   *offset = intel_obj->offset;
+   return intel_obj->buffer;
+}
+
+static void
+intel_bufferobj_copy_subdata(struct gl_context *ctx,
+                            struct gl_buffer_object *src,
+                            struct gl_buffer_object *dst,
+                            GLintptr read_offset, GLintptr write_offset,
+                            GLsizeiptr size)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_buffer_object *intel_src = intel_buffer_object(src);
+   struct intel_buffer_object *intel_dst = intel_buffer_object(dst);
+   drm_intel_bo *src_bo, *dst_bo;
+   GLuint src_offset;
+
+   if (size == 0)
+      return;
+
+   /* If we're in system memory, just map and memcpy. */
+   if (intel_src->sys_buffer || intel_dst->sys_buffer) {
+      /* The same buffer may be used, but note that regions copied may
+       * not overlap.
+       */
+      if (src == dst) {
+        char *ptr = intel_bufferobj_map_range(ctx, 0, dst->Size,
+                                              GL_MAP_READ_BIT |
+                                              GL_MAP_WRITE_BIT,
+                                              dst);
+        memmove(ptr + write_offset, ptr + read_offset, size);
+        intel_bufferobj_unmap(ctx, dst);
+      } else {
+        const char *src_ptr;
+        char *dst_ptr;
+
+        src_ptr =  intel_bufferobj_map_range(ctx, 0, src->Size,
+                                             GL_MAP_READ_BIT, src);
+        dst_ptr =  intel_bufferobj_map_range(ctx, 0, dst->Size,
+                                             GL_MAP_WRITE_BIT, dst);
+
+        memcpy(dst_ptr + write_offset, src_ptr + read_offset, size);
+
+        intel_bufferobj_unmap(ctx, src);
+        intel_bufferobj_unmap(ctx, dst);
+      }
+      return;
+   }
+
+   /* Otherwise, we have real BOs, so blit them. */
+
+   dst_bo = intel_bufferobj_buffer(intel, intel_dst, INTEL_WRITE_PART);
+   src_bo = intel_bufferobj_source(intel, intel_src, 64, &src_offset);
+
+   intel_emit_linear_blit(intel,
+                         dst_bo, write_offset,
+                         src_bo, read_offset + src_offset, size);
+
+   /* Since we've emitted some blits to buffers that will (likely) be used
+    * in rendering operations in other cache domains in this batch, emit a
+    * flush.  Once again, we wish for a domain tracker in libdrm to cover
+    * usage inside of a batchbuffer.
+    */
+   intel_batchbuffer_emit_mi_flush(intel);
+}
+
+static GLenum
+intel_buffer_purgeable(drm_intel_bo *buffer)
+{
+   int retained = 0;
+
+   if (buffer != NULL)
+      retained = drm_intel_bo_madvise (buffer, I915_MADV_DONTNEED);
+
+   return retained ? GL_VOLATILE_APPLE : GL_RELEASED_APPLE;
+}
+
+static GLenum
+intel_buffer_object_purgeable(struct gl_context * ctx,
+                              struct gl_buffer_object *obj,
+                              GLenum option)
+{
+   struct intel_buffer_object *intel_obj = intel_buffer_object (obj);
+
+   if (intel_obj->buffer != NULL)
+      return intel_buffer_purgeable(intel_obj->buffer);
+
+   if (option == GL_RELEASED_APPLE) {
+      free(intel_obj->sys_buffer);
+      intel_obj->sys_buffer = NULL;
+
+      return GL_RELEASED_APPLE;
+   } else {
+      /* XXX Create the buffer and madvise(MADV_DONTNEED)? */
+      struct intel_context *intel = intel_context(ctx);
+      drm_intel_bo *bo = intel_bufferobj_buffer(intel, intel_obj, INTEL_READ);
+
+      return intel_buffer_purgeable(bo);
+   }
+}
+
+static GLenum
+intel_texture_object_purgeable(struct gl_context * ctx,
+                               struct gl_texture_object *obj,
+                               GLenum option)
+{
+   struct intel_texture_object *intel;
+
+   (void) ctx;
+   (void) option;
+
+   intel = intel_texture_object(obj);
+   if (intel->mt == NULL || intel->mt->region == NULL)
+      return GL_RELEASED_APPLE;
+
+   return intel_buffer_purgeable(intel->mt->region->bo);
+}
+
+static GLenum
+intel_render_object_purgeable(struct gl_context * ctx,
+                              struct gl_renderbuffer *obj,
+                              GLenum option)
+{
+   struct intel_renderbuffer *intel;
+
+   (void) ctx;
+   (void) option;
+
+   intel = intel_renderbuffer(obj);
+   if (intel->mt == NULL)
+      return GL_RELEASED_APPLE;
+
+   return intel_buffer_purgeable(intel->mt->region->bo);
+}
+
+static GLenum
+intel_buffer_unpurgeable(drm_intel_bo *buffer)
+{
+   int retained;
+
+   retained = 0;
+   if (buffer != NULL)
+      retained = drm_intel_bo_madvise (buffer, I915_MADV_WILLNEED);
+
+   return retained ? GL_RETAINED_APPLE : GL_UNDEFINED_APPLE;
+}
+
+static GLenum
+intel_buffer_object_unpurgeable(struct gl_context * ctx,
+                                struct gl_buffer_object *obj,
+                                GLenum option)
+{
+   (void) ctx;
+   (void) option;
+
+   return intel_buffer_unpurgeable(intel_buffer_object (obj)->buffer);
+}
+
+static GLenum
+intel_texture_object_unpurgeable(struct gl_context * ctx,
+                                 struct gl_texture_object *obj,
+                                 GLenum option)
+{
+   struct intel_texture_object *intel;
+
+   (void) ctx;
+   (void) option;
+
+   intel = intel_texture_object(obj);
+   if (intel->mt == NULL || intel->mt->region == NULL)
+      return GL_UNDEFINED_APPLE;
+
+   return intel_buffer_unpurgeable(intel->mt->region->bo);
+}
+
+static GLenum
+intel_render_object_unpurgeable(struct gl_context * ctx,
+                                struct gl_renderbuffer *obj,
+                                GLenum option)
+{
+   struct intel_renderbuffer *intel;
+
+   (void) ctx;
+   (void) option;
+
+   intel = intel_renderbuffer(obj);
+   if (intel->mt == NULL)
+      return GL_UNDEFINED_APPLE;
+
+   return intel_buffer_unpurgeable(intel->mt->region->bo);
+}
+
+void
+intelInitBufferObjectFuncs(struct dd_function_table *functions)
+{
+   functions->NewBufferObject = intel_bufferobj_alloc;
+   functions->DeleteBuffer = intel_bufferobj_free;
+   functions->BufferData = intel_bufferobj_data;
+   functions->BufferSubData = intel_bufferobj_subdata;
+   functions->GetBufferSubData = intel_bufferobj_get_subdata;
+   functions->MapBufferRange = intel_bufferobj_map_range;
+   functions->FlushMappedBufferRange = intel_bufferobj_flush_mapped_range;
+   functions->UnmapBuffer = intel_bufferobj_unmap;
+   functions->CopyBufferSubData = intel_bufferobj_copy_subdata;
+
+   functions->BufferObjectPurgeable = intel_buffer_object_purgeable;
+   functions->TextureObjectPurgeable = intel_texture_object_purgeable;
+   functions->RenderObjectPurgeable = intel_render_object_purgeable;
+
+   functions->BufferObjectUnpurgeable = intel_buffer_object_unpurgeable;
+   functions->TextureObjectUnpurgeable = intel_texture_object_unpurgeable;
+   functions->RenderObjectUnpurgeable = intel_render_object_unpurgeable;
+}
deleted file mode 120000 (symlink)
index c86daa49f47cd6f633b2ac0da20838a6ac12f6dd..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_buffers.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..fdad480cb39ca392d4bb2ba4fe89c6c08777db8d
--- /dev/null
@@ -0,0 +1,118 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#include "intel_context.h"
+#include "intel_buffers.h"
+#include "intel_fbo.h"
+#include "intel_mipmap_tree.h"
+
+#include "main/fbobject.h"
+#include "main/framebuffer.h"
+#include "main/renderbuffer.h"
+
+/**
+ * Return pointer to current color reading region, or NULL.
+ */
+struct intel_region *
+intel_readbuf_region(struct intel_context *intel)
+{
+   struct intel_renderbuffer *irb
+      = intel_renderbuffer(intel->ctx.ReadBuffer->_ColorReadBuffer);
+   if (irb && irb->mt)
+      return irb->mt->region;
+   else
+      return NULL;
+}
+
+/**
+ * Check if we're about to draw into the front color buffer.
+ * If so, set the intel->front_buffer_dirty field to true.
+ */
+void
+intel_check_front_buffer_rendering(struct intel_context *intel)
+{
+   const struct gl_framebuffer *fb = intel->ctx.DrawBuffer;
+   if (_mesa_is_winsys_fbo(fb)) {
+      /* drawing to window system buffer */
+      if (fb->_NumColorDrawBuffers > 0) {
+         if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
+           intel->front_buffer_dirty = true;
+        }
+      }
+   }
+}
+
+static void
+intelDrawBuffer(struct gl_context * ctx, GLenum mode)
+{
+   if (ctx->DrawBuffer && _mesa_is_winsys_fbo(ctx->DrawBuffer)) {
+      struct intel_context *const intel = intel_context(ctx);
+      const bool was_front_buffer_rendering =
+       intel->is_front_buffer_rendering;
+
+      intel->is_front_buffer_rendering = (mode == GL_FRONT_LEFT)
+       || (mode == GL_FRONT) || (mode == GL_FRONT_AND_BACK);
+
+      /* If we weren't front-buffer rendering before but we are now,
+       * invalidate our DRI drawable so we'll ask for new buffers
+       * (including the fake front) before we start rendering again.
+       */
+      if (!was_front_buffer_rendering && intel->is_front_buffer_rendering)
+        dri2InvalidateDrawable(intel->driContext->driDrawablePriv);
+   }
+
+   intel_draw_buffer(ctx);
+}
+
+
+static void
+intelReadBuffer(struct gl_context * ctx, GLenum mode)
+{
+   if (ctx->DrawBuffer && _mesa_is_winsys_fbo(ctx->DrawBuffer)) {
+      struct intel_context *const intel = intel_context(ctx);
+      const bool was_front_buffer_reading =
+       intel->is_front_buffer_reading;
+
+      intel->is_front_buffer_reading = (mode == GL_FRONT_LEFT)
+       || (mode == GL_FRONT);
+
+      /* If we weren't front-buffer reading before but we are now,
+       * invalidate our DRI drawable so we'll ask for new buffers
+       * (including the fake front) before we start reading again.
+       */
+      if (!was_front_buffer_reading && intel->is_front_buffer_reading)
+        dri2InvalidateDrawable(intel->driContext->driReadablePriv);
+   }
+}
+
+
+void
+intelInitBufferFuncs(struct dd_function_table *functions)
+{
+   functions->DrawBuffer = intelDrawBuffer;
+   functions->ReadBuffer = intelReadBuffer;
+}
deleted file mode 120000 (symlink)
index 27a1cbb255e69228f67acb1a50cb0f51622074ca..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_context.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..23d8281b4ca92952d072b1f4aab31be48a2af1aa
--- /dev/null
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/extensions.h"
+#include "main/fbobject.h"
+#include "main/framebuffer.h"
+#include "main/imports.h"
+#include "main/points.h"
+#include "main/renderbuffer.h"
+
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/tnl.h"
+#include "drivers/common/driverfuncs.h"
+#include "drivers/common/meta.h"
+
+#include "intel_chipset.h"
+#include "intel_buffers.h"
+#include "intel_tex.h"
+#include "intel_batchbuffer.h"
+#include "intel_clear.h"
+#include "intel_extensions.h"
+#include "intel_pixel.h"
+#include "intel_regions.h"
+#include "intel_buffer_objects.h"
+#include "intel_fbo.h"
+#include "intel_bufmgr.h"
+#include "intel_screen.h"
+#include "intel_mipmap_tree.h"
+
+#include "utils.h"
+#include "../glsl/ralloc.h"
+
+#ifndef INTEL_DEBUG
+int INTEL_DEBUG = (0);
+#endif
+
+
+static const GLubyte *
+intelGetString(struct gl_context * ctx, GLenum name)
+{
+   const struct intel_context *const intel = intel_context(ctx);
+   const char *chipset;
+   static char buffer[128];
+
+   switch (name) {
+   case GL_VENDOR:
+      return (GLubyte *) "Intel Open Source Technology Center";
+      break;
+
+   case GL_RENDERER:
+      switch (intel->intelScreen->deviceID) {
+#undef CHIPSET
+#define CHIPSET(id, symbol, str) case id: chipset = str; break;
+#include "pci_ids/i915_pci_ids.h"
+#include "pci_ids/i965_pci_ids.h"
+      default:
+         chipset = "Unknown Intel Chipset";
+         break;
+      }
+
+      (void) driGetRendererString(buffer, chipset, 0);
+      return (GLubyte *) buffer;
+
+   default:
+      return NULL;
+   }
+}
+
+void
+intel_resolve_for_dri2_flush(struct intel_context *intel,
+                             __DRIdrawable *drawable)
+{
+   if (intel->gen < 6) {
+      /* MSAA and fast color clear are not supported, so don't waste time
+       * checking whether a resolve is needed.
+       */
+      return;
+   }
+
+   struct gl_framebuffer *fb = drawable->driverPrivate;
+   struct intel_renderbuffer *rb;
+
+   /* Usually, only the back buffer will need to be downsampled. However,
+    * the front buffer will also need it if the user has rendered into it.
+    */
+   static const gl_buffer_index buffers[2] = {
+         BUFFER_BACK_LEFT,
+         BUFFER_FRONT_LEFT,
+   };
+
+   for (int i = 0; i < 2; ++i) {
+      rb = intel_get_renderbuffer(fb, buffers[i]);
+      if (rb == NULL || rb->mt == NULL)
+         continue;
+      if (rb->mt->num_samples <= 1)
+         intel_miptree_resolve_color(intel, rb->mt);
+      else
+         intel_miptree_downsample(intel, rb->mt);
+   }
+}
+
+static void
+intel_flush_front(struct gl_context *ctx)
+{
+   struct intel_context *intel = intel_context(ctx);
+    __DRIcontext *driContext = intel->driContext;
+    __DRIdrawable *driDrawable = driContext->driDrawablePriv;
+    __DRIscreen *const screen = intel->intelScreen->driScrnPriv;
+
+    if (intel->front_buffer_dirty && _mesa_is_winsys_fbo(ctx->DrawBuffer)) {
+      if (screen->dri2.loader->flushFrontBuffer != NULL &&
+          driDrawable &&
+          driDrawable->loaderPrivate) {
+
+         /* Resolve before flushing FAKE_FRONT_LEFT to FRONT_LEFT.
+          *
+          * This potentially resolves both front and back buffer. It
+          * is unnecessary to resolve the back, but harms nothing except
+          * performance. And no one cares about front-buffer render
+          * performance.
+          */
+         intel_resolve_for_dri2_flush(intel, driDrawable);
+
+         screen->dri2.loader->flushFrontBuffer(driDrawable,
+                                               driDrawable->loaderPrivate);
+
+        /* We set the dirty bit in intel_prepare_render() if we're
+         * front buffer rendering once we get there.
+         */
+        intel->front_buffer_dirty = false;
+      }
+   }
+}
+
+static unsigned
+intel_bits_per_pixel(const struct intel_renderbuffer *rb)
+{
+   return _mesa_get_format_bytes(intel_rb_format(rb)) * 8;
+}
+
+static void
+intel_query_dri2_buffers(struct intel_context *intel,
+                        __DRIdrawable *drawable,
+                        __DRIbuffer **buffers,
+                        int *count);
+
+static void
+intel_process_dri2_buffer(struct intel_context *intel,
+                         __DRIdrawable *drawable,
+                         __DRIbuffer *buffer,
+                         struct intel_renderbuffer *rb,
+                         const char *buffer_name);
+
+void
+intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
+{
+   struct gl_framebuffer *fb = drawable->driverPrivate;
+   struct intel_renderbuffer *rb;
+   struct intel_context *intel = context->driverPrivate;
+   __DRIbuffer *buffers = NULL;
+   int i, count;
+   const char *region_name;
+
+   /* Set this up front, so that in case our buffers get invalidated
+    * while we're getting new buffers, we don't clobber the stamp and
+    * thus ignore the invalidate. */
+   drawable->lastStamp = drawable->dri2.stamp;
+
+   if (unlikely(INTEL_DEBUG & DEBUG_DRI))
+      fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
+
+   intel_query_dri2_buffers(intel, drawable, &buffers, &count);
+
+   if (buffers == NULL)
+      return;
+
+   for (i = 0; i < count; i++) {
+       switch (buffers[i].attachment) {
+       case __DRI_BUFFER_FRONT_LEFT:
+          rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
+          region_name = "dri2 front buffer";
+          break;
+
+       case __DRI_BUFFER_FAKE_FRONT_LEFT:
+          rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
+          region_name = "dri2 fake front buffer";
+          break;
+
+       case __DRI_BUFFER_BACK_LEFT:
+          rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
+          region_name = "dri2 back buffer";
+          break;
+
+       case __DRI_BUFFER_DEPTH:
+       case __DRI_BUFFER_HIZ:
+       case __DRI_BUFFER_DEPTH_STENCIL:
+       case __DRI_BUFFER_STENCIL:
+       case __DRI_BUFFER_ACCUM:
+       default:
+          fprintf(stderr,
+                  "unhandled buffer attach event, attachment type %d\n",
+                  buffers[i].attachment);
+          return;
+       }
+
+       intel_process_dri2_buffer(intel, drawable, &buffers[i], rb, region_name);
+   }
+
+   driUpdateFramebufferSize(&intel->ctx, drawable);
+}
+
+/**
+ * intel_prepare_render should be called anywhere that curent read/drawbuffer
+ * state is required.
+ */
+void
+intel_prepare_render(struct intel_context *intel)
+{
+   __DRIcontext *driContext = intel->driContext;
+   __DRIdrawable *drawable;
+
+   drawable = driContext->driDrawablePriv;
+   if (drawable && drawable->dri2.stamp != driContext->dri2.draw_stamp) {
+      if (drawable->lastStamp != drawable->dri2.stamp)
+        intel_update_renderbuffers(driContext, drawable);
+      intel_draw_buffer(&intel->ctx);
+      driContext->dri2.draw_stamp = drawable->dri2.stamp;
+   }
+
+   drawable = driContext->driReadablePriv;
+   if (drawable && drawable->dri2.stamp != driContext->dri2.read_stamp) {
+      if (drawable->lastStamp != drawable->dri2.stamp)
+        intel_update_renderbuffers(driContext, drawable);
+      driContext->dri2.read_stamp = drawable->dri2.stamp;
+   }
+
+   /* If we're currently rendering to the front buffer, the rendering
+    * that will happen next will probably dirty the front buffer.  So
+    * mark it as dirty here.
+    */
+   if (intel->is_front_buffer_rendering)
+      intel->front_buffer_dirty = true;
+
+   /* Wait for the swapbuffers before the one we just emitted, so we
+    * don't get too many swaps outstanding for apps that are GPU-heavy
+    * but not CPU-heavy.
+    *
+    * We're using intelDRI2Flush (called from the loader before
+    * swapbuffer) and glFlush (for front buffer rendering) as the
+    * indicator that a frame is done and then throttle when we get
+    * here as we prepare to render the next frame.  At this point for
+    * round trips for swap/copy and getting new buffers are done and
+    * we'll spend less time waiting on the GPU.
+    *
+    * Unfortunately, we don't have a handle to the batch containing
+    * the swap, and getting our hands on that doesn't seem worth it,
+    * so we just us the first batch we emitted after the last swap.
+    */
+   if (intel->need_throttle && intel->first_post_swapbuffers_batch) {
+      if (!intel->disable_throttling)
+         drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch);
+      drm_intel_bo_unreference(intel->first_post_swapbuffers_batch);
+      intel->first_post_swapbuffers_batch = NULL;
+      intel->need_throttle = false;
+   }
+}
+
+static void
+intel_viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+{
+    struct intel_context *intel = intel_context(ctx);
+    __DRIcontext *driContext = intel->driContext;
+
+    if (intel->saved_viewport)
+       intel->saved_viewport(ctx, x, y, w, h);
+
+    if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
+       dri2InvalidateDrawable(driContext->driDrawablePriv);
+       dri2InvalidateDrawable(driContext->driReadablePriv);
+    }
+}
+
+static const struct dri_debug_control debug_control[] = {
+   { "tex",   DEBUG_TEXTURE},
+   { "state", DEBUG_STATE},
+   { "ioctl", DEBUG_IOCTL},
+   { "blit",  DEBUG_BLIT},
+   { "mip",   DEBUG_MIPTREE},
+   { "fall",  DEBUG_PERF},
+   { "perf",  DEBUG_PERF},
+   { "bat",   DEBUG_BATCH},
+   { "pix",   DEBUG_PIXEL},
+   { "buf",   DEBUG_BUFMGR},
+   { "reg",   DEBUG_REGION},
+   { "fbo",   DEBUG_FBO},
+   { "fs",    DEBUG_WM },
+   { "gs",    DEBUG_GS},
+   { "sync",  DEBUG_SYNC},
+   { "prim",  DEBUG_PRIMS },
+   { "vert",  DEBUG_VERTS },
+   { "dri",   DEBUG_DRI },
+   { "sf",    DEBUG_SF },
+   { "stats", DEBUG_STATS },
+   { "wm",    DEBUG_WM },
+   { "urb",   DEBUG_URB },
+   { "vs",    DEBUG_VS },
+   { "clip",  DEBUG_CLIP },
+   { "aub",   DEBUG_AUB },
+   { "shader_time", DEBUG_SHADER_TIME },
+   { "no16",  DEBUG_NO16 },
+   { "blorp", DEBUG_BLORP },
+   { NULL,    0 }
+};
+
+
+static void
+intelInvalidateState(struct gl_context * ctx, GLuint new_state)
+{
+    struct intel_context *intel = intel_context(ctx);
+
+    if (ctx->swrast_context)
+       _swrast_InvalidateState(ctx, new_state);
+   _vbo_InvalidateState(ctx, new_state);
+
+   intel->NewGLState |= new_state;
+
+   if (intel->vtbl.invalidate_state)
+      intel->vtbl.invalidate_state( intel, new_state );
+}
+
+void
+intel_flush_rendering_to_batch(struct gl_context *ctx)
+{
+   struct intel_context *intel = intel_context(ctx);
+
+   if (intel->Fallback)
+      _swrast_flush(ctx);
+
+   if (intel->gen < 4)
+      INTEL_FIREVERTICES(intel);
+}
+
+void
+_intel_flush(struct gl_context *ctx, const char *file, int line)
+{
+   struct intel_context *intel = intel_context(ctx);
+
+   intel_flush_rendering_to_batch(ctx);
+
+   if (intel->batch.used)
+      _intel_batchbuffer_flush(intel, file, line);
+}
+
+static void
+intel_glFlush(struct gl_context *ctx)
+{
+   struct intel_context *intel = intel_context(ctx);
+
+   intel_flush(ctx);
+   intel_flush_front(ctx);
+   if (intel->is_front_buffer_rendering)
+      intel->need_throttle = true;
+}
+
+void
+intelFinish(struct gl_context * ctx)
+{
+   struct intel_context *intel = intel_context(ctx);
+
+   intel_flush(ctx);
+   intel_flush_front(ctx);
+
+   if (intel->batch.last_bo)
+      drm_intel_bo_wait_rendering(intel->batch.last_bo);
+}
+
+void
+intelInitDriverFunctions(struct dd_function_table *functions)
+{
+   _mesa_init_driver_functions(functions);
+
+   functions->Flush = intel_glFlush;
+   functions->Finish = intelFinish;
+   functions->GetString = intelGetString;
+   functions->UpdateState = intelInvalidateState;
+
+   intelInitTextureFuncs(functions);
+   intelInitTextureImageFuncs(functions);
+   intelInitTextureSubImageFuncs(functions);
+   intelInitTextureCopyImageFuncs(functions);
+   intelInitClearFuncs(functions);
+   intelInitBufferFuncs(functions);
+   intelInitPixelFuncs(functions);
+   intelInitBufferObjectFuncs(functions);
+   intel_init_syncobj_functions(functions);
+}
+
+static bool
+validate_context_version(struct intel_screen *screen,
+                         int mesa_api,
+                         unsigned major_version,
+                         unsigned minor_version,
+                         unsigned *dri_ctx_error)
+{
+   unsigned req_version = 10 * major_version + minor_version;
+   unsigned max_version = 0;
+
+   switch (mesa_api) {
+   case API_OPENGL_COMPAT:
+      max_version = screen->max_gl_compat_version;
+      break;
+   case API_OPENGL_CORE:
+      max_version = screen->max_gl_core_version;
+      break;
+   case API_OPENGLES:
+      max_version = screen->max_gl_es1_version;
+      break;
+   case API_OPENGLES2:
+      max_version = screen->max_gl_es2_version;
+      break;
+   default:
+      max_version = 0;
+      break;
+   }
+
+   if (max_version == 0) {
+      *dri_ctx_error = __DRI_CTX_ERROR_BAD_API;
+      return false;
+   } else if (req_version > max_version) {
+      *dri_ctx_error = __DRI_CTX_ERROR_BAD_VERSION;
+      return false;
+   }
+
+   return true;
+}
+
+bool
+intelInitContext(struct intel_context *intel,
+                 int api,
+                 unsigned major_version,
+                 unsigned minor_version,
+                 const struct gl_config * mesaVis,
+                 __DRIcontext * driContextPriv,
+                 void *sharedContextPrivate,
+                 struct dd_function_table *functions,
+                 unsigned *dri_ctx_error)
+{
+   struct gl_context *ctx = &intel->ctx;
+   struct gl_context *shareCtx = (struct gl_context *) sharedContextPrivate;
+   __DRIscreen *sPriv = driContextPriv->driScreenPriv;
+   struct intel_screen *intelScreen = sPriv->driverPrivate;
+   int bo_reuse_mode;
+   struct gl_config visual;
+
+   /* we can't do anything without a connection to the device */
+   if (intelScreen->bufmgr == NULL) {
+      *dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY;
+      return false;
+   }
+
+   if (!validate_context_version(intelScreen,
+                                 api, major_version, minor_version,
+                                 dri_ctx_error))
+      return false;
+
+   /* Can't rely on invalidate events, fall back to glViewport hack */
+   if (!driContextPriv->driScreenPriv->dri2.useInvalidate) {
+      intel->saved_viewport = functions->Viewport;
+      functions->Viewport = intel_viewport;
+   }
+
+   if (mesaVis == NULL) {
+      memset(&visual, 0, sizeof visual);
+      mesaVis = &visual;
+   }
+
+   intel->intelScreen = intelScreen;
+
+   if (!_mesa_initialize_context(&intel->ctx, api, mesaVis, shareCtx,
+                                 functions)) {
+      *dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY;
+      printf("%s: failed to init mesa context\n", __FUNCTION__);
+      return false;
+   }
+
+   driContextPriv->driverPrivate = intel;
+   intel->driContext = driContextPriv;
+   intel->driFd = sPriv->fd;
+
+   intel->gen = intelScreen->gen;
+
+   const int devID = intelScreen->deviceID;
+   if (IS_SNB_GT1(devID) || IS_IVB_GT1(devID) || IS_HSW_GT1(devID))
+      intel->gt = 1;
+   else if (IS_SNB_GT2(devID) || IS_IVB_GT2(devID) || IS_HSW_GT2(devID))
+      intel->gt = 2;
+   else if (IS_HSW_GT3(devID))
+      intel->gt = 3;
+   else
+      intel->gt = 0;
+
+   if (IS_HASWELL(devID)) {
+      intel->is_haswell = true;
+   } else if (IS_BAYTRAIL(devID)) {
+      intel->is_baytrail = true;
+      intel->gt = 1;
+   } else if (IS_G4X(devID)) {
+      intel->is_g4x = true;
+   } else if (IS_945(devID)) {
+      intel->is_945 = true;
+   }
+
+   if (intel->gen >= 5) {
+      intel->needs_ff_sync = true;
+   }
+
+   intel->has_separate_stencil = intel->intelScreen->hw_has_separate_stencil;
+   intel->must_use_separate_stencil = intel->intelScreen->hw_must_use_separate_stencil;
+   intel->has_hiz = intel->gen >= 6;
+   intel->has_llc = intel->intelScreen->hw_has_llc;
+   intel->has_swizzling = intel->intelScreen->hw_has_swizzling;
+
+   memset(&ctx->TextureFormatSupported,
+         0, sizeof(ctx->TextureFormatSupported));
+
+   driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache,
+                       sPriv->myNum, (intel->gen >= 4) ? "i965" : "i915");
+   if (intel->gen < 4)
+      intel->maxBatchSize = 4096;
+   else
+      intel->maxBatchSize = BATCH_SZ;
+
+   /* Estimate the size of the mappable aperture into the GTT.  There's an
+    * ioctl to get the whole GTT size, but not one to get the mappable subset.
+    * It turns out it's basically always 256MB, though some ancient hardware
+    * was smaller.
+    */
+   uint32_t gtt_size = 256 * 1024 * 1024;
+   if (intel->gen == 2)
+      gtt_size = 128 * 1024 * 1024;
+
+   /* We don't want to map two objects such that a memcpy between them would
+    * just fault one mapping in and then the other over and over forever.  So
+    * we would need to divide the GTT size by 2.  Additionally, some GTT is
+    * taken up by things like the framebuffer and the ringbuffer and such, so
+    * be more conservative.
+    */
+   intel->max_gtt_map_object_size = gtt_size / 4;
+
+   intel->bufmgr = intelScreen->bufmgr;
+
+   bo_reuse_mode = driQueryOptioni(&intel->optionCache, "bo_reuse");
+   switch (bo_reuse_mode) {
+   case DRI_CONF_BO_REUSE_DISABLED:
+      break;
+   case DRI_CONF_BO_REUSE_ALL:
+      intel_bufmgr_gem_enable_reuse(intel->bufmgr);
+      break;
+   }
+
+   ctx->Const.MinLineWidth = 1.0;
+   ctx->Const.MinLineWidthAA = 1.0;
+   ctx->Const.MaxLineWidth = 5.0;
+   ctx->Const.MaxLineWidthAA = 5.0;
+   ctx->Const.LineWidthGranularity = 0.5;
+
+   ctx->Const.MinPointSize = 1.0;
+   ctx->Const.MinPointSizeAA = 1.0;
+   ctx->Const.MaxPointSize = 255.0;
+   ctx->Const.MaxPointSizeAA = 3.0;
+   ctx->Const.PointSizeGranularity = 1.0;
+
+   if (intel->gen >= 6)
+      ctx->Const.MaxClipPlanes = 8;
+
+   ctx->Const.StripTextureBorder = GL_TRUE;
+
+   /* reinitialize the context point state.
+    * It depend on constants in __struct gl_contextRec::Const
+    */
+   _mesa_init_point(ctx);
+
+   if (intel->gen >= 4) {
+      ctx->Const.MaxRenderbufferSize = 8192;
+   } else {
+      ctx->Const.MaxRenderbufferSize = 2048;
+   }
+
+   /* Initialize the software rasterizer and helper modules.
+    *
+    * As of GL 3.1 core, the gen4+ driver doesn't need the swrast context for
+    * software fallbacks (which we have to support on legacy GL to do weird
+    * glDrawPixels(), glBitmap(), and other functions).
+    */
+   if (intel->gen <= 3 || api != API_OPENGL_CORE) {
+      _swrast_CreateContext(ctx);
+   }
+
+   _vbo_CreateContext(ctx);
+   if (ctx->swrast_context) {
+      _tnl_CreateContext(ctx);
+      _swsetup_CreateContext(ctx);
+
+      /* Configure swrast to match hardware characteristics: */
+      _swrast_allow_pixel_fog(ctx, false);
+      _swrast_allow_vertex_fog(ctx, true);
+   }
+
+   _mesa_meta_init(ctx);
+
+   intel->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24;
+   intel->hw_stipple = 1;
+
+   intel->RenderIndex = ~0;
+
+   intelInitExtensions(ctx);
+
+   INTEL_DEBUG = driParseDebugString(getenv("INTEL_DEBUG"), debug_control);
+   if (INTEL_DEBUG & DEBUG_BUFMGR)
+      dri_bufmgr_set_debug(intel->bufmgr, true);
+   if ((INTEL_DEBUG & DEBUG_SHADER_TIME) && intel->gen < 7) {
+      fprintf(stderr,
+              "shader_time debugging requires gen7 (Ivybridge) or better.\n");
+      INTEL_DEBUG &= ~DEBUG_SHADER_TIME;
+   }
+   if (INTEL_DEBUG & DEBUG_PERF)
+      intel->perf_debug = true;
+
+   if (INTEL_DEBUG & DEBUG_AUB)
+      drm_intel_bufmgr_gem_set_aub_dump(intel->bufmgr, true);
+
+   intel_batchbuffer_init(intel);
+
+   intel_fbo_init(intel);
+
+   intel->use_early_z = driQueryOptionb(&intel->optionCache, "early_z");
+
+   if (!driQueryOptionb(&intel->optionCache, "hiz")) {
+       intel->has_hiz = false;
+       /* On gen6, you can only do separate stencil with HIZ. */
+       if (intel->gen == 6)
+         intel->has_separate_stencil = false;
+   }
+
+   intel->prim.primitive = ~0;
+
+   /* Force all software fallbacks */
+#ifdef I915
+   if (driQueryOptionb(&intel->optionCache, "no_rast")) {
+      fprintf(stderr, "disabling 3D rasterization\n");
+      intel->no_rast = 1;
+   }
+#endif
+
+   if (driQueryOptionb(&intel->optionCache, "always_flush_batch")) {
+      fprintf(stderr, "flushing batchbuffer before/after each draw call\n");
+      intel->always_flush_batch = 1;
+   }
+
+   if (driQueryOptionb(&intel->optionCache, "always_flush_cache")) {
+      fprintf(stderr, "flushing GPU caches before/after each draw call\n");
+      intel->always_flush_cache = 1;
+   }
+
+   if (driQueryOptionb(&intel->optionCache, "disable_throttling")) {
+      fprintf(stderr, "disabling flush throttling\n");
+      intel->disable_throttling = 1;
+   }
+
+   return true;
+}
+
+void
+intelDestroyContext(__DRIcontext * driContextPriv)
+{
+   struct intel_context *intel =
+      (struct intel_context *) driContextPriv->driverPrivate;
+   struct gl_context *ctx = &intel->ctx;
+
+   assert(intel);               /* should never be null */
+   if (intel) {
+      INTEL_FIREVERTICES(intel);
+
+      /* Dump a final BMP in case the application doesn't call SwapBuffers */
+      if (INTEL_DEBUG & DEBUG_AUB) {
+         intel_batchbuffer_flush(intel);
+        aub_dump_bmp(&intel->ctx);
+      }
+
+      _mesa_meta_free(&intel->ctx);
+
+      intel->vtbl.destroy(intel);
+
+      if (ctx->swrast_context) {
+         _swsetup_DestroyContext(&intel->ctx);
+         _tnl_DestroyContext(&intel->ctx);
+      }
+      _vbo_DestroyContext(&intel->ctx);
+
+      if (ctx->swrast_context)
+         _swrast_DestroyContext(&intel->ctx);
+      intel->Fallback = 0x0;      /* don't call _swrast_Flush later */
+
+      intel_batchbuffer_free(intel);
+
+      free(intel->prim.vb);
+      intel->prim.vb = NULL;
+      drm_intel_bo_unreference(intel->prim.vb_bo);
+      intel->prim.vb_bo = NULL;
+      drm_intel_bo_unreference(intel->first_post_swapbuffers_batch);
+      intel->first_post_swapbuffers_batch = NULL;
+
+      driDestroyOptionCache(&intel->optionCache);
+
+      /* free the Mesa context */
+      _mesa_free_context_data(&intel->ctx);
+
+      _math_matrix_dtr(&intel->ViewportMatrix);
+
+      ralloc_free(intel);
+      driContextPriv->driverPrivate = NULL;
+   }
+}
+
+GLboolean
+intelUnbindContext(__DRIcontext * driContextPriv)
+{
+   /* Unset current context and dispath table */
+   _mesa_make_current(NULL, NULL, NULL);
+
+   return true;
+}
+
+/**
+ * Fixes up the context for GLES23 with our default-to-sRGB-capable behavior
+ * on window system framebuffers.
+ *
+ * Desktop GL is fairly reasonable in its handling of sRGB: You can ask if
+ * your renderbuffer can do sRGB encode, and you can flip a switch that does
+ * sRGB encode if the renderbuffer can handle it.  You can ask specifically
+ * for a visual where you're guaranteed to be capable, but it turns out that
+ * everyone just makes all their ARGB8888 visuals capable and doesn't offer
+ * incapable ones, becuase there's no difference between the two in resources
+ * used.  Applications thus get built that accidentally rely on the default
+ * visual choice being sRGB, so we make ours sRGB capable.  Everything sounds
+ * great...
+ *
+ * But for GLES2/3, they decided that it was silly to not turn on sRGB encode
+ * for sRGB renderbuffers you made with the GL_EXT_texture_sRGB equivalent.
+ * So they removed the enable knob and made it "if the renderbuffer is sRGB
+ * capable, do sRGB encode".  Then, for your window system renderbuffers, you
+ * can ask for sRGB visuals and get sRGB encode, or not ask for sRGB visuals
+ * and get no sRGB encode (assuming that both kinds of visual are available).
+ * Thus our choice to support sRGB by default on our visuals for desktop would
+ * result in broken rendering of GLES apps that aren't expecting sRGB encode.
+ *
+ * Unfortunately, renderbuffer setup happens before a context is created.  So
+ * in intel_screen.c we always set up sRGB, and here, if you're a GLES2/3
+ * context (without an sRGB visual, though we don't have sRGB visuals exposed
+ * yet), we go turn that back off before anyone finds out.
+ */
+static void
+intel_gles3_srgb_workaround(struct intel_context *intel,
+                            struct gl_framebuffer *fb)
+{
+   struct gl_context *ctx = &intel->ctx;
+
+   if (_mesa_is_desktop_gl(ctx) || !fb->Visual.sRGBCapable)
+      return;
+
+   /* Some day when we support the sRGB capable bit on visuals available for
+    * GLES, we'll need to respect that and not disable things here.
+    */
+   fb->Visual.sRGBCapable = false;
+   for (int i = 0; i < BUFFER_COUNT; i++) {
+      if (fb->Attachment[i].Renderbuffer &&
+          fb->Attachment[i].Renderbuffer->Format == MESA_FORMAT_SARGB8) {
+         fb->Attachment[i].Renderbuffer->Format = MESA_FORMAT_ARGB8888;
+      }
+   }
+}
+
+GLboolean
+intelMakeCurrent(__DRIcontext * driContextPriv,
+                 __DRIdrawable * driDrawPriv,
+                 __DRIdrawable * driReadPriv)
+{
+   struct intel_context *intel;
+   GET_CURRENT_CONTEXT(curCtx);
+
+   if (driContextPriv)
+      intel = (struct intel_context *) driContextPriv->driverPrivate;
+   else
+      intel = NULL;
+
+   /* According to the glXMakeCurrent() man page: "Pending commands to
+    * the previous context, if any, are flushed before it is released."
+    * But only flush if we're actually changing contexts.
+    */
+   if (intel_context(curCtx) && intel_context(curCtx) != intel) {
+      _mesa_flush(curCtx);
+   }
+
+   if (driContextPriv) {
+      struct gl_context *ctx = &intel->ctx;
+      struct gl_framebuffer *fb, *readFb;
+      
+      if (driDrawPriv == NULL && driReadPriv == NULL) {
+        fb = _mesa_get_incomplete_framebuffer();
+        readFb = _mesa_get_incomplete_framebuffer();
+      } else {
+        fb = driDrawPriv->driverPrivate;
+        readFb = driReadPriv->driverPrivate;
+        driContextPriv->dri2.draw_stamp = driDrawPriv->dri2.stamp - 1;
+        driContextPriv->dri2.read_stamp = driReadPriv->dri2.stamp - 1;
+      }
+
+      intel_prepare_render(intel);
+      _mesa_make_current(ctx, fb, readFb);
+
+      intel_gles3_srgb_workaround(intel, ctx->WinSysDrawBuffer);
+      intel_gles3_srgb_workaround(intel, ctx->WinSysReadBuffer);
+
+      /* We do this in intel_prepare_render() too, but intel->ctx.DrawBuffer
+       * is NULL at that point.  We can't call _mesa_makecurrent()
+       * first, since we need the buffer size for the initial
+       * viewport.  So just call intel_draw_buffer() again here. */
+      intel_draw_buffer(ctx);
+   }
+   else {
+      _mesa_make_current(NULL, NULL, NULL);
+   }
+
+   return true;
+}
+
+/**
+ * \brief Query DRI2 to obtain a DRIdrawable's buffers.
+ *
+ * To determine which DRI buffers to request, examine the renderbuffers
+ * attached to the drawable's framebuffer. Then request the buffers with
+ * DRI2GetBuffers() or DRI2GetBuffersWithFormat().
+ *
+ * This is called from intel_update_renderbuffers().
+ *
+ * \param drawable      Drawable whose buffers are queried.
+ * \param buffers       [out] List of buffers returned by DRI2 query.
+ * \param buffer_count  [out] Number of buffers returned.
+ *
+ * \see intel_update_renderbuffers()
+ * \see DRI2GetBuffers()
+ * \see DRI2GetBuffersWithFormat()
+ */
+static void
+intel_query_dri2_buffers(struct intel_context *intel,
+                        __DRIdrawable *drawable,
+                        __DRIbuffer **buffers,
+                        int *buffer_count)
+{
+   __DRIscreen *screen = intel->intelScreen->driScrnPriv;
+   struct gl_framebuffer *fb = drawable->driverPrivate;
+   int i = 0;
+   unsigned attachments[8];
+
+   struct intel_renderbuffer *front_rb;
+   struct intel_renderbuffer *back_rb;
+
+   front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
+   back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
+
+   memset(attachments, 0, sizeof(attachments));
+   if ((intel->is_front_buffer_rendering ||
+       intel->is_front_buffer_reading ||
+       !back_rb) && front_rb) {
+      /* If a fake front buffer is in use, then querying for
+       * __DRI_BUFFER_FRONT_LEFT will cause the server to copy the image from
+       * the real front buffer to the fake front buffer.  So before doing the
+       * query, we need to make sure all the pending drawing has landed in the
+       * real front buffer.
+       */
+      intel_flush(&intel->ctx);
+      intel_flush_front(&intel->ctx);
+
+      attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
+      attachments[i++] = intel_bits_per_pixel(front_rb);
+   } else if (front_rb && intel->front_buffer_dirty) {
+      /* We have pending front buffer rendering, but we aren't querying for a
+       * front buffer.  If the front buffer we have is a fake front buffer,
+       * the X server is going to throw it away when it processes the query.
+       * So before doing the query, make sure all the pending drawing has
+       * landed in the real front buffer.
+       */
+      intel_flush(&intel->ctx);
+      intel_flush_front(&intel->ctx);
+   }
+
+   if (back_rb) {
+      attachments[i++] = __DRI_BUFFER_BACK_LEFT;
+      attachments[i++] = intel_bits_per_pixel(back_rb);
+   }
+
+   assert(i <= ARRAY_SIZE(attachments));
+
+   *buffers = screen->dri2.loader->getBuffersWithFormat(drawable,
+                                                       &drawable->w,
+                                                       &drawable->h,
+                                                       attachments, i / 2,
+                                                       buffer_count,
+                                                       drawable->loaderPrivate);
+}
+
+/**
+ * \brief Assign a DRI buffer's DRM region to a renderbuffer.
+ *
+ * This is called from intel_update_renderbuffers().
+ *
+ * \par Note:
+ *    DRI buffers whose attachment point is DRI2BufferStencil or
+ *    DRI2BufferDepthStencil are handled as special cases.
+ *
+ * \param buffer_name is a human readable name, such as "dri2 front buffer",
+ *        that is passed to intel_region_alloc_for_handle().
+ *
+ * \see intel_update_renderbuffers()
+ * \see intel_region_alloc_for_handle()
+ */
+static void
+intel_process_dri2_buffer(struct intel_context *intel,
+                         __DRIdrawable *drawable,
+                         __DRIbuffer *buffer,
+                         struct intel_renderbuffer *rb,
+                         const char *buffer_name)
+{
+   struct intel_region *region = NULL;
+
+   if (!rb)
+      return;
+
+   unsigned num_samples = rb->Base.Base.NumSamples;
+
+   /* We try to avoid closing and reopening the same BO name, because the first
+    * use of a mapping of the buffer involves a bunch of page faulting which is
+    * moderately expensive.
+    */
+   if (num_samples == 0) {
+       if (rb->mt &&
+           rb->mt->region &&
+           rb->mt->region->name == buffer->name)
+          return;
+   } else {
+       if (rb->mt &&
+           rb->mt->singlesample_mt &&
+           rb->mt->singlesample_mt->region &&
+           rb->mt->singlesample_mt->region->name == buffer->name)
+          return;
+   }
+
+   if (unlikely(INTEL_DEBUG & DEBUG_DRI)) {
+      fprintf(stderr,
+             "attaching buffer %d, at %d, cpp %d, pitch %d\n",
+             buffer->name, buffer->attachment,
+             buffer->cpp, buffer->pitch);
+   }
+
+   intel_miptree_release(&rb->mt);
+   region = intel_region_alloc_for_handle(intel->intelScreen,
+                                          buffer->cpp,
+                                          drawable->w,
+                                          drawable->h,
+                                          buffer->pitch,
+                                          buffer->name,
+                                          buffer_name);
+   if (!region)
+      return;
+
+   rb->mt = intel_miptree_create_for_dri2_buffer(intel,
+                                                 buffer->attachment,
+                                                 intel_rb_format(rb),
+                                                 num_samples,
+                                                 region);
+   intel_region_release(&region);
+}
deleted file mode 120000 (symlink)
index a2f3e8cd2084f79232c3fc5ebea65f320add0bd0..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_extensions.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..5cb2fa38f33765bb5fba9639df32d0b2366efc59
--- /dev/null
@@ -0,0 +1,188 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#include "main/version.h"
+
+#include "intel_chipset.h"
+#include "intel_context.h"
+#include "intel_extensions.h"
+#include "intel_reg.h"
+#include "utils.h"
+
+/**
+ * Initializes potential list of extensions if ctx == NULL, or actually enables
+ * extensions for a context.
+ */
+void
+intelInitExtensions(struct gl_context *ctx)
+{
+   struct intel_context *intel = intel_context(ctx);
+
+   ctx->Extensions.ARB_draw_elements_base_vertex = true;
+   ctx->Extensions.ARB_explicit_attrib_location = true;
+   ctx->Extensions.ARB_framebuffer_object = true;
+   ctx->Extensions.ARB_half_float_pixel = true;
+   ctx->Extensions.ARB_internalformat_query = true;
+   ctx->Extensions.ARB_map_buffer_range = true;
+   ctx->Extensions.ARB_point_sprite = true;
+   ctx->Extensions.ARB_shader_objects = true;
+   ctx->Extensions.ARB_shading_language_100 = true;
+   ctx->Extensions.ARB_sync = true;
+   ctx->Extensions.ARB_texture_border_clamp = true;
+   ctx->Extensions.ARB_texture_cube_map = true;
+   ctx->Extensions.ARB_texture_env_combine = true;
+   ctx->Extensions.ARB_texture_env_crossbar = true;
+   ctx->Extensions.ARB_texture_env_dot3 = true;
+   ctx->Extensions.ARB_texture_storage = true;
+   ctx->Extensions.ARB_vertex_program = true;
+   ctx->Extensions.ARB_vertex_shader = true;
+   ctx->Extensions.EXT_blend_color = true;
+   ctx->Extensions.EXT_blend_equation_separate = true;
+   ctx->Extensions.EXT_blend_func_separate = true;
+   ctx->Extensions.EXT_blend_minmax = true;
+   ctx->Extensions.EXT_framebuffer_blit = true;
+   ctx->Extensions.EXT_framebuffer_object = true;
+   ctx->Extensions.EXT_fog_coord = true;
+   ctx->Extensions.EXT_gpu_program_parameters = true;
+   ctx->Extensions.EXT_packed_depth_stencil = true;
+   ctx->Extensions.EXT_pixel_buffer_object = true;
+   ctx->Extensions.EXT_point_parameters = true;
+   ctx->Extensions.EXT_provoking_vertex = true;
+   ctx->Extensions.EXT_secondary_color = true;
+   ctx->Extensions.EXT_separate_shader_objects = true;
+   ctx->Extensions.EXT_texture_env_dot3 = true;
+   ctx->Extensions.EXT_texture_filter_anisotropic = true;
+   ctx->Extensions.APPLE_object_purgeable = true;
+   ctx->Extensions.MESA_pack_invert = true;
+   ctx->Extensions.MESA_ycbcr_texture = true;
+   ctx->Extensions.NV_blend_square = true;
+   ctx->Extensions.NV_texture_rectangle = true;
+   ctx->Extensions.TDFX_texture_compression_FXT1 = true;
+   ctx->Extensions.OES_EGL_image = true;
+   ctx->Extensions.OES_draw_texture = true;
+
+   if (intel->gen >= 6)
+      ctx->Const.GLSLVersion = 140;
+   else
+      ctx->Const.GLSLVersion = 120;
+   _mesa_override_glsl_version(ctx);
+
+   if (intel->gen >= 6) {
+      ctx->Extensions.EXT_framebuffer_multisample = true;
+      ctx->Extensions.EXT_transform_feedback = true;
+      ctx->Extensions.ARB_blend_func_extended = !driQueryOptionb(&intel->optionCache, "disable_blend_func_extended");
+      ctx->Extensions.ARB_draw_buffers_blend = true;
+      ctx->Extensions.ARB_ES3_compatibility = true;
+      ctx->Extensions.ARB_uniform_buffer_object = true;
+      ctx->Extensions.ARB_texture_buffer_object = true;
+      ctx->Extensions.ARB_texture_buffer_object_rgb32 = true;
+      ctx->Extensions.ARB_texture_cube_map_array = true;
+      ctx->Extensions.OES_depth_texture_cube_map = true;
+      ctx->Extensions.ARB_shading_language_packing = true;
+      ctx->Extensions.ARB_texture_multisample = true;
+      ctx->Extensions.ARB_texture_storage_multisample = true;
+   }
+
+   if (intel->gen >= 5) {
+      ctx->Extensions.ARB_texture_query_lod = true;
+      ctx->Extensions.EXT_timer_query = true;
+   }
+
+   if (intel->gen >= 6) {
+      uint64_t dummy;
+      /* Test if the kernel has the ioctl. */
+      if (drm_intel_reg_read(intel->bufmgr, TIMESTAMP, &dummy) == 0)
+         ctx->Extensions.ARB_timer_query = true;
+   }
+
+   if (intel->gen >= 4) {
+      if (ctx->API == API_OPENGL_CORE)
+         ctx->Extensions.ARB_base_instance = true;
+      if (ctx->API != API_OPENGL_CORE)
+         ctx->Extensions.ARB_color_buffer_float = true;
+      ctx->Extensions.ARB_depth_buffer_float = true;
+      ctx->Extensions.ARB_depth_clamp = true;
+      ctx->Extensions.ARB_draw_instanced = true;
+      ctx->Extensions.ARB_instanced_arrays = true;
+      ctx->Extensions.ARB_fragment_coord_conventions = true;
+      ctx->Extensions.ARB_fragment_program_shadow = true;
+      ctx->Extensions.ARB_fragment_shader = true;
+      ctx->Extensions.ARB_half_float_vertex = true;
+      ctx->Extensions.ARB_occlusion_query = true;
+      ctx->Extensions.ARB_occlusion_query2 = true;
+      ctx->Extensions.ARB_point_sprite = true;
+      ctx->Extensions.ARB_seamless_cube_map = true;
+      ctx->Extensions.ARB_shader_bit_encoding = true;
+      ctx->Extensions.ARB_shader_texture_lod = true;
+      ctx->Extensions.ARB_texture_float = true;
+      ctx->Extensions.EXT_texture_shared_exponent = true;
+      ctx->Extensions.EXT_packed_float = true;
+      ctx->Extensions.ARB_texture_compression_rgtc = true;
+      ctx->Extensions.ARB_texture_rg = true;
+      ctx->Extensions.ARB_texture_rgb10_a2ui = true;
+      ctx->Extensions.ARB_vertex_type_2_10_10_10_rev = true;
+      ctx->Extensions.EXT_draw_buffers2 = true;
+      ctx->Extensions.EXT_framebuffer_sRGB = true;
+      ctx->Extensions.EXT_texture_array = true;
+      ctx->Extensions.EXT_texture_integer = true;
+      ctx->Extensions.EXT_texture_snorm = true;
+      ctx->Extensions.EXT_texture_swizzle = true;
+      ctx->Extensions.EXT_vertex_array_bgra = true;
+      ctx->Extensions.ATI_envmap_bumpmap = true;
+      ctx->Extensions.MESA_texture_array = true;
+      ctx->Extensions.NV_conditional_render = true;
+      ctx->Extensions.OES_compressed_ETC1_RGB8_texture = true;
+      ctx->Extensions.OES_standard_derivatives = true;
+   }
+
+   if (intel->gen >= 3) {
+      ctx->Extensions.ARB_ES2_compatibility = true;
+      ctx->Extensions.ARB_depth_texture = true;
+      ctx->Extensions.ARB_fragment_program = true;
+      ctx->Extensions.ARB_shadow = true;
+      ctx->Extensions.ARB_texture_non_power_of_two = true;
+      ctx->Extensions.EXT_texture_sRGB = true;
+      ctx->Extensions.EXT_texture_sRGB_decode = true;
+      ctx->Extensions.EXT_shadow_funcs = true;
+      ctx->Extensions.EXT_stencil_two_side = true;
+      ctx->Extensions.ATI_separate_stencil = true;
+      ctx->Extensions.ATI_texture_env_combine3 = true;
+      ctx->Extensions.NV_texture_env_combine4 = true;
+      ctx->Extensions.ARB_fragment_shader = true;
+      ctx->Extensions.ARB_occlusion_query = true;
+   }
+
+   if (intel->ctx.Mesa_DXTn
+       || driQueryOptionb(&intel->optionCache, "force_s3tc_enable"))
+      ctx->Extensions.EXT_texture_compression_s3tc = true;
+
+   ctx->Extensions.ANGLE_texture_compression_dxt = true;
+
+   if (intel->gen >= 4) {
+      ctx->Extensions.NV_primitive_restart = true;
+   }
+}
deleted file mode 120000 (symlink)
index a19f86dcc576950a6390c17dce540cb4a9f44e5e..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_fbo.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..d16523bbbf6ae121196342803203706c930eabe0
--- /dev/null
@@ -0,0 +1,949 @@
+/**************************************************************************
+ * 
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+
+#include "main/enums.h"
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/mtypes.h"
+#include "main/fbobject.h"
+#include "main/framebuffer.h"
+#include "main/renderbuffer.h"
+#include "main/context.h"
+#include "main/teximage.h"
+#include "main/image.h"
+
+#include "swrast/swrast.h"
+#include "drivers/common/meta.h"
+
+#include "intel_context.h"
+#include "intel_batchbuffer.h"
+#include "intel_buffers.h"
+#include "intel_blit.h"
+#include "intel_fbo.h"
+#include "intel_mipmap_tree.h"
+#include "intel_regions.h"
+#include "intel_tex.h"
+#ifndef I915
+#include "brw_context.h"
+#endif
+
+#define FILE_DEBUG_FLAG DEBUG_FBO
+
+static struct gl_renderbuffer *
+intel_new_renderbuffer(struct gl_context * ctx, GLuint name);
+
+struct intel_region*
+intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex)
+{
+   struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, attIndex);
+   if (irb && irb->mt) {
+      if (attIndex == BUFFER_STENCIL && irb->mt->stencil_mt)
+        return irb->mt->stencil_mt->region;
+      else
+        return irb->mt->region;
+   } else
+      return NULL;
+}
+
+/**
+ * Create a new framebuffer object.
+ */
+static struct gl_framebuffer *
+intel_new_framebuffer(struct gl_context * ctx, GLuint name)
+{
+   /* Only drawable state in intel_framebuffer at this time, just use Mesa's
+    * class
+    */
+   return _mesa_new_framebuffer(ctx, name);
+}
+
+
+/** Called by gl_renderbuffer::Delete() */
+static void
+intel_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
+{
+   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+
+   ASSERT(irb);
+
+   intel_miptree_release(&irb->mt);
+
+   _mesa_delete_renderbuffer(ctx, rb);
+}
+
+/**
+ * \see dd_function_table::MapRenderbuffer
+ */
+static void
+intel_map_renderbuffer(struct gl_context *ctx,
+                      struct gl_renderbuffer *rb,
+                      GLuint x, GLuint y, GLuint w, GLuint h,
+                      GLbitfield mode,
+                      GLubyte **out_map,
+                      GLint *out_stride)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct swrast_renderbuffer *srb = (struct swrast_renderbuffer *)rb;
+   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+   void *map;
+   int stride;
+
+   if (srb->Buffer) {
+      /* this is a malloc'd renderbuffer (accum buffer), not an irb */
+      GLint bpp = _mesa_get_format_bytes(rb->Format);
+      GLint rowStride = srb->RowStride;
+      *out_map = (GLubyte *) srb->Buffer + y * rowStride + x * bpp;
+      *out_stride = rowStride;
+      return;
+   }
+
+   intel_prepare_render(intel);
+
+   /* For a window-system renderbuffer, we need to flip the mapping we receive
+    * upside-down.  So we need to ask for a rectangle on flipped vertically, and
+    * we then return a pointer to the bottom of it with a negative stride.
+    */
+   if (rb->Name == 0) {
+      y = rb->Height - y - h;
+   }
+
+   intel_miptree_map(intel, irb->mt, irb->mt_level, irb->mt_layer,
+                    x, y, w, h, mode, &map, &stride);
+
+   if (rb->Name == 0) {
+      map += (h - 1) * stride;
+      stride = -stride;
+   }
+
+   DBG("%s: rb %d (%s) mt mapped: (%d, %d) (%dx%d) -> %p/%d\n",
+       __FUNCTION__, rb->Name, _mesa_get_format_name(rb->Format),
+       x, y, w, h, map, stride);
+
+   *out_map = map;
+   *out_stride = stride;
+}
+
+/**
+ * \see dd_function_table::UnmapRenderbuffer
+ */
+static void
+intel_unmap_renderbuffer(struct gl_context *ctx,
+                        struct gl_renderbuffer *rb)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct swrast_renderbuffer *srb = (struct swrast_renderbuffer *)rb;
+   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+
+   DBG("%s: rb %d (%s)\n", __FUNCTION__,
+       rb->Name, _mesa_get_format_name(rb->Format));
+
+   if (srb->Buffer) {
+      /* this is a malloc'd renderbuffer (accum buffer) */
+      /* nothing to do */
+      return;
+   }
+
+   intel_miptree_unmap(intel, irb->mt, irb->mt_level, irb->mt_layer);
+}
+
+
+/**
+ * Round up the requested multisample count to the next supported sample size.
+ */
+unsigned
+intel_quantize_num_samples(struct intel_screen *intel, unsigned num_samples)
+{
+   switch (intel->gen) {
+   case 6:
+      /* Gen6 supports only 4x multisampling. */
+      if (num_samples > 0)
+         return 4;
+      else
+         return 0;
+   case 7:
+      /* Gen7 supports 4x and 8x multisampling. */
+      if (num_samples > 4)
+         return 8;
+      else if (num_samples > 0)
+         return 4;
+      else
+         return 0;
+      return 0;
+   default:
+      /* MSAA unsupported. */
+      return 0;
+   }
+}
+
+
+/**
+ * Called via glRenderbufferStorageEXT() to set the format and allocate
+ * storage for a user-created renderbuffer.
+ */
+static GLboolean
+intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
+                                 GLenum internalFormat,
+                                 GLuint width, GLuint height)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_screen *screen = intel->intelScreen;
+   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+   rb->NumSamples = intel_quantize_num_samples(screen, rb->NumSamples);
+
+   switch (internalFormat) {
+   default:
+      /* Use the same format-choice logic as for textures.
+       * Renderbuffers aren't any different from textures for us,
+       * except they're less useful because you can't texture with
+       * them.
+       */
+      rb->Format = intel->ctx.Driver.ChooseTextureFormat(ctx, GL_TEXTURE_2D,
+                                                        internalFormat,
+                                                        GL_NONE, GL_NONE);
+      break;
+   case GL_STENCIL_INDEX:
+   case GL_STENCIL_INDEX1_EXT:
+   case GL_STENCIL_INDEX4_EXT:
+   case GL_STENCIL_INDEX8_EXT:
+   case GL_STENCIL_INDEX16_EXT:
+      /* These aren't actual texture formats, so force them here. */
+      if (intel->has_separate_stencil) {
+        rb->Format = MESA_FORMAT_S8;
+      } else {
+        assert(!intel->must_use_separate_stencil);
+        rb->Format = MESA_FORMAT_S8_Z24;
+      }
+      break;
+   }
+
+   rb->Width = width;
+   rb->Height = height;
+   rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
+
+   intel_miptree_release(&irb->mt);
+
+   DBG("%s: %s: %s (%dx%d)\n", __FUNCTION__,
+       _mesa_lookup_enum_by_nr(internalFormat),
+       _mesa_get_format_name(rb->Format), width, height);
+
+   if (width == 0 || height == 0)
+      return true;
+
+   irb->mt = intel_miptree_create_for_renderbuffer(intel, rb->Format,
+                                                  width, height,
+                                                   rb->NumSamples);
+   if (!irb->mt)
+      return false;
+
+   return true;
+}
+
+
+static void
+intel_image_target_renderbuffer_storage(struct gl_context *ctx,
+                                       struct gl_renderbuffer *rb,
+                                       void *image_handle)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_renderbuffer *irb;
+   __DRIscreen *screen;
+   __DRIimage *image;
+
+   screen = intel->intelScreen->driScrnPriv;
+   image = screen->dri2.image->lookupEGLImage(screen, image_handle,
+                                             screen->loaderPrivate);
+   if (image == NULL)
+      return;
+
+   /* __DRIimage is opaque to the core so it has to be checked here */
+   switch (image->format) {
+   case MESA_FORMAT_RGBA8888_REV:
+      _mesa_error(&intel->ctx, GL_INVALID_OPERATION,
+            "glEGLImageTargetRenderbufferStorage(unsupported image format");
+      return;
+      break;
+   default:
+      break;
+   }
+
+   irb = intel_renderbuffer(rb);
+   intel_miptree_release(&irb->mt);
+   irb->mt = intel_miptree_create_for_bo(intel,
+                                         image->region->bo,
+                                         image->format,
+                                         image->offset,
+                                         image->region->width,
+                                         image->region->height,
+                                         image->region->pitch,
+                                         image->region->tiling);
+   if (!irb->mt)
+      return;
+
+   rb->InternalFormat = image->internal_format;
+   rb->Width = image->region->width;
+   rb->Height = image->region->height;
+   rb->Format = image->format;
+   rb->_BaseFormat = _mesa_base_fbo_format(&intel->ctx,
+                                          image->internal_format);
+   rb->NeedsFinishRenderTexture = true;
+}
+
+/**
+ * Called by _mesa_resize_framebuffer() for each hardware renderbuffer when a
+ * window system framebuffer is resized.
+ *
+ * Any actual buffer reallocations for hardware renderbuffers (which would
+ * have triggered _mesa_resize_framebuffer()) were done by
+ * intel_process_dri2_buffer().
+ */
+static GLboolean
+intel_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
+                           GLenum internalFormat, GLuint width, GLuint height)
+{
+   ASSERT(rb->Name == 0);
+   rb->Width = width;
+   rb->Height = height;
+   rb->InternalFormat = internalFormat;
+
+   return true;
+}
+
+/** Dummy function for gl_renderbuffer::AllocStorage() */
+static GLboolean
+intel_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
+                        GLenum internalFormat, GLuint width, GLuint height)
+{
+   _mesa_problem(ctx, "intel_op_alloc_storage should never be called.");
+   return false;
+}
+
+/**
+ * Create a new intel_renderbuffer which corresponds to an on-screen window,
+ * not a user-created renderbuffer.
+ *
+ * \param num_samples must be quantized.
+ */
+struct intel_renderbuffer *
+intel_create_renderbuffer(gl_format format, unsigned num_samples)
+{
+   struct intel_renderbuffer *irb;
+   struct gl_renderbuffer *rb;
+
+   GET_CURRENT_CONTEXT(ctx);
+
+   irb = CALLOC_STRUCT(intel_renderbuffer);
+   if (!irb) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
+      return NULL;
+   }
+
+   rb = &irb->Base.Base;
+
+   _mesa_init_renderbuffer(rb, 0);
+   rb->ClassID = INTEL_RB_CLASS;
+   rb->_BaseFormat = _mesa_get_format_base_format(format);
+   rb->Format = format;
+   rb->InternalFormat = rb->_BaseFormat;
+   rb->NumSamples = num_samples;
+
+   /* intel-specific methods */
+   rb->Delete = intel_delete_renderbuffer;
+   rb->AllocStorage = intel_alloc_window_storage;
+
+   return irb;
+}
+
+/**
+ * Private window-system buffers (as opposed to ones shared with the display
+ * server created with intel_create_renderbuffer()) are most similar in their
+ * handling to user-created renderbuffers, but they have a resize handler that
+ * may be called at intel_update_renderbuffers() time.
+ *
+ * \param num_samples must be quantized.
+ */
+struct intel_renderbuffer *
+intel_create_private_renderbuffer(gl_format format, unsigned num_samples)
+{
+   struct intel_renderbuffer *irb;
+
+   irb = intel_create_renderbuffer(format, num_samples);
+   irb->Base.Base.AllocStorage = intel_alloc_renderbuffer_storage;
+
+   return irb;
+}
+
+/**
+ * Create a new renderbuffer object.
+ * Typically called via glBindRenderbufferEXT().
+ */
+static struct gl_renderbuffer *
+intel_new_renderbuffer(struct gl_context * ctx, GLuint name)
+{
+   /*struct intel_context *intel = intel_context(ctx); */
+   struct intel_renderbuffer *irb;
+   struct gl_renderbuffer *rb;
+
+   irb = CALLOC_STRUCT(intel_renderbuffer);
+   if (!irb) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
+      return NULL;
+   }
+
+   rb = &irb->Base.Base;
+
+   _mesa_init_renderbuffer(rb, name);
+   rb->ClassID = INTEL_RB_CLASS;
+
+   /* intel-specific methods */
+   rb->Delete = intel_delete_renderbuffer;
+   rb->AllocStorage = intel_alloc_renderbuffer_storage;
+   /* span routines set in alloc_storage function */
+
+   return rb;
+}
+
+
+/**
+ * Called via glBindFramebufferEXT().
+ */
+static void
+intel_bind_framebuffer(struct gl_context * ctx, GLenum target,
+                       struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
+{
+   if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
+      intel_draw_buffer(ctx);
+   }
+   else {
+      /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
+   }
+}
+
+
+/**
+ * Called via glFramebufferRenderbufferEXT().
+ */
+static void
+intel_framebuffer_renderbuffer(struct gl_context * ctx,
+                               struct gl_framebuffer *fb,
+                               GLenum attachment, struct gl_renderbuffer *rb)
+{
+   DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0);
+
+   _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
+   intel_draw_buffer(ctx);
+}
+
+static bool
+intel_renderbuffer_update_wrapper(struct intel_context *intel,
+                                  struct intel_renderbuffer *irb,
+                                 struct gl_texture_image *image,
+                                  uint32_t layer)
+{
+   struct gl_renderbuffer *rb = &irb->Base.Base;
+   struct intel_texture_image *intel_image = intel_texture_image(image);
+   struct intel_mipmap_tree *mt = intel_image->mt;
+   int level = image->Level;
+
+   rb->Depth = image->Depth;
+
+   rb->AllocStorage = intel_nop_alloc_storage;
+
+   intel_miptree_check_level_layer(mt, level, layer);
+   irb->mt_level = level;
+
+   switch (mt->msaa_layout) {
+      case INTEL_MSAA_LAYOUT_UMS:
+      case INTEL_MSAA_LAYOUT_CMS:
+         irb->mt_layer = layer * mt->num_samples;
+         break;
+
+      default:
+         irb->mt_layer = layer;
+   }
+
+   intel_miptree_reference(&irb->mt, mt);
+
+   intel_renderbuffer_set_draw_offset(irb);
+
+   if (mt->hiz_mt == NULL &&
+       intel->vtbl.is_hiz_depth_format(intel, rb->Format)) {
+      intel_miptree_alloc_hiz(intel, mt);
+      if (!mt->hiz_mt)
+        return false;
+   }
+
+   return true;
+}
+
+void
+intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb)
+{
+   unsigned int dst_x, dst_y;
+
+   /* compute offset of the particular 2D image within the texture region */
+   intel_miptree_get_image_offset(irb->mt,
+                                 irb->mt_level,
+                                 irb->mt_layer,
+                                 &dst_x, &dst_y);
+
+   irb->draw_x = dst_x;
+   irb->draw_y = dst_y;
+}
+
+/**
+ * Called by glFramebufferTexture[123]DEXT() (and other places) to
+ * prepare for rendering into texture memory.  This might be called
+ * many times to choose different texture levels, cube faces, etc
+ * before intel_finish_render_texture() is ever called.
+ */
+static void
+intel_render_texture(struct gl_context * ctx,
+                     struct gl_framebuffer *fb,
+                     struct gl_renderbuffer_attachment *att)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct gl_renderbuffer *rb = att->Renderbuffer;
+   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+   struct gl_texture_image *image = rb->TexImage;
+   struct intel_texture_image *intel_image = intel_texture_image(image);
+   struct intel_mipmap_tree *mt = intel_image->mt;
+   int layer;
+
+   (void) fb;
+
+   if (att->CubeMapFace > 0) {
+      assert(att->Zoffset == 0);
+      layer = att->CubeMapFace;
+   } else {
+      layer = att->Zoffset;
+   }
+
+   if (!intel_image->mt) {
+      /* Fallback on drawing to a texture that doesn't have a miptree
+       * (has a border, width/height 0, etc.)
+       */
+      _swrast_render_texture(ctx, fb, att);
+      return;
+   }
+
+   intel_miptree_check_level_layer(mt, att->TextureLevel, layer);
+
+   if (!intel_renderbuffer_update_wrapper(intel, irb, image, layer)) {
+       _swrast_render_texture(ctx, fb, att);
+       return;
+   }
+
+   DBG("Begin render %s texture tex=%u w=%d h=%d d=%d refcount=%d\n",
+       _mesa_get_format_name(image->TexFormat),
+       att->Texture->Name, image->Width, image->Height, image->Depth,
+       rb->RefCount);
+
+   /* update drawing region, etc */
+   intel_draw_buffer(ctx);
+}
+
+
+/**
+ * Called by Mesa when rendering to a texture is done.
+ */
+static void
+intel_finish_render_texture(struct gl_context * ctx, struct gl_renderbuffer *rb)
+{
+   struct intel_context *intel = intel_context(ctx);
+
+   DBG("Finish render %s texture\n", _mesa_get_format_name(rb->Format));
+
+   /* Since we've (probably) rendered to the texture and will (likely) use
+    * it in the texture domain later on in this batchbuffer, flush the
+    * batch.  Once again, we wish for a domain tracker in libdrm to cover
+    * usage inside of a batchbuffer like GEM does in the kernel.
+    */
+   intel_batchbuffer_emit_mi_flush(intel);
+}
+
+#define fbo_incomplete(fb, ...) do {                                          \
+      static GLuint msg_id = 0;                                               \
+      if (unlikely(ctx->Const.ContextFlags & GL_CONTEXT_FLAG_DEBUG_BIT)) {    \
+         _mesa_gl_debug(ctx, &msg_id,                                         \
+                        MESA_DEBUG_TYPE_OTHER,                                \
+                        MESA_DEBUG_SEVERITY_MEDIUM,                           \
+                        __VA_ARGS__);                                         \
+      }                                                                       \
+      DBG(__VA_ARGS__);                                                       \
+      fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;                               \
+   } while (0)
+
+/**
+ * Do additional "completeness" testing of a framebuffer object.
+ */
+static void
+intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_renderbuffer *depthRb =
+      intel_get_renderbuffer(fb, BUFFER_DEPTH);
+   struct intel_renderbuffer *stencilRb =
+      intel_get_renderbuffer(fb, BUFFER_STENCIL);
+   struct intel_mipmap_tree *depth_mt = NULL, *stencil_mt = NULL;
+   int i;
+
+   DBG("%s() on fb %p (%s)\n", __FUNCTION__,
+       fb, (fb == ctx->DrawBuffer ? "drawbuffer" :
+           (fb == ctx->ReadBuffer ? "readbuffer" : "other buffer")));
+
+   if (depthRb)
+      depth_mt = depthRb->mt;
+   if (stencilRb) {
+      stencil_mt = stencilRb->mt;
+      if (stencil_mt->stencil_mt)
+        stencil_mt = stencil_mt->stencil_mt;
+   }
+
+   if (depth_mt && stencil_mt) {
+      if (depth_mt == stencil_mt) {
+        /* For true packed depth/stencil (not faked on prefers-separate-stencil
+         * hardware) we need to be sure they're the same level/layer, since
+         * we'll be emitting a single packet describing the packed setup.
+         */
+        if (depthRb->mt_level != stencilRb->mt_level ||
+            depthRb->mt_layer != stencilRb->mt_layer) {
+           fbo_incomplete(fb,
+                           "FBO incomplete: depth image level/layer %d/%d != "
+                           "stencil image %d/%d\n",
+                           depthRb->mt_level,
+                           depthRb->mt_layer,
+                           stencilRb->mt_level,
+                           stencilRb->mt_layer);
+        }
+      } else {
+        if (!intel->has_separate_stencil) {
+           fbo_incomplete(fb, "FBO incomplete: separate stencil "
+                           "unsupported\n");
+        }
+        if (stencil_mt->format != MESA_FORMAT_S8) {
+           fbo_incomplete(fb, "FBO incomplete: separate stencil is %s "
+                           "instead of S8\n",
+                           _mesa_get_format_name(stencil_mt->format));
+        }
+        if (intel->gen < 7 && !intel_renderbuffer_has_hiz(depthRb)) {
+           /* Before Gen7, separate depth and stencil buffers can be used
+            * only if HiZ is enabled. From the Sandybridge PRM, Volume 2,
+            * Part 1, Bit 3DSTATE_DEPTH_BUFFER.SeparateStencilBufferEnable:
+            *     [DevSNB]: This field must be set to the same value (enabled
+            *     or disabled) as Hierarchical Depth Buffer Enable.
+            */
+           fbo_incomplete(fb, "FBO incomplete: separate stencil "
+                           "without HiZ\n");
+        }
+      }
+   }
+
+   for (i = 0; i < Elements(fb->Attachment); i++) {
+      struct gl_renderbuffer *rb;
+      struct intel_renderbuffer *irb;
+
+      if (fb->Attachment[i].Type == GL_NONE)
+        continue;
+
+      /* A supported attachment will have a Renderbuffer set either
+       * from being a Renderbuffer or being a texture that got the
+       * intel_wrap_texture() treatment.
+       */
+      rb = fb->Attachment[i].Renderbuffer;
+      if (rb == NULL) {
+        fbo_incomplete(fb, "FBO incomplete: attachment without "
+                        "renderbuffer\n");
+        continue;
+      }
+
+      if (fb->Attachment[i].Type == GL_TEXTURE) {
+        if (rb->TexImage->Border) {
+           fbo_incomplete(fb, "FBO incomplete: texture with border\n");
+           continue;
+        }
+      }
+
+      irb = intel_renderbuffer(rb);
+      if (irb == NULL) {
+        fbo_incomplete(fb, "FBO incomplete: software rendering "
+                        "renderbuffer\n");
+        continue;
+      }
+
+      if (!intel->vtbl.render_target_supported(intel, rb)) {
+        fbo_incomplete(fb, "FBO incomplete: Unsupported HW "
+                        "texture/renderbuffer format attached: %s\n",
+                        _mesa_get_format_name(intel_rb_format(irb)));
+      }
+   }
+}
+
+/**
+ * Try to do a glBlitFramebuffer using glCopyTexSubImage2D
+ * We can do this when the dst renderbuffer is actually a texture and
+ * there is no scaling, mirroring or scissoring.
+ *
+ * \return new buffer mask indicating the buffers left to blit using the
+ *         normal path.
+ */
+static GLbitfield
+intel_blit_framebuffer_with_blitter(struct gl_context *ctx,
+                                    GLint srcX0, GLint srcY0,
+                                    GLint srcX1, GLint srcY1,
+                                    GLint dstX0, GLint dstY0,
+                                    GLint dstX1, GLint dstY1,
+                                    GLbitfield mask, GLenum filter)
+{
+   struct intel_context *intel = intel_context(ctx);
+
+   if (mask & GL_COLOR_BUFFER_BIT) {
+      GLint i;
+      const struct gl_framebuffer *drawFb = ctx->DrawBuffer;
+      const struct gl_framebuffer *readFb = ctx->ReadBuffer;
+      struct gl_renderbuffer *src_rb = readFb->_ColorReadBuffer;
+      struct intel_renderbuffer *src_irb = intel_renderbuffer(src_rb);
+
+      if (!src_irb) {
+         perf_debug("glBlitFramebuffer(): missing src renderbuffer.  "
+                    "Falling back to software rendering.\n");
+         return mask;
+      }
+
+      /* If the source and destination are the same size with no mirroring,
+       * the rectangles are within the size of the texture and there is no
+       * scissor, then we can probably use the blit engine.
+       */
+      if (!(srcX0 - srcX1 == dstX0 - dstX1 &&
+            srcY0 - srcY1 == dstY0 - dstY1 &&
+            srcX1 >= srcX0 &&
+            srcY1 >= srcY0 &&
+            srcX0 >= 0 && srcX1 <= readFb->Width &&
+            srcY0 >= 0 && srcY1 <= readFb->Height &&
+            dstX0 >= 0 && dstX1 <= drawFb->Width &&
+            dstY0 >= 0 && dstY1 <= drawFb->Height &&
+            !ctx->Scissor.Enabled)) {
+         perf_debug("glBlitFramebuffer(): non-1:1 blit.  "
+                    "Falling back to software rendering.\n");
+         return mask;
+      }
+
+      /* Blit to all active draw buffers.  We don't do any pre-checking,
+       * because we assume that copying to MRTs is rare, and failure midway
+       * through copying is even more rare.  Even if it was to occur, it's
+       * safe to let meta start the copy over from scratch, because
+       * glBlitFramebuffer completely overwrites the destination pixels, and
+       * results are undefined if any destination pixels have a dependency on
+       * source pixels.
+       */
+      for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
+         struct gl_renderbuffer *dst_rb = ctx->DrawBuffer->_ColorDrawBuffers[i];
+         struct intel_renderbuffer *dst_irb = intel_renderbuffer(dst_rb);
+
+         if (!dst_irb) {
+            perf_debug("glBlitFramebuffer(): missing dst renderbuffer.  "
+                       "Falling back to software rendering.\n");
+            return mask;
+         }
+
+         gl_format src_format = _mesa_get_srgb_format_linear(src_rb->Format);
+         gl_format dst_format = _mesa_get_srgb_format_linear(dst_rb->Format);
+         if (src_format != dst_format) {
+            perf_debug("glBlitFramebuffer(): unsupported blit from %s to %s.  "
+                       "Falling back to software rendering.\n",
+                       _mesa_get_format_name(src_format),
+                       _mesa_get_format_name(dst_format));
+            return mask;
+         }
+
+         if (!intel_miptree_blit(intel,
+                                 src_irb->mt,
+                                 src_irb->mt_level, src_irb->mt_layer,
+                                 srcX0, srcY0, src_rb->Name == 0,
+                                 dst_irb->mt,
+                                 dst_irb->mt_level, dst_irb->mt_layer,
+                                 dstX0, dstY0, dst_rb->Name == 0,
+                                 dstX1 - dstX0, dstY1 - dstY0, GL_COPY)) {
+            perf_debug("glBlitFramebuffer(): unknown blit failure.  "
+                       "Falling back to software rendering.\n");
+            return mask;
+         }
+      }
+
+      mask &= ~GL_COLOR_BUFFER_BIT;
+   }
+
+   return mask;
+}
+
+static void
+intel_blit_framebuffer(struct gl_context *ctx,
+                       GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+                       GLbitfield mask, GLenum filter)
+{
+#ifndef I915
+   mask = brw_blorp_framebuffer(intel_context(ctx),
+                                srcX0, srcY0, srcX1, srcY1,
+                                dstX0, dstY0, dstX1, dstY1,
+                                mask, filter);
+   if (mask == 0x0)
+      return;
+#endif
+
+   /* Try using the BLT engine. */
+   mask = intel_blit_framebuffer_with_blitter(ctx,
+                                              srcX0, srcY0, srcX1, srcY1,
+                                              dstX0, dstY0, dstX1, dstY1,
+                                              mask, filter);
+   if (mask == 0x0)
+      return;
+
+
+   _mesa_meta_BlitFramebuffer(ctx,
+                              srcX0, srcY0, srcX1, srcY1,
+                              dstX0, dstY0, dstX1, dstY1,
+                              mask, filter);
+}
+
+/**
+ * This is a no-op except on multisample buffers shared with DRI2.
+ */
+void
+intel_renderbuffer_set_needs_downsample(struct intel_renderbuffer *irb)
+{
+   if (irb->mt && irb->mt->singlesample_mt)
+      irb->mt->need_downsample = true;
+}
+
+/**
+ * Does the renderbuffer have hiz enabled?
+ */
+bool
+intel_renderbuffer_has_hiz(struct intel_renderbuffer *irb)
+{
+   return intel_miptree_slice_has_hiz(irb->mt, irb->mt_level, irb->mt_layer);
+}
+
+void
+intel_renderbuffer_set_needs_hiz_resolve(struct intel_renderbuffer *irb)
+{
+   if (irb->mt) {
+      intel_miptree_slice_set_needs_hiz_resolve(irb->mt,
+                                                irb->mt_level,
+                                                irb->mt_layer);
+   }
+}
+
+void
+intel_renderbuffer_set_needs_depth_resolve(struct intel_renderbuffer *irb)
+{
+   if (irb->mt) {
+      intel_miptree_slice_set_needs_depth_resolve(irb->mt,
+                                                  irb->mt_level,
+                                                  irb->mt_layer);
+   }
+}
+
+bool
+intel_renderbuffer_resolve_hiz(struct intel_context *intel,
+                              struct intel_renderbuffer *irb)
+{
+   if (irb->mt)
+      return intel_miptree_slice_resolve_hiz(intel,
+                                             irb->mt,
+                                             irb->mt_level,
+                                             irb->mt_layer);
+
+   return false;
+}
+
+bool
+intel_renderbuffer_resolve_depth(struct intel_context *intel,
+                                struct intel_renderbuffer *irb)
+{
+   if (irb->mt)
+      return intel_miptree_slice_resolve_depth(intel,
+                                               irb->mt,
+                                               irb->mt_level,
+                                               irb->mt_layer);
+
+   return false;
+}
+
+void
+intel_renderbuffer_move_to_temp(struct intel_context *intel,
+                                struct intel_renderbuffer *irb,
+                                bool invalidate)
+{
+   struct gl_renderbuffer *rb =&irb->Base.Base;
+   struct intel_texture_image *intel_image = intel_texture_image(rb->TexImage);
+   struct intel_mipmap_tree *new_mt;
+   int width, height, depth;
+
+   intel_miptree_get_dimensions_for_image(rb->TexImage, &width, &height, &depth);
+
+   new_mt = intel_miptree_create(intel, rb->TexImage->TexObject->Target,
+                                 intel_image->base.Base.TexFormat,
+                                 intel_image->base.Base.Level,
+                                 intel_image->base.Base.Level,
+                                 width, height, depth,
+                                 true,
+                                 irb->mt->num_samples,
+                                 INTEL_MIPTREE_TILING_ANY);
+
+   if (intel->vtbl.is_hiz_depth_format(intel, new_mt->format)) {
+      intel_miptree_alloc_hiz(intel, new_mt);
+   }
+
+   intel_miptree_copy_teximage(intel, intel_image, new_mt, invalidate);
+
+   intel_miptree_reference(&irb->mt, intel_image->mt);
+   intel_renderbuffer_set_draw_offset(irb);
+   intel_miptree_release(&new_mt);
+}
+
+/**
+ * Do one-time context initializations related to GL_EXT_framebuffer_object.
+ * Hook in device driver functions.
+ */
+void
+intel_fbo_init(struct intel_context *intel)
+{
+   intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer;
+   intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer;
+   intel->ctx.Driver.MapRenderbuffer = intel_map_renderbuffer;
+   intel->ctx.Driver.UnmapRenderbuffer = intel_unmap_renderbuffer;
+   intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer;
+   intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer;
+   intel->ctx.Driver.RenderTexture = intel_render_texture;
+   intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture;
+   intel->ctx.Driver.ValidateFramebuffer = intel_validate_framebuffer;
+   intel->ctx.Driver.BlitFramebuffer = intel_blit_framebuffer;
+   intel->ctx.Driver.EGLImageTargetRenderbufferStorage =
+      intel_image_target_renderbuffer_storage;
+}
deleted file mode 120000 (symlink)
index 242fed0b6aea3103f34d47677242be8804cf0b31..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_mipmap_tree.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..1776a4b34c578d27b236e05fe2b3ec2e70c0d39c
--- /dev/null
+/**************************************************************************
+ * 
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#include <GL/gl.h>
+#include <GL/internal/dri_interface.h>
+
+#include "intel_batchbuffer.h"
+#include "intel_chipset.h"
+#include "intel_context.h"
+#include "intel_mipmap_tree.h"
+#include "intel_regions.h"
+#include "intel_resolve_map.h"
+#include "intel_tex_layout.h"
+#include "intel_tex.h"
+#include "intel_blit.h"
+
+#ifndef I915
+#include "brw_blorp.h"
+#endif
+
+#include "main/enums.h"
+#include "main/formats.h"
+#include "main/glformats.h"
+#include "main/texcompress_etc.h"
+#include "main/teximage.h"
+
+#define FILE_DEBUG_FLAG DEBUG_MIPTREE
+
+static GLenum
+target_to_target(GLenum target)
+{
+   switch (target) {
+   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
+   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
+   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
+   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
+   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
+   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
+      return GL_TEXTURE_CUBE_MAP_ARB;
+   default:
+      return target;
+   }
+}
+
+
+/**
+ * Determine which MSAA layout should be used by the MSAA surface being
+ * created, based on the chip generation and the surface type.
+ */
+static enum intel_msaa_layout
+compute_msaa_layout(struct intel_context *intel, gl_format format, GLenum target)
+{
+   /* Prior to Gen7, all MSAA surfaces used IMS layout. */
+   if (intel->gen < 7)
+      return INTEL_MSAA_LAYOUT_IMS;
+
+   /* In Gen7, IMS layout is only used for depth and stencil buffers. */
+   switch (_mesa_get_format_base_format(format)) {
+   case GL_DEPTH_COMPONENT:
+   case GL_STENCIL_INDEX:
+   case GL_DEPTH_STENCIL:
+      return INTEL_MSAA_LAYOUT_IMS;
+   default:
+      /* From the Ivy Bridge PRM, Vol4 Part1 p77 ("MCS Enable"):
+       *
+       *   This field must be set to 0 for all SINT MSRTs when all RT channels
+       *   are not written
+       *
+       * In practice this means that we have to disable MCS for all signed
+       * integer MSAA buffers.  The alternative, to disable MCS only when one
+       * of the render target channels is disabled, is impractical because it
+       * would require converting between CMS and UMS MSAA layouts on the fly,
+       * which is expensive.
+       */
+      if (_mesa_get_format_datatype(format) == GL_INT) {
+         /* TODO: is this workaround needed for future chipsets? */
+         assert(intel->gen == 7);
+         return INTEL_MSAA_LAYOUT_UMS;
+      } else {
+         /* For now, if we're going to be texturing from this surface,
+          * force UMS, so that the shader doesn't have to do different things
+          * based on whether there's a multisample control surface needing sampled first.
+          * We can't just blindly read the MCS surface in all cases because:
+          *
+          * From the Ivy Bridge PRM, Vol4 Part1 p77 ("MCS Enable"):
+          *
+          *    If this field is disabled and the sampling engine <ld_mcs> message
+          *    is issued on this surface, the MCS surface may be accessed. Software
+          *    must ensure that the surface is defined to avoid GTT errors.
+          */
+         if (target == GL_TEXTURE_2D_MULTISAMPLE ||
+             target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
+            return INTEL_MSAA_LAYOUT_UMS;
+         } else {
+            return INTEL_MSAA_LAYOUT_CMS;
+         }
+      }
+   }
+}
+
+
+/**
+ * For single-sampled render targets ("non-MSRT"), the MCS buffer is a
+ * scaled-down bitfield representation of the color buffer which is capable of
+ * recording when blocks of the color buffer are equal to the clear value.
+ * This function returns the block size that will be used by the MCS buffer
+ * corresponding to a certain color miptree.
+ *
+ * From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render Target(s)",
+ * beneath the "Fast Color Clear" bullet (p327):
+ *
+ *     The following table describes the RT alignment
+ *
+ *                       Pixels  Lines
+ *         TiledY RT CL
+ *             bpp
+ *              32          8      4
+ *              64          4      4
+ *             128          2      4
+ *         TiledX RT CL
+ *             bpp
+ *              32         16      2
+ *              64          8      2
+ *             128          4      2
+ *
+ * This alignment has the following uses:
+ *
+ * - For figuring out the size of the MCS buffer.  Each 4k tile in the MCS
+ *   buffer contains 128 blocks horizontally and 256 blocks vertically.
+ *
+ * - For figuring out alignment restrictions for a fast clear operation.  Fast
+ *   clear operations must always clear aligned multiples of 16 blocks
+ *   horizontally and 32 blocks vertically.
+ *
+ * - For scaling down the coordinates sent through the render pipeline during
+ *   a fast clear.  X coordinates must be scaled down by 8 times the block
+ *   width, and Y coordinates by 16 times the block height.
+ *
+ * - For scaling down the coordinates sent through the render pipeline during
+ *   a "Render Target Resolve" operation.  X coordinates must be scaled down
+ *   by half the block width, and Y coordinates by half the block height.
+ */
+void
+intel_get_non_msrt_mcs_alignment(struct intel_context *intel,
+                                 struct intel_mipmap_tree *mt,
+                                 unsigned *width_px, unsigned *height)
+{
+   switch (mt->region->tiling) {
+   default:
+      assert(!"Non-MSRT MCS requires X or Y tiling");
+      /* In release builds, fall through */
+   case I915_TILING_Y:
+      *width_px = 32 / mt->cpp;
+      *height = 4;
+      break;
+   case I915_TILING_X:
+      *width_px = 64 / mt->cpp;
+      *height = 2;
+   }
+}
+
+
+/**
+ * For a single-sampled render target ("non-MSRT"), determine if an MCS buffer
+ * can be used.
+ *
+ * From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render Target(s)",
+ * beneath the "Fast Color Clear" bullet (p326):
+ *
+ *     - Support is limited to tiled render targets.
+ *     - Support is for non-mip-mapped and non-array surface types only.
+ *
+ * And then later, on p327:
+ *
+ *     - MCS buffer for non-MSRT is supported only for RT formats 32bpp,
+ *       64bpp, and 128bpp.
+ */
+bool
+intel_is_non_msrt_mcs_buffer_supported(struct intel_context *intel,
+                                       struct intel_mipmap_tree *mt)
+{
+#ifdef I915
+   /* MCS is not supported on the i915 (pre-Gen4) driver */
+   return false;
+#else
+   struct brw_context *brw = brw_context(&intel->ctx);
+
+   /* MCS support does not exist prior to Gen7 */
+   if (intel->gen < 7)
+      return false;
+
+   /* MCS is only supported for color buffers */
+   switch (_mesa_get_format_base_format(mt->format)) {
+   case GL_DEPTH_COMPONENT:
+   case GL_DEPTH_STENCIL:
+   case GL_STENCIL_INDEX:
+      return false;
+   }
+
+   if (mt->region->tiling != I915_TILING_X &&
+       mt->region->tiling != I915_TILING_Y)
+      return false;
+   if (mt->cpp != 4 && mt->cpp != 8 && mt->cpp != 16)
+      return false;
+   if (mt->first_level != 0 || mt->last_level != 0)
+      return false;
+   if (mt->physical_depth0 != 1)
+      return false;
+
+   /* There's no point in using an MCS buffer if the surface isn't in a
+    * renderable format.
+    */
+   if (!brw->format_supported_as_render_target[mt->format])
+      return false;
+
+   return true;
+#endif
+}
+
+
+/**
+ * @param for_bo Indicates that the caller is
+ *        intel_miptree_create_for_bo(). If true, then do not create
+ *        \c stencil_mt.
+ */
+struct intel_mipmap_tree *
+intel_miptree_create_layout(struct intel_context *intel,
+                            GLenum target,
+                            gl_format format,
+                            GLuint first_level,
+                            GLuint last_level,
+                            GLuint width0,
+                            GLuint height0,
+                            GLuint depth0,
+                            bool for_bo,
+                            GLuint num_samples)
+{
+   struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
+
+   DBG("%s target %s format %s level %d..%d <-- %p\n", __FUNCTION__,
+       _mesa_lookup_enum_by_nr(target),
+       _mesa_get_format_name(format),
+       first_level, last_level, mt);
+
+   mt->target = target_to_target(target);
+   mt->format = format;
+   mt->first_level = first_level;
+   mt->last_level = last_level;
+   mt->logical_width0 = width0;
+   mt->logical_height0 = height0;
+   mt->logical_depth0 = depth0;
+#ifndef I915
+   mt->mcs_state = INTEL_MCS_STATE_NONE;
+#endif
+
+   /* The cpp is bytes per (1, blockheight)-sized block for compressed
+    * textures.  This is why you'll see divides by blockheight all over
+    */
+   unsigned bw, bh;
+   _mesa_get_format_block_size(format, &bw, &bh);
+   assert(_mesa_get_format_bytes(mt->format) % bw == 0);
+   mt->cpp = _mesa_get_format_bytes(mt->format) / bw;
+
+   mt->num_samples = num_samples;
+   mt->compressed = _mesa_is_format_compressed(format);
+   mt->msaa_layout = INTEL_MSAA_LAYOUT_NONE;
+   mt->refcount = 1; 
+
+   if (num_samples > 1) {
+      /* Adjust width/height/depth for MSAA */
+      mt->msaa_layout = compute_msaa_layout(intel, format, mt->target);
+      if (mt->msaa_layout == INTEL_MSAA_LAYOUT_IMS) {
+         /* In the Sandy Bridge PRM, volume 4, part 1, page 31, it says:
+          *
+          *     "Any of the other messages (sample*, LOD, load4) used with a
+          *      (4x) multisampled surface will in-effect sample a surface with
+          *      double the height and width as that indicated in the surface
+          *      state. Each pixel position on the original-sized surface is
+          *      replaced with a 2x2 of samples with the following arrangement:
+          *
+          *         sample 0 sample 2
+          *         sample 1 sample 3"
+          *
+          * Thus, when sampling from a multisampled texture, it behaves as
+          * though the layout in memory for (x,y,sample) is:
+          *
+          *      (0,0,0) (0,0,2)   (1,0,0) (1,0,2)
+          *      (0,0,1) (0,0,3)   (1,0,1) (1,0,3)
+          *
+          *      (0,1,0) (0,1,2)   (1,1,0) (1,1,2)
+          *      (0,1,1) (0,1,3)   (1,1,1) (1,1,3)
+          *
+          * However, the actual layout of multisampled data in memory is:
+          *
+          *      (0,0,0) (1,0,0)   (0,0,1) (1,0,1)
+          *      (0,1,0) (1,1,0)   (0,1,1) (1,1,1)
+          *
+          *      (0,0,2) (1,0,2)   (0,0,3) (1,0,3)
+          *      (0,1,2) (1,1,2)   (0,1,3) (1,1,3)
+          *
+          * This pattern repeats for each 2x2 pixel block.
+          *
+          * As a result, when calculating the size of our 4-sample buffer for
+          * an odd width or height, we have to align before scaling up because
+          * sample 3 is in that bottom right 2x2 block.
+          */
+         switch (num_samples) {
+         case 4:
+            width0 = ALIGN(width0, 2) * 2;
+            height0 = ALIGN(height0, 2) * 2;
+            break;
+         case 8:
+            width0 = ALIGN(width0, 2) * 4;
+            height0 = ALIGN(height0, 2) * 2;
+            break;
+         default:
+            /* num_samples should already have been quantized to 0, 1, 4, or
+             * 8.
+             */
+            assert(false);
+         }
+      } else {
+         /* Non-interleaved */
+         depth0 *= num_samples;
+      }
+   }
+
+   /* array_spacing_lod0 is only used for non-IMS MSAA surfaces.  TODO: can we
+    * use it elsewhere?
+    */
+   switch (mt->msaa_layout) {
+   case INTEL_MSAA_LAYOUT_NONE:
+   case INTEL_MSAA_LAYOUT_IMS:
+      mt->array_spacing_lod0 = false;
+      break;
+   case INTEL_MSAA_LAYOUT_UMS:
+   case INTEL_MSAA_LAYOUT_CMS:
+      mt->array_spacing_lod0 = true;
+      break;
+   }
+
+   if (target == GL_TEXTURE_CUBE_MAP) {
+      assert(depth0 == 1);
+      depth0 = 6;
+   }
+
+   mt->physical_width0 = width0;
+   mt->physical_height0 = height0;
+   mt->physical_depth0 = depth0;
+
+   if (!for_bo &&
+       _mesa_get_format_base_format(format) == GL_DEPTH_STENCIL &&
+       (intel->must_use_separate_stencil ||
+       (intel->has_separate_stencil &&
+        intel->vtbl.is_hiz_depth_format(intel, format)))) {
+      mt->stencil_mt = intel_miptree_create(intel,
+                                            mt->target,
+                                            MESA_FORMAT_S8,
+                                            mt->first_level,
+                                            mt->last_level,
+                                            mt->logical_width0,
+                                            mt->logical_height0,
+                                            mt->logical_depth0,
+                                            true,
+                                            num_samples,
+                                            INTEL_MIPTREE_TILING_ANY);
+      if (!mt->stencil_mt) {
+        intel_miptree_release(&mt);
+        return NULL;
+      }
+
+      /* Fix up the Z miptree format for how we're splitting out separate
+       * stencil.  Gen7 expects there to be no stencil bits in its depth buffer.
+       */
+      if (mt->format == MESA_FORMAT_S8_Z24) {
+        mt->format = MESA_FORMAT_X8_Z24;
+      } else if (mt->format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+        mt->format = MESA_FORMAT_Z32_FLOAT;
+        mt->cpp = 4;
+      } else {
+        _mesa_problem(NULL, "Unknown format %s in separate stencil mt\n",
+                      _mesa_get_format_name(mt->format));
+      }
+   }
+
+   intel_get_texture_alignment_unit(intel, mt->format,
+                                   &mt->align_w, &mt->align_h);
+
+#ifdef I915
+   (void) intel;
+   if (intel->is_945)
+      i945_miptree_layout(mt);
+   else
+      i915_miptree_layout(mt);
+#else
+   brw_miptree_layout(intel, mt);
+#endif
+
+   return mt;
+}
+
+/**
+ * \brief Helper function for intel_miptree_create().
+ */
+static uint32_t
+intel_miptree_choose_tiling(struct intel_context *intel,
+                            gl_format format,
+                            uint32_t width0,
+                            uint32_t num_samples,
+                            enum intel_miptree_tiling_mode requested,
+                            struct intel_mipmap_tree *mt)
+{
+
+   if (format == MESA_FORMAT_S8) {
+      /* The stencil buffer is W tiled. However, we request from the kernel a
+       * non-tiled buffer because the GTT is incapable of W fencing.
+       */
+      return I915_TILING_NONE;
+   }
+
+   /* Some usages may want only one type of tiling, like depth miptrees (Y
+    * tiled), or temporary BOs for uploading data once (linear).
+    */
+   switch (requested) {
+   case INTEL_MIPTREE_TILING_ANY:
+      break;
+   case INTEL_MIPTREE_TILING_Y:
+      return I915_TILING_Y;
+   case INTEL_MIPTREE_TILING_NONE:
+      return I915_TILING_NONE;
+   }
+
+   if (num_samples > 1) {
+      /* From p82 of the Sandy Bridge PRM, dw3[1] of SURFACE_STATE ("Tiled
+       * Surface"):
+       *
+       *   [DevSNB+]: For multi-sample render targets, this field must be
+       *   1. MSRTs can only be tiled.
+       *
+       * Our usual reason for preferring X tiling (fast blits using the
+       * blitting engine) doesn't apply to MSAA, since we'll generally be
+       * downsampling or upsampling when blitting between the MSAA buffer
+       * and another buffer, and the blitting engine doesn't support that.
+       * So use Y tiling, since it makes better use of the cache.
+       */
+      return I915_TILING_Y;
+   }
+
+   GLenum base_format = _mesa_get_format_base_format(format);
+   if (intel->gen >= 4 &&
+       (base_format == GL_DEPTH_COMPONENT ||
+        base_format == GL_DEPTH_STENCIL_EXT))
+      return I915_TILING_Y;
+
+   int minimum_pitch = mt->total_width * mt->cpp;
+
+   /* If the width is much smaller than a tile, don't bother tiling. */
+   if (minimum_pitch < 64)
+      return I915_TILING_NONE;
+
+   if (ALIGN(minimum_pitch, 512) >= 32768) {
+      perf_debug("%dx%d miptree too large to blit, falling back to untiled",
+                 mt->total_width, mt->total_height);
+      return I915_TILING_NONE;
+   }
+
+   /* Pre-gen6 doesn't have BLORP to handle Y-tiling, so use X-tiling. */
+   if (intel->gen < 6)
+      return I915_TILING_X;
+
+   return I915_TILING_Y | I915_TILING_X;
+}
+
+struct intel_mipmap_tree *
+intel_miptree_create(struct intel_context *intel,
+                    GLenum target,
+                    gl_format format,
+                    GLuint first_level,
+                    GLuint last_level,
+                    GLuint width0,
+                    GLuint height0,
+                    GLuint depth0,
+                    bool expect_accelerated_upload,
+                     GLuint num_samples,
+                     enum intel_miptree_tiling_mode requested_tiling)
+{
+   struct intel_mipmap_tree *mt;
+   gl_format tex_format = format;
+   gl_format etc_format = MESA_FORMAT_NONE;
+   GLuint total_width, total_height;
+
+   if (!intel->is_baytrail) {
+      switch (format) {
+      case MESA_FORMAT_ETC1_RGB8:
+         format = MESA_FORMAT_RGBX8888_REV;
+         break;
+      case MESA_FORMAT_ETC2_RGB8:
+         format = MESA_FORMAT_RGBX8888_REV;
+         break;
+      case MESA_FORMAT_ETC2_SRGB8:
+      case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
+      case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
+         format = MESA_FORMAT_SARGB8;
+         break;
+      case MESA_FORMAT_ETC2_RGBA8_EAC:
+      case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
+         format = MESA_FORMAT_RGBA8888_REV;
+         break;
+      case MESA_FORMAT_ETC2_R11_EAC:
+         format = MESA_FORMAT_R16;
+         break;
+      case MESA_FORMAT_ETC2_SIGNED_R11_EAC:
+         format = MESA_FORMAT_SIGNED_R16;
+         break;
+      case MESA_FORMAT_ETC2_RG11_EAC:
+         format = MESA_FORMAT_GR1616;
+         break;
+      case MESA_FORMAT_ETC2_SIGNED_RG11_EAC:
+         format = MESA_FORMAT_SIGNED_GR1616;
+         break;
+      default:
+         /* Non ETC1 / ETC2 format */
+         break;
+      }
+   }
+
+   etc_format = (format != tex_format) ? tex_format : MESA_FORMAT_NONE;
+
+   mt = intel_miptree_create_layout(intel, target, format,
+                                     first_level, last_level, width0,
+                                     height0, depth0,
+                                     false, num_samples);
+   /*
+    * pitch == 0 || height == 0  indicates the null texture
+    */
+   if (!mt || !mt->total_width || !mt->total_height) {
+      intel_miptree_release(&mt);
+      return NULL;
+   }
+
+   total_width = mt->total_width;
+   total_height = mt->total_height;
+
+   if (format == MESA_FORMAT_S8) {
+      /* Align to size of W tile, 64x64. */
+      total_width = ALIGN(total_width, 64);
+      total_height = ALIGN(total_height, 64);
+   }
+
+   uint32_t tiling = intel_miptree_choose_tiling(intel, format, width0,
+                                                 num_samples, requested_tiling,
+                                                 mt);
+   bool y_or_x = tiling == (I915_TILING_Y | I915_TILING_X);
+
+   mt->etc_format = etc_format;
+   mt->region = intel_region_alloc(intel->intelScreen,
+                                  y_or_x ? I915_TILING_Y : tiling,
+                                  mt->cpp,
+                                  total_width,
+                                  total_height,
+                                  expect_accelerated_upload);
+
+   /* If the region is too large to fit in the aperture, we need to use the
+    * BLT engine to support it.  The BLT paths can't currently handle Y-tiling,
+    * so we need to fall back to X.
+    */
+   if (y_or_x && mt->region->bo->size >= intel->max_gtt_map_object_size) {
+      perf_debug("%dx%d miptree larger than aperture; falling back to X-tiled\n",
+                 mt->total_width, mt->total_height);
+      intel_region_release(&mt->region);
+
+      mt->region = intel_region_alloc(intel->intelScreen,
+                                      I915_TILING_X,
+                                      mt->cpp,
+                                      total_width,
+                                      total_height,
+                                      expect_accelerated_upload);
+   }
+
+   mt->offset = 0;
+
+   if (!mt->region) {
+       intel_miptree_release(&mt);
+       return NULL;
+   }
+
+#ifndef I915
+   /* If this miptree is capable of supporting fast color clears, set
+    * mcs_state appropriately to ensure that fast clears will occur.
+    * Allocation of the MCS miptree will be deferred until the first fast
+    * clear actually occurs.
+    */
+   if (intel_is_non_msrt_mcs_buffer_supported(intel, mt))
+      mt->mcs_state = INTEL_MCS_STATE_RESOLVED;
+#endif
+
+   return mt;
+}
+
+struct intel_mipmap_tree *
+intel_miptree_create_for_bo(struct intel_context *intel,
+                            drm_intel_bo *bo,
+                            gl_format format,
+                            uint32_t offset,
+                            uint32_t width,
+                            uint32_t height,
+                            int pitch,
+                            uint32_t tiling)
+{
+   struct intel_mipmap_tree *mt;
+
+   struct intel_region *region = calloc(1, sizeof(*region));
+   if (!region)
+      return NULL;
+
+   /* Nothing will be able to use this miptree with the BO if the offset isn't
+    * aligned.
+    */
+   if (tiling != I915_TILING_NONE)
+      assert(offset % 4096 == 0);
+
+   /* miptrees can't handle negative pitch.  If you need flipping of images,
+    * that's outside of the scope of the mt.
+    */
+   assert(pitch >= 0);
+
+   mt = intel_miptree_create_layout(intel, GL_TEXTURE_2D, format,
+                                    0, 0,
+                                    width, height, 1,
+                                    true, 0 /* num_samples */);
+   if (!mt)
+      return mt;
+
+   region->cpp = mt->cpp;
+   region->width = width;
+   region->height = height;
+   region->pitch = pitch;
+   region->refcount = 1;
+   drm_intel_bo_reference(bo);
+   region->bo = bo;
+   region->tiling = tiling;
+
+   mt->region = region;
+   mt->offset = offset;
+
+   return mt;
+}
+
+
+/**
+ * For a singlesample DRI2 buffer, this simply wraps the given region with a miptree.
+ *
+ * For a multisample DRI2 buffer, this wraps the given region with
+ * a singlesample miptree, then creates a multisample miptree into which the
+ * singlesample miptree is embedded as a child.
+ */
+struct intel_mipmap_tree*
+intel_miptree_create_for_dri2_buffer(struct intel_context *intel,
+                                     unsigned dri_attachment,
+                                     gl_format format,
+                                     uint32_t num_samples,
+                                     struct intel_region *region)
+{
+   struct intel_mipmap_tree *singlesample_mt = NULL;
+   struct intel_mipmap_tree *multisample_mt = NULL;
+
+   /* Only the front and back buffers, which are color buffers, are shared
+    * through DRI2.
+    */
+   assert(dri_attachment == __DRI_BUFFER_BACK_LEFT ||
+          dri_attachment == __DRI_BUFFER_FRONT_LEFT ||
+          dri_attachment == __DRI_BUFFER_FAKE_FRONT_LEFT);
+   assert(_mesa_get_format_base_format(format) == GL_RGB ||
+          _mesa_get_format_base_format(format) == GL_RGBA);
+
+   singlesample_mt = intel_miptree_create_for_bo(intel,
+                                                 region->bo,
+                                                 format,
+                                                 0,
+                                                 region->width,
+                                                 region->height,
+                                                 region->pitch,
+                                                 region->tiling);
+   if (!singlesample_mt)
+      return NULL;
+   singlesample_mt->region->name = region->name;
+
+#ifndef I915
+   /* If this miptree is capable of supporting fast color clears, set
+    * mcs_state appropriately to ensure that fast clears will occur.
+    * Allocation of the MCS miptree will be deferred until the first fast
+    * clear actually occurs.
+    */
+   if (intel_is_non_msrt_mcs_buffer_supported(intel, singlesample_mt))
+      singlesample_mt->mcs_state = INTEL_MCS_STATE_RESOLVED;
+#endif
+
+   if (num_samples == 0)
+      return singlesample_mt;
+
+   multisample_mt = intel_miptree_create_for_renderbuffer(intel,
+                                                          format,
+                                                          region->width,
+                                                          region->height,
+                                                          num_samples);
+   if (!multisample_mt) {
+      intel_miptree_release(&singlesample_mt);
+      return NULL;
+   }
+
+   multisample_mt->singlesample_mt = singlesample_mt;
+   multisample_mt->need_downsample = false;
+
+   if (intel->is_front_buffer_rendering &&
+       (dri_attachment == __DRI_BUFFER_FRONT_LEFT ||
+        dri_attachment == __DRI_BUFFER_FAKE_FRONT_LEFT)) {
+      intel_miptree_upsample(intel, multisample_mt);
+   }
+
+   return multisample_mt;
+}
+
+struct intel_mipmap_tree*
+intel_miptree_create_for_renderbuffer(struct intel_context *intel,
+                                      gl_format format,
+                                      uint32_t width,
+                                      uint32_t height,
+                                      uint32_t num_samples)
+{
+   struct intel_mipmap_tree *mt;
+   uint32_t depth = 1;
+   bool ok;
+
+   mt = intel_miptree_create(intel, GL_TEXTURE_2D, format, 0, 0,
+                            width, height, depth, true, num_samples,
+                             INTEL_MIPTREE_TILING_ANY);
+   if (!mt)
+      goto fail;
+
+   if (intel->vtbl.is_hiz_depth_format(intel, format)) {
+      ok = intel_miptree_alloc_hiz(intel, mt);
+      if (!ok)
+         goto fail;
+   }
+
+   if (mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) {
+      ok = intel_miptree_alloc_mcs(intel, mt, num_samples);
+      if (!ok)
+         goto fail;
+   }
+
+   return mt;
+
+fail:
+   intel_miptree_release(&mt);
+   return NULL;
+}
+
+void
+intel_miptree_reference(struct intel_mipmap_tree **dst,
+                        struct intel_mipmap_tree *src)
+{
+   if (*dst == src)
+      return;
+
+   intel_miptree_release(dst);
+
+   if (src) {
+      src->refcount++;
+      DBG("%s %p refcount now %d\n", __FUNCTION__, src, src->refcount);
+   }
+
+   *dst = src;
+}
+
+
+void
+intel_miptree_release(struct intel_mipmap_tree **mt)
+{
+   if (!*mt)
+      return;
+
+   DBG("%s %p refcount will be %d\n", __FUNCTION__, *mt, (*mt)->refcount - 1);
+   if (--(*mt)->refcount <= 0) {
+      GLuint i;
+
+      DBG("%s deleting %p\n", __FUNCTION__, *mt);
+
+      intel_region_release(&((*mt)->region));
+      intel_miptree_release(&(*mt)->stencil_mt);
+      intel_miptree_release(&(*mt)->hiz_mt);
+#ifndef I915
+      intel_miptree_release(&(*mt)->mcs_mt);
+#endif
+      intel_miptree_release(&(*mt)->singlesample_mt);
+      intel_resolve_map_clear(&(*mt)->hiz_map);
+
+      for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
+        free((*mt)->level[i].slice);
+      }
+
+      free(*mt);
+   }
+   *mt = NULL;
+}
+
+void
+intel_miptree_get_dimensions_for_image(struct gl_texture_image *image,
+                                       int *width, int *height, int *depth)
+{
+   switch (image->TexObject->Target) {
+   case GL_TEXTURE_1D_ARRAY:
+      *width = image->Width;
+      *height = 1;
+      *depth = image->Height;
+      break;
+   default:
+      *width = image->Width;
+      *height = image->Height;
+      *depth = image->Depth;
+      break;
+   }
+}
+
+/**
+ * Can the image be pulled into a unified mipmap tree?  This mirrors
+ * the completeness test in a lot of ways.
+ *
+ * Not sure whether I want to pass gl_texture_image here.
+ */
+bool
+intel_miptree_match_image(struct intel_mipmap_tree *mt,
+                          struct gl_texture_image *image)
+{
+   struct intel_texture_image *intelImage = intel_texture_image(image);
+   GLuint level = intelImage->base.Base.Level;
+   int width, height, depth;
+
+   /* glTexImage* choose the texture object based on the target passed in, and
+    * objects can't change targets over their lifetimes, so this should be
+    * true.
+    */
+   assert(target_to_target(image->TexObject->Target) == mt->target);
+
+   gl_format mt_format = mt->format;
+   if (mt->format == MESA_FORMAT_X8_Z24 && mt->stencil_mt)
+      mt_format = MESA_FORMAT_S8_Z24;
+   if (mt->format == MESA_FORMAT_Z32_FLOAT && mt->stencil_mt)
+      mt_format = MESA_FORMAT_Z32_FLOAT_X24S8;
+   if (mt->etc_format != MESA_FORMAT_NONE)
+      mt_format = mt->etc_format;
+
+   if (image->TexFormat != mt_format)
+      return false;
+
+   intel_miptree_get_dimensions_for_image(image, &width, &height, &depth);
+
+   if (mt->target == GL_TEXTURE_CUBE_MAP)
+      depth = 6;
+
+   /* Test image dimensions against the base level image adjusted for
+    * minification.  This will also catch images not present in the
+    * tree, changed targets, etc.
+    */
+   if (mt->target == GL_TEXTURE_2D_MULTISAMPLE ||
+         mt->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
+      /* nonzero level here is always bogus */
+      assert(level == 0);
+
+      if (width != mt->logical_width0 ||
+            height != mt->logical_height0 ||
+            depth != mt->logical_depth0) {
+         return false;
+      }
+   }
+   else {
+      /* all normal textures, renderbuffers, etc */
+      if (width != mt->level[level].width ||
+          height != mt->level[level].height ||
+          depth != mt->level[level].depth) {
+         return false;
+      }
+   }
+
+   if (image->NumSamples != mt->num_samples)
+      return false;
+
+   return true;
+}
+
+
+void
+intel_miptree_set_level_info(struct intel_mipmap_tree *mt,
+                            GLuint level,
+                            GLuint x, GLuint y,
+                            GLuint w, GLuint h, GLuint d)
+{
+   mt->level[level].width = w;
+   mt->level[level].height = h;
+   mt->level[level].depth = d;
+   mt->level[level].level_x = x;
+   mt->level[level].level_y = y;
+
+   DBG("%s level %d size: %d,%d,%d offset %d,%d\n", __FUNCTION__,
+       level, w, h, d, x, y);
+
+   assert(mt->level[level].slice == NULL);
+
+   mt->level[level].slice = calloc(d, sizeof(*mt->level[0].slice));
+   mt->level[level].slice[0].x_offset = mt->level[level].level_x;
+   mt->level[level].slice[0].y_offset = mt->level[level].level_y;
+}
+
+
+void
+intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
+                              GLuint level, GLuint img,
+                              GLuint x, GLuint y)
+{
+   if (img == 0 && level == 0)
+      assert(x == 0 && y == 0);
+
+   assert(img < mt->level[level].depth);
+
+   mt->level[level].slice[img].x_offset = mt->level[level].level_x + x;
+   mt->level[level].slice[img].y_offset = mt->level[level].level_y + y;
+
+   DBG("%s level %d img %d pos %d,%d\n",
+       __FUNCTION__, level, img,
+       mt->level[level].slice[img].x_offset,
+       mt->level[level].slice[img].y_offset);
+}
+
+void
+intel_miptree_get_image_offset(struct intel_mipmap_tree *mt,
+                              GLuint level, GLuint slice,
+                              GLuint *x, GLuint *y)
+{
+   assert(slice < mt->level[level].depth);
+
+   *x = mt->level[level].slice[slice].x_offset;
+   *y = mt->level[level].slice[slice].y_offset;
+}
+
+/**
+ * Rendering with tiled buffers requires that the base address of the buffer
+ * be aligned to a page boundary.  For renderbuffers, and sometimes with
+ * textures, we may want the surface to point at a texture image level that
+ * isn't at a page boundary.
+ *
+ * This function returns an appropriately-aligned base offset
+ * according to the tiling restrictions, plus any required x/y offset
+ * from there.
+ */
+uint32_t
+intel_miptree_get_tile_offsets(struct intel_mipmap_tree *mt,
+                               GLuint level, GLuint slice,
+                               uint32_t *tile_x,
+                               uint32_t *tile_y)
+{
+   struct intel_region *region = mt->region;
+   uint32_t x, y;
+   uint32_t mask_x, mask_y;
+
+   intel_region_get_tile_masks(region, &mask_x, &mask_y, false);
+   intel_miptree_get_image_offset(mt, level, slice, &x, &y);
+
+   *tile_x = x & mask_x;
+   *tile_y = y & mask_y;
+
+   return intel_region_get_aligned_offset(region, x & ~mask_x, y & ~mask_y,
+                                          false);
+}
+
+static void
+intel_miptree_copy_slice_sw(struct intel_context *intel,
+                            struct intel_mipmap_tree *dst_mt,
+                            struct intel_mipmap_tree *src_mt,
+                            int level,
+                            int slice,
+                            int width,
+                            int height)
+{
+   void *src, *dst;
+   int src_stride, dst_stride;
+   int cpp = dst_mt->cpp;
+
+   intel_miptree_map(intel, src_mt,
+                     level, slice,
+                     0, 0,
+                     width, height,
+                     GL_MAP_READ_BIT | BRW_MAP_DIRECT_BIT,
+                     &src, &src_stride);
+
+   intel_miptree_map(intel, dst_mt,
+                     level, slice,
+                     0, 0,
+                     width, height,
+                     GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT |
+                     BRW_MAP_DIRECT_BIT,
+                     &dst, &dst_stride);
+
+   DBG("sw blit %s mt %p %p/%d -> %s mt %p %p/%d (%dx%d)\n",
+       _mesa_get_format_name(src_mt->format),
+       src_mt, src, src_stride,
+       _mesa_get_format_name(dst_mt->format),
+       dst_mt, dst, dst_stride,
+       width, height);
+
+   int row_size = cpp * width;
+   if (src_stride == row_size &&
+       dst_stride == row_size) {
+      memcpy(dst, src, row_size * height);
+   } else {
+      for (int i = 0; i < height; i++) {
+         memcpy(dst, src, row_size);
+         dst += dst_stride;
+         src += src_stride;
+      }
+   }
+
+   intel_miptree_unmap(intel, dst_mt, level, slice);
+   intel_miptree_unmap(intel, src_mt, level, slice);
+
+   /* Don't forget to copy the stencil data over, too.  We could have skipped
+    * passing BRW_MAP_DIRECT_BIT, but that would have meant intel_miptree_map
+    * shuffling the two data sources in/out of temporary storage instead of
+    * the direct mapping we get this way.
+    */
+   if (dst_mt->stencil_mt) {
+      assert(src_mt->stencil_mt);
+      intel_miptree_copy_slice_sw(intel, dst_mt->stencil_mt, src_mt->stencil_mt,
+                                  level, slice, width, height);
+   }
+}
+
+static void
+intel_miptree_copy_slice(struct intel_context *intel,
+                        struct intel_mipmap_tree *dst_mt,
+                        struct intel_mipmap_tree *src_mt,
+                        int level,
+                        int face,
+                        int depth)
+
+{
+   gl_format format = src_mt->format;
+   uint32_t width = src_mt->level[level].width;
+   uint32_t height = src_mt->level[level].height;
+   int slice;
+
+   if (face > 0)
+      slice = face;
+   else
+      slice = depth;
+
+   assert(depth < src_mt->level[level].depth);
+   assert(src_mt->format == dst_mt->format);
+
+   if (dst_mt->compressed) {
+      height = ALIGN(height, dst_mt->align_h) / dst_mt->align_h;
+      width = ALIGN(width, dst_mt->align_w);
+   }
+
+   /* If it's a packed depth/stencil buffer with separate stencil, the blit
+    * below won't apply since we can't do the depth's Y tiling or the
+    * stencil's W tiling in the blitter.
+    */
+   if (src_mt->stencil_mt) {
+      intel_miptree_copy_slice_sw(intel,
+                                  dst_mt, src_mt,
+                                  level, slice,
+                                  width, height);
+      return;
+   }
+
+   uint32_t dst_x, dst_y, src_x, src_y;
+   intel_miptree_get_image_offset(dst_mt, level, slice, &dst_x, &dst_y);
+   intel_miptree_get_image_offset(src_mt, level, slice, &src_x, &src_y);
+
+   DBG("validate blit mt %s %p %d,%d/%d -> mt %s %p %d,%d/%d (%dx%d)\n",
+       _mesa_get_format_name(src_mt->format),
+       src_mt, src_x, src_y, src_mt->region->pitch,
+       _mesa_get_format_name(dst_mt->format),
+       dst_mt, dst_x, dst_y, dst_mt->region->pitch,
+       width, height);
+
+   if (!intel_miptree_blit(intel,
+                           src_mt, level, slice, 0, 0, false,
+                           dst_mt, level, slice, 0, 0, false,
+                           width, height, GL_COPY)) {
+      perf_debug("miptree validate blit for %s failed\n",
+                 _mesa_get_format_name(format));
+
+      intel_miptree_copy_slice_sw(intel, dst_mt, src_mt, level, slice,
+                                  width, height);
+   }
+}
+
+/**
+ * Copies the image's current data to the given miptree, and associates that
+ * miptree with the image.
+ *
+ * If \c invalidate is true, then the actual image data does not need to be
+ * copied, but the image still needs to be associated to the new miptree (this
+ * is set to true if we're about to clear the image).
+ */
+void
+intel_miptree_copy_teximage(struct intel_context *intel,
+                           struct intel_texture_image *intelImage,
+                           struct intel_mipmap_tree *dst_mt,
+                            bool invalidate)
+{
+   struct intel_mipmap_tree *src_mt = intelImage->mt;
+   struct intel_texture_object *intel_obj =
+      intel_texture_object(intelImage->base.Base.TexObject);
+   int level = intelImage->base.Base.Level;
+   int face = intelImage->base.Base.Face;
+   GLuint depth = intelImage->base.Base.Depth;
+
+   if (!invalidate) {
+      for (int slice = 0; slice < depth; slice++) {
+         intel_miptree_copy_slice(intel, dst_mt, src_mt, level, face, slice);
+      }
+   }
+
+   intel_miptree_reference(&intelImage->mt, dst_mt);
+   intel_obj->needs_validate = true;
+}
+
+bool
+intel_miptree_alloc_mcs(struct intel_context *intel,
+                        struct intel_mipmap_tree *mt,
+                        GLuint num_samples)
+{
+   assert(intel->gen >= 7); /* MCS only used on Gen7+ */
+#ifdef I915
+   return false;
+#else
+   assert(mt->mcs_mt == NULL);
+
+   /* Choose the correct format for the MCS buffer.  All that really matters
+    * is that we allocate the right buffer size, since we'll always be
+    * accessing this miptree using MCS-specific hardware mechanisms, which
+    * infer the correct format based on num_samples.
+    */
+   gl_format format;
+   switch (num_samples) {
+   case 4:
+      /* 8 bits/pixel are required for MCS data when using 4x MSAA (2 bits for
+       * each sample).
+       */
+      format = MESA_FORMAT_R8;
+      break;
+   case 8:
+      /* 32 bits/pixel are required for MCS data when using 8x MSAA (3 bits
+       * for each sample, plus 8 padding bits).
+       */
+      format = MESA_FORMAT_R_UINT32;
+      break;
+   default:
+      assert(!"Unrecognized sample count in intel_miptree_alloc_mcs");
+      return false;
+   };
+
+   /* From the Ivy Bridge PRM, Vol4 Part1 p76, "MCS Base Address":
+    *
+    *     "The MCS surface must be stored as Tile Y."
+    */
+   mt->mcs_state = INTEL_MCS_STATE_MSAA;
+   mt->mcs_mt = intel_miptree_create(intel,
+                                     mt->target,
+                                     format,
+                                     mt->first_level,
+                                     mt->last_level,
+                                     mt->logical_width0,
+                                     mt->logical_height0,
+                                     mt->logical_depth0,
+                                     true,
+                                     0 /* num_samples */,
+                                     INTEL_MIPTREE_TILING_Y);
+
+   /* From the Ivy Bridge PRM, Vol 2 Part 1 p326:
+    *
+    *     When MCS buffer is enabled and bound to MSRT, it is required that it
+    *     is cleared prior to any rendering.
+    *
+    * Since we don't use the MCS buffer for any purpose other than rendering,
+    * it makes sense to just clear it immediately upon allocation.
+    *
+    * Note: the clear value for MCS buffers is all 1's, so we memset to 0xff.
+    */
+   void *data = intel_miptree_map_raw(intel, mt->mcs_mt);
+   memset(data, 0xff, mt->mcs_mt->region->bo->size);
+   intel_miptree_unmap_raw(intel, mt->mcs_mt);
+
+   return mt->mcs_mt;
+#endif
+}
+
+
+bool
+intel_miptree_alloc_non_msrt_mcs(struct intel_context *intel,
+                                 struct intel_mipmap_tree *mt)
+{
+#ifdef I915
+   assert(!"MCS not supported on i915");
+   return false;
+#else
+   assert(mt->mcs_mt == NULL);
+
+   /* The format of the MCS buffer is opaque to the driver; all that matters
+    * is that we get its size and pitch right.  We'll pretend that the format
+    * is R32.  Since an MCS tile covers 128 blocks horizontally, and a Y-tiled
+    * R32 buffer is 32 pixels across, we'll need to scale the width down by
+    * the block width and then a further factor of 4.  Since an MCS tile
+    * covers 256 blocks vertically, and a Y-tiled R32 buffer is 32 rows high,
+    * we'll need to scale the height down by the block height and then a
+    * further factor of 8.
+    */
+   const gl_format format = MESA_FORMAT_R_UINT32;
+   unsigned block_width_px;
+   unsigned block_height;
+   intel_get_non_msrt_mcs_alignment(intel, mt, &block_width_px, &block_height);
+   unsigned width_divisor = block_width_px * 4;
+   unsigned height_divisor = block_height * 8;
+   unsigned mcs_width =
+      ALIGN(mt->logical_width0, width_divisor) / width_divisor;
+   unsigned mcs_height =
+      ALIGN(mt->logical_height0, height_divisor) / height_divisor;
+   assert(mt->logical_depth0 == 1);
+   mt->mcs_mt = intel_miptree_create(intel,
+                                     mt->target,
+                                     format,
+                                     mt->first_level,
+                                     mt->last_level,
+                                     mcs_width,
+                                     mcs_height,
+                                     mt->logical_depth0,
+                                     true,
+                                     0 /* num_samples */,
+                                     INTEL_MIPTREE_TILING_Y);
+
+   return mt->mcs_mt;
+#endif
+}
+
+
+/**
+ * Helper for intel_miptree_alloc_hiz() that sets
+ * \c mt->level[level].slice[layer].has_hiz. Return true if and only if
+ * \c has_hiz was set.
+ */
+static bool
+intel_miptree_slice_enable_hiz(struct intel_context *intel,
+                               struct intel_mipmap_tree *mt,
+                               uint32_t level,
+                               uint32_t layer)
+{
+   assert(mt->hiz_mt);
+
+   if (intel->is_haswell) {
+      /* Disable HiZ for some slices to work around a hardware bug.
+       *
+       * Haswell hardware fails to respect
+       * 3DSTATE_DEPTH_BUFFER.Depth_Coordinate_Offset_X/Y when during HiZ
+       * ambiguate operations.  The failure is inconsistent and affected by
+       * other GPU contexts. Running a heavy GPU workload in a separate
+       * process causes the failure rate to drop to nearly 0.
+       *
+       * To workaround the bug, we enable HiZ only when we can guarantee that
+       * the Depth Coordinate Offset fields will be set to 0. The function
+       * brw_get_depthstencil_tile_masks() is used to calculate the fields,
+       * and the function is sometimes called in such a way that the presence
+       * of an attached stencil buffer changes the fuction's return value.
+       *
+       * The largest tile size considered by brw_get_depthstencil_tile_masks()
+       * is that of the stencil buffer. Therefore, if this hiz slice's
+       * corresponding depth slice has an offset that is aligned to the
+       * stencil buffer tile size, 64x64 pixels, then
+       * 3DSTATE_DEPTH_BUFFER.Depth_Coordinate_Offset_X/Y is set to 0.
+       */
+      uint32_t depth_x_offset = mt->level[level].slice[layer].x_offset;
+      uint32_t depth_y_offset = mt->level[level].slice[layer].y_offset;
+      if ((depth_x_offset & 63) || (depth_y_offset & 63)) {
+         return false;
+      }
+   }
+
+   mt->level[level].slice[layer].has_hiz = true;
+   return true;
+}
+
+
+
+bool
+intel_miptree_alloc_hiz(struct intel_context *intel,
+                       struct intel_mipmap_tree *mt)
+{
+   assert(mt->hiz_mt == NULL);
+   mt->hiz_mt = intel_miptree_create(intel,
+                                     mt->target,
+                                     mt->format,
+                                     mt->first_level,
+                                     mt->last_level,
+                                     mt->logical_width0,
+                                     mt->logical_height0,
+                                     mt->logical_depth0,
+                                     true,
+                                     mt->num_samples,
+                                     INTEL_MIPTREE_TILING_ANY);
+
+   if (!mt->hiz_mt)
+      return false;
+
+   /* Mark that all slices need a HiZ resolve. */
+   struct intel_resolve_map *head = &mt->hiz_map;
+   for (int level = mt->first_level; level <= mt->last_level; ++level) {
+      for (int layer = 0; layer < mt->level[level].depth; ++layer) {
+         if (!intel_miptree_slice_enable_hiz(intel, mt, level, layer))
+            continue;
+
+        head->next = malloc(sizeof(*head->next));
+        head->next->prev = head;
+        head->next->next = NULL;
+        head = head->next;
+
+        head->level = level;
+        head->layer = layer;
+        head->need = GEN6_HIZ_OP_HIZ_RESOLVE;
+      }
+   }
+
+   return true;
+}
+
+/**
+ * Does the miptree slice have hiz enabled?
+ */
+bool
+intel_miptree_slice_has_hiz(struct intel_mipmap_tree *mt,
+                            uint32_t level,
+                            uint32_t layer)
+{
+   intel_miptree_check_level_layer(mt, level, layer);
+   return mt->level[level].slice[layer].has_hiz;
+}
+
+void
+intel_miptree_slice_set_needs_hiz_resolve(struct intel_mipmap_tree *mt,
+                                         uint32_t level,
+                                         uint32_t layer)
+{
+   if (!intel_miptree_slice_has_hiz(mt, level, layer))
+      return;
+
+   intel_resolve_map_set(&mt->hiz_map,
+                        level, layer, GEN6_HIZ_OP_HIZ_RESOLVE);
+}
+
+
+void
+intel_miptree_slice_set_needs_depth_resolve(struct intel_mipmap_tree *mt,
+                                            uint32_t level,
+                                            uint32_t layer)
+{
+   if (!intel_miptree_slice_has_hiz(mt, level, layer))
+      return;
+
+   intel_resolve_map_set(&mt->hiz_map,
+                        level, layer, GEN6_HIZ_OP_DEPTH_RESOLVE);
+}
+
+static bool
+intel_miptree_slice_resolve(struct intel_context *intel,
+                           struct intel_mipmap_tree *mt,
+                           uint32_t level,
+                           uint32_t layer,
+                           enum gen6_hiz_op need)
+{
+   intel_miptree_check_level_layer(mt, level, layer);
+
+   struct intel_resolve_map *item =
+        intel_resolve_map_get(&mt->hiz_map, level, layer);
+
+   if (!item || item->need != need)
+      return false;
+
+   intel_hiz_exec(intel, mt, level, layer, need);
+   intel_resolve_map_remove(item);
+   return true;
+}
+
+bool
+intel_miptree_slice_resolve_hiz(struct intel_context *intel,
+                               struct intel_mipmap_tree *mt,
+                               uint32_t level,
+                               uint32_t layer)
+{
+   return intel_miptree_slice_resolve(intel, mt, level, layer,
+                                     GEN6_HIZ_OP_HIZ_RESOLVE);
+}
+
+bool
+intel_miptree_slice_resolve_depth(struct intel_context *intel,
+                                 struct intel_mipmap_tree *mt,
+                                 uint32_t level,
+                                 uint32_t layer)
+{
+   return intel_miptree_slice_resolve(intel, mt, level, layer,
+                                     GEN6_HIZ_OP_DEPTH_RESOLVE);
+}
+
+static bool
+intel_miptree_all_slices_resolve(struct intel_context *intel,
+                                struct intel_mipmap_tree *mt,
+                                enum gen6_hiz_op need)
+{
+   bool did_resolve = false;
+   struct intel_resolve_map *i, *next;
+
+   for (i = mt->hiz_map.next; i; i = next) {
+      next = i->next;
+      if (i->need != need)
+        continue;
+
+      intel_hiz_exec(intel, mt, i->level, i->layer, need);
+      intel_resolve_map_remove(i);
+      did_resolve = true;
+   }
+
+   return did_resolve;
+}
+
+bool
+intel_miptree_all_slices_resolve_hiz(struct intel_context *intel,
+                                    struct intel_mipmap_tree *mt)
+{
+   return intel_miptree_all_slices_resolve(intel, mt,
+                                          GEN6_HIZ_OP_HIZ_RESOLVE);
+}
+
+bool
+intel_miptree_all_slices_resolve_depth(struct intel_context *intel,
+                                      struct intel_mipmap_tree *mt)
+{
+   return intel_miptree_all_slices_resolve(intel, mt,
+                                          GEN6_HIZ_OP_DEPTH_RESOLVE);
+}
+
+
+void
+intel_miptree_resolve_color(struct intel_context *intel,
+                            struct intel_mipmap_tree *mt)
+{
+#ifdef I915
+   /* Fast color clear is not supported on the i915 (pre-Gen4) driver */
+#else
+   switch (mt->mcs_state) {
+   case INTEL_MCS_STATE_NONE:
+   case INTEL_MCS_STATE_MSAA:
+   case INTEL_MCS_STATE_RESOLVED:
+      /* No resolve needed */
+      break;
+   case INTEL_MCS_STATE_UNRESOLVED:
+   case INTEL_MCS_STATE_CLEAR:
+      brw_blorp_resolve_color(intel, mt);
+      break;
+   }
+#endif
+}
+
+
+/**
+ * Make it possible to share the region backing the given miptree with another
+ * process or another miptree.
+ *
+ * Fast color clears are unsafe with shared buffers, so we need to resolve and
+ * then discard the MCS buffer, if present.  We also set the mcs_state to
+ * INTEL_MCS_STATE_NONE to ensure that no MCS buffer gets allocated in the
+ * future.
+ */
+void
+intel_miptree_make_shareable(struct intel_context *intel,
+                             struct intel_mipmap_tree *mt)
+{
+#ifdef I915
+   /* Nothing needs to be done for I915 */
+   (void) intel;
+   (void) mt;
+#else
+   /* MCS buffers are also used for multisample buffers, but we can't resolve
+    * away a multisample MCS buffer because it's an integral part of how the
+    * pixel data is stored.  Fortunately this code path should never be
+    * reached for multisample buffers.
+    */
+   assert(mt->msaa_layout == INTEL_MSAA_LAYOUT_NONE);
+
+   if (mt->mcs_mt) {
+      intel_miptree_resolve_color(intel, mt);
+      intel_miptree_release(&mt->mcs_mt);
+      mt->mcs_state = INTEL_MCS_STATE_NONE;
+   }
+#endif
+}
+
+
+/**
+ * \brief Get pointer offset into stencil buffer.
+ *
+ * The stencil buffer is W tiled. Since the GTT is incapable of W fencing, we
+ * must decode the tile's layout in software.
+ *
+ * See
+ *   - PRM, 2011 Sandy Bridge, Volume 1, Part 2, Section 4.5.2.1 W-Major Tile
+ *     Format.
+ *   - PRM, 2011 Sandy Bridge, Volume 1, Part 2, Section 4.5.3 Tiling Algorithm
+ *
+ * Even though the returned offset is always positive, the return type is
+ * signed due to
+ *    commit e8b1c6d6f55f5be3bef25084fdd8b6127517e137
+ *    mesa: Fix return type of  _mesa_get_format_bytes() (#37351)
+ */
+static intptr_t
+intel_offset_S8(uint32_t stride, uint32_t x, uint32_t y, bool swizzled)
+{
+   uint32_t tile_size = 4096;
+   uint32_t tile_width = 64;
+   uint32_t tile_height = 64;
+   uint32_t row_size = 64 * stride;
+
+   uint32_t tile_x = x / tile_width;
+   uint32_t tile_y = y / tile_height;
+
+   /* The byte's address relative to the tile's base addres. */
+   uint32_t byte_x = x % tile_width;
+   uint32_t byte_y = y % tile_height;
+
+   uintptr_t u = tile_y * row_size
+               + tile_x * tile_size
+               + 512 * (byte_x / 8)
+               +  64 * (byte_y / 8)
+               +  32 * ((byte_y / 4) % 2)
+               +  16 * ((byte_x / 4) % 2)
+               +   8 * ((byte_y / 2) % 2)
+               +   4 * ((byte_x / 2) % 2)
+               +   2 * (byte_y % 2)
+               +   1 * (byte_x % 2);
+
+   if (swizzled) {
+      /* adjust for bit6 swizzling */
+      if (((byte_x / 8) % 2) == 1) {
+        if (((byte_y / 8) % 2) == 0) {
+           u += 64;
+        } else {
+           u -= 64;
+        }
+      }
+   }
+
+   return u;
+}
+
+static void
+intel_miptree_updownsample(struct intel_context *intel,
+                           struct intel_mipmap_tree *src,
+                           struct intel_mipmap_tree *dst,
+                           unsigned width,
+                           unsigned height)
+{
+#ifndef I915
+   int src_x0 = 0;
+   int src_y0 = 0;
+   int dst_x0 = 0;
+   int dst_y0 = 0;
+
+   brw_blorp_blit_miptrees(intel,
+                           src, 0 /* level */, 0 /* layer */,
+                           dst, 0 /* level */, 0 /* layer */,
+                           src_x0, src_y0,
+                           width, height,
+                           dst_x0, dst_y0,
+                           width, height,
+                           false, false /*mirror x, y*/);
+
+   if (src->stencil_mt) {
+      brw_blorp_blit_miptrees(intel,
+                              src->stencil_mt, 0 /* level */, 0 /* layer */,
+                              dst->stencil_mt, 0 /* level */, 0 /* layer */,
+                              src_x0, src_y0,
+                              width, height,
+                              dst_x0, dst_y0,
+                              width, height,
+                              false, false /*mirror x, y*/);
+   }
+#endif /* I915 */
+}
+
+static void
+assert_is_flat(struct intel_mipmap_tree *mt)
+{
+   assert(mt->target == GL_TEXTURE_2D);
+   assert(mt->first_level == 0);
+   assert(mt->last_level == 0);
+}
+
+/**
+ * \brief Downsample from mt to mt->singlesample_mt.
+ *
+ * If the miptree needs no downsample, then skip.
+ */
+void
+intel_miptree_downsample(struct intel_context *intel,
+                         struct intel_mipmap_tree *mt)
+{
+   /* Only flat, renderbuffer-like miptrees are supported. */
+   assert_is_flat(mt);
+
+   if (!mt->need_downsample)
+      return;
+   intel_miptree_updownsample(intel,
+                              mt, mt->singlesample_mt,
+                              mt->logical_width0,
+                              mt->logical_height0);
+   mt->need_downsample = false;
+}
+
+/**
+ * \brief Upsample from mt->singlesample_mt to mt.
+ *
+ * The upsample is done unconditionally.
+ */
+void
+intel_miptree_upsample(struct intel_context *intel,
+                       struct intel_mipmap_tree *mt)
+{
+   /* Only flat, renderbuffer-like miptrees are supported. */
+   assert_is_flat(mt);
+   assert(!mt->need_downsample);
+
+   intel_miptree_updownsample(intel,
+                              mt->singlesample_mt, mt,
+                              mt->logical_width0,
+                              mt->logical_height0);
+}
+
+void *
+intel_miptree_map_raw(struct intel_context *intel, struct intel_mipmap_tree *mt)
+{
+   /* CPU accesses to color buffers don't understand fast color clears, so
+    * resolve any pending fast color clears before we map.
+    */
+   intel_miptree_resolve_color(intel, mt);
+
+   drm_intel_bo *bo = mt->region->bo;
+
+   if (unlikely(INTEL_DEBUG & DEBUG_PERF)) {
+      if (drm_intel_bo_busy(bo)) {
+         perf_debug("Mapping a busy BO, causing a stall on the GPU.\n");
+      }
+   }
+
+   intel_flush(&intel->ctx);
+
+   if (mt->region->tiling != I915_TILING_NONE)
+      drm_intel_gem_bo_map_gtt(bo);
+   else
+      drm_intel_bo_map(bo, true);
+
+   return bo->virtual;
+}
+
+void
+intel_miptree_unmap_raw(struct intel_context *intel,
+                        struct intel_mipmap_tree *mt)
+{
+   drm_intel_bo_unmap(mt->region->bo);
+}
+
+static void
+intel_miptree_map_gtt(struct intel_context *intel,
+                     struct intel_mipmap_tree *mt,
+                     struct intel_miptree_map *map,
+                     unsigned int level, unsigned int slice)
+{
+   unsigned int bw, bh;
+   void *base;
+   unsigned int image_x, image_y;
+   int x = map->x;
+   int y = map->y;
+
+   /* For compressed formats, the stride is the number of bytes per
+    * row of blocks.  intel_miptree_get_image_offset() already does
+    * the divide.
+    */
+   _mesa_get_format_block_size(mt->format, &bw, &bh);
+   assert(y % bh == 0);
+   y /= bh;
+
+   base = intel_miptree_map_raw(intel, mt) + mt->offset;
+
+   if (base == NULL)
+      map->ptr = NULL;
+   else {
+      /* Note that in the case of cube maps, the caller must have passed the
+       * slice number referencing the face.
+      */
+      intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y);
+      x += image_x;
+      y += image_y;
+
+      map->stride = mt->region->pitch;
+      map->ptr = base + y * map->stride + x * mt->cpp;
+   }
+
+   DBG("%s: %d,%d %dx%d from mt %p (%s) %d,%d = %p/%d\n", __FUNCTION__,
+       map->x, map->y, map->w, map->h,
+       mt, _mesa_get_format_name(mt->format),
+       x, y, map->ptr, map->stride);
+}
+
+static void
+intel_miptree_unmap_gtt(struct intel_context *intel,
+                       struct intel_mipmap_tree *mt,
+                       struct intel_miptree_map *map,
+                       unsigned int level,
+                       unsigned int slice)
+{
+   intel_miptree_unmap_raw(intel, mt);
+}
+
+static void
+intel_miptree_map_blit(struct intel_context *intel,
+                      struct intel_mipmap_tree *mt,
+                      struct intel_miptree_map *map,
+                      unsigned int level, unsigned int slice)
+{
+   map->mt = intel_miptree_create(intel, GL_TEXTURE_2D, mt->format,
+                                  0, 0,
+                                  map->w, map->h, 1,
+                                  false, 0,
+                                  INTEL_MIPTREE_TILING_NONE);
+   if (!map->mt) {
+      fprintf(stderr, "Failed to allocate blit temporary\n");
+      goto fail;
+   }
+   map->stride = map->mt->region->pitch;
+
+   if (!intel_miptree_blit(intel,
+                           mt, level, slice,
+                           map->x, map->y, false,
+                           map->mt, 0, 0,
+                           0, 0, false,
+                           map->w, map->h, GL_COPY)) {
+      fprintf(stderr, "Failed to blit\n");
+      goto fail;
+   }
+
+   intel_batchbuffer_flush(intel);
+   map->ptr = intel_miptree_map_raw(intel, map->mt);
+
+   DBG("%s: %d,%d %dx%d from mt %p (%s) %d,%d = %p/%d\n", __FUNCTION__,
+       map->x, map->y, map->w, map->h,
+       mt, _mesa_get_format_name(mt->format),
+       level, slice, map->ptr, map->stride);
+
+   return;
+
+fail:
+   intel_miptree_release(&map->mt);
+   map->ptr = NULL;
+   map->stride = 0;
+}
+
+static void
+intel_miptree_unmap_blit(struct intel_context *intel,
+                        struct intel_mipmap_tree *mt,
+                        struct intel_miptree_map *map,
+                        unsigned int level,
+                        unsigned int slice)
+{
+   struct gl_context *ctx = &intel->ctx;
+
+   intel_miptree_unmap_raw(intel, map->mt);
+
+   if (map->mode & GL_MAP_WRITE_BIT) {
+      bool ok = intel_miptree_blit(intel,
+                                   map->mt, 0, 0,
+                                   0, 0, false,
+                                   mt, level, slice,
+                                   map->x, map->y, false,
+                                   map->w, map->h, GL_COPY);
+      WARN_ONCE(!ok, "Failed to blit from linear temporary mapping");
+   }
+
+   intel_miptree_release(&map->mt);
+}
+
+static void
+intel_miptree_map_s8(struct intel_context *intel,
+                    struct intel_mipmap_tree *mt,
+                    struct intel_miptree_map *map,
+                    unsigned int level, unsigned int slice)
+{
+   map->stride = map->w;
+   map->buffer = map->ptr = malloc(map->stride * map->h);
+   if (!map->buffer)
+      return;
+
+   /* One of either READ_BIT or WRITE_BIT or both is set.  READ_BIT implies no
+    * INVALIDATE_RANGE_BIT.  WRITE_BIT needs the original values read in unless
+    * invalidate is set, since we'll be writing the whole rectangle from our
+    * temporary buffer back out.
+    */
+   if (!(map->mode & GL_MAP_INVALIDATE_RANGE_BIT)) {
+      uint8_t *untiled_s8_map = map->ptr;
+      uint8_t *tiled_s8_map = intel_miptree_map_raw(intel, mt);
+      unsigned int image_x, image_y;
+
+      intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y);
+
+      for (uint32_t y = 0; y < map->h; y++) {
+        for (uint32_t x = 0; x < map->w; x++) {
+           ptrdiff_t offset = intel_offset_S8(mt->region->pitch,
+                                              x + image_x + map->x,
+                                              y + image_y + map->y,
+                                              intel->has_swizzling);
+           untiled_s8_map[y * map->w + x] = tiled_s8_map[offset];
+        }
+      }
+
+      intel_miptree_unmap_raw(intel, mt);
+
+      DBG("%s: %d,%d %dx%d from mt %p %d,%d = %p/%d\n", __FUNCTION__,
+         map->x, map->y, map->w, map->h,
+         mt, map->x + image_x, map->y + image_y, map->ptr, map->stride);
+   } else {
+      DBG("%s: %d,%d %dx%d from mt %p = %p/%d\n", __FUNCTION__,
+         map->x, map->y, map->w, map->h,
+         mt, map->ptr, map->stride);
+   }
+}
+
+static void
+intel_miptree_unmap_s8(struct intel_context *intel,
+                      struct intel_mipmap_tree *mt,
+                      struct intel_miptree_map *map,
+                      unsigned int level,
+                      unsigned int slice)
+{
+   if (map->mode & GL_MAP_WRITE_BIT) {
+      unsigned int image_x, image_y;
+      uint8_t *untiled_s8_map = map->ptr;
+      uint8_t *tiled_s8_map = intel_miptree_map_raw(intel, mt);
+
+      intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y);
+
+      for (uint32_t y = 0; y < map->h; y++) {
+        for (uint32_t x = 0; x < map->w; x++) {
+           ptrdiff_t offset = intel_offset_S8(mt->region->pitch,
+                                              x + map->x,
+                                              y + map->y,
+                                              intel->has_swizzling);
+           tiled_s8_map[offset] = untiled_s8_map[y * map->w + x];
+        }
+      }
+
+      intel_miptree_unmap_raw(intel, mt);
+   }
+
+   free(map->buffer);
+}
+
+static void
+intel_miptree_map_etc(struct intel_context *intel,
+                      struct intel_mipmap_tree *mt,
+                      struct intel_miptree_map *map,
+                      unsigned int level,
+                      unsigned int slice)
+{
+   assert(mt->etc_format != MESA_FORMAT_NONE);
+   if (mt->etc_format == MESA_FORMAT_ETC1_RGB8) {
+      assert(mt->format == MESA_FORMAT_RGBX8888_REV);
+   }
+
+   assert(map->mode & GL_MAP_WRITE_BIT);
+   assert(map->mode & GL_MAP_INVALIDATE_RANGE_BIT);
+
+   map->stride = _mesa_format_row_stride(mt->etc_format, map->w);
+   map->buffer = malloc(_mesa_format_image_size(mt->etc_format,
+                                                map->w, map->h, 1));
+   map->ptr = map->buffer;
+}
+
+static void
+intel_miptree_unmap_etc(struct intel_context *intel,
+                        struct intel_mipmap_tree *mt,
+                        struct intel_miptree_map *map,
+                        unsigned int level,
+                        unsigned int slice)
+{
+   uint32_t image_x;
+   uint32_t image_y;
+   intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y);
+
+   image_x += map->x;
+   image_y += map->y;
+
+   uint8_t *dst = intel_miptree_map_raw(intel, mt)
+                + image_y * mt->region->pitch
+                + image_x * mt->region->cpp;
+
+   if (mt->etc_format == MESA_FORMAT_ETC1_RGB8)
+      _mesa_etc1_unpack_rgba8888(dst, mt->region->pitch,
+                                 map->ptr, map->stride,
+                                 map->w, map->h);
+   else
+      _mesa_unpack_etc2_format(dst, mt->region->pitch,
+                               map->ptr, map->stride,
+                               map->w, map->h, mt->etc_format);
+
+   intel_miptree_unmap_raw(intel, mt);
+   free(map->buffer);
+}
+
+/**
+ * Mapping function for packed depth/stencil miptrees backed by real separate
+ * miptrees for depth and stencil.
+ *
+ * On gen7, and to support HiZ pre-gen7, we have to have the stencil buffer
+ * separate from the depth buffer.  Yet at the GL API level, we have to expose
+ * packed depth/stencil textures and FBO attachments, and Mesa core expects to
+ * be able to map that memory for texture storage and glReadPixels-type
+ * operations.  We give Mesa core that access by mallocing a temporary and
+ * copying the data between the actual backing store and the temporary.
+ */
+static void
+intel_miptree_map_depthstencil(struct intel_context *intel,
+                              struct intel_mipmap_tree *mt,
+                              struct intel_miptree_map *map,
+                              unsigned int level, unsigned int slice)
+{
+   struct intel_mipmap_tree *z_mt = mt;
+   struct intel_mipmap_tree *s_mt = mt->stencil_mt;
+   bool map_z32f_x24s8 = mt->format == MESA_FORMAT_Z32_FLOAT;
+   int packed_bpp = map_z32f_x24s8 ? 8 : 4;
+
+   map->stride = map->w * packed_bpp;
+   map->buffer = map->ptr = malloc(map->stride * map->h);
+   if (!map->buffer)
+      return;
+
+   /* One of either READ_BIT or WRITE_BIT or both is set.  READ_BIT implies no
+    * INVALIDATE_RANGE_BIT.  WRITE_BIT needs the original values read in unless
+    * invalidate is set, since we'll be writing the whole rectangle from our
+    * temporary buffer back out.
+    */
+   if (!(map->mode & GL_MAP_INVALIDATE_RANGE_BIT)) {
+      uint32_t *packed_map = map->ptr;
+      uint8_t *s_map = intel_miptree_map_raw(intel, s_mt);
+      uint32_t *z_map = intel_miptree_map_raw(intel, z_mt);
+      unsigned int s_image_x, s_image_y;
+      unsigned int z_image_x, z_image_y;
+
+      intel_miptree_get_image_offset(s_mt, level, slice,
+                                    &s_image_x, &s_image_y);
+      intel_miptree_get_image_offset(z_mt, level, slice,
+                                    &z_image_x, &z_image_y);
+
+      for (uint32_t y = 0; y < map->h; y++) {
+        for (uint32_t x = 0; x < map->w; x++) {
+           int map_x = map->x + x, map_y = map->y + y;
+           ptrdiff_t s_offset = intel_offset_S8(s_mt->region->pitch,
+                                                map_x + s_image_x,
+                                                map_y + s_image_y,
+                                                intel->has_swizzling);
+           ptrdiff_t z_offset = ((map_y + z_image_y) *
+                                  (z_mt->region->pitch / 4) +
+                                 (map_x + z_image_x));
+           uint8_t s = s_map[s_offset];
+           uint32_t z = z_map[z_offset];
+
+           if (map_z32f_x24s8) {
+              packed_map[(y * map->w + x) * 2 + 0] = z;
+              packed_map[(y * map->w + x) * 2 + 1] = s;
+           } else {
+              packed_map[y * map->w + x] = (s << 24) | (z & 0x00ffffff);
+           }
+        }
+      }
+
+      intel_miptree_unmap_raw(intel, s_mt);
+      intel_miptree_unmap_raw(intel, z_mt);
+
+      DBG("%s: %d,%d %dx%d from z mt %p %d,%d, s mt %p %d,%d = %p/%d\n",
+         __FUNCTION__,
+         map->x, map->y, map->w, map->h,
+         z_mt, map->x + z_image_x, map->y + z_image_y,
+         s_mt, map->x + s_image_x, map->y + s_image_y,
+         map->ptr, map->stride);
+   } else {
+      DBG("%s: %d,%d %dx%d from mt %p = %p/%d\n", __FUNCTION__,
+         map->x, map->y, map->w, map->h,
+         mt, map->ptr, map->stride);
+   }
+}
+
+static void
+intel_miptree_unmap_depthstencil(struct intel_context *intel,
+                                struct intel_mipmap_tree *mt,
+                                struct intel_miptree_map *map,
+                                unsigned int level,
+                                unsigned int slice)
+{
+   struct intel_mipmap_tree *z_mt = mt;
+   struct intel_mipmap_tree *s_mt = mt->stencil_mt;
+   bool map_z32f_x24s8 = mt->format == MESA_FORMAT_Z32_FLOAT;
+
+   if (map->mode & GL_MAP_WRITE_BIT) {
+      uint32_t *packed_map = map->ptr;
+      uint8_t *s_map = intel_miptree_map_raw(intel, s_mt);
+      uint32_t *z_map = intel_miptree_map_raw(intel, z_mt);
+      unsigned int s_image_x, s_image_y;
+      unsigned int z_image_x, z_image_y;
+
+      intel_miptree_get_image_offset(s_mt, level, slice,
+                                    &s_image_x, &s_image_y);
+      intel_miptree_get_image_offset(z_mt, level, slice,
+                                    &z_image_x, &z_image_y);
+
+      for (uint32_t y = 0; y < map->h; y++) {
+        for (uint32_t x = 0; x < map->w; x++) {
+           ptrdiff_t s_offset = intel_offset_S8(s_mt->region->pitch,
+                                                x + s_image_x + map->x,
+                                                y + s_image_y + map->y,
+                                                intel->has_swizzling);
+           ptrdiff_t z_offset = ((y + z_image_y) *
+                                  (z_mt->region->pitch / 4) +
+                                 (x + z_image_x));
+
+           if (map_z32f_x24s8) {
+              z_map[z_offset] = packed_map[(y * map->w + x) * 2 + 0];
+              s_map[s_offset] = packed_map[(y * map->w + x) * 2 + 1];
+           } else {
+              uint32_t packed = packed_map[y * map->w + x];
+              s_map[s_offset] = packed >> 24;
+              z_map[z_offset] = packed;
+           }
+        }
+      }
+
+      intel_miptree_unmap_raw(intel, s_mt);
+      intel_miptree_unmap_raw(intel, z_mt);
+
+      DBG("%s: %d,%d %dx%d from z mt %p (%s) %d,%d, s mt %p %d,%d = %p/%d\n",
+         __FUNCTION__,
+         map->x, map->y, map->w, map->h,
+         z_mt, _mesa_get_format_name(z_mt->format),
+         map->x + z_image_x, map->y + z_image_y,
+         s_mt, map->x + s_image_x, map->y + s_image_y,
+         map->ptr, map->stride);
+   }
+
+   free(map->buffer);
+}
+
+/**
+ * Create and attach a map to the miptree at (level, slice). Return the
+ * attached map.
+ */
+static struct intel_miptree_map*
+intel_miptree_attach_map(struct intel_mipmap_tree *mt,
+                         unsigned int level,
+                         unsigned int slice,
+                         unsigned int x,
+                         unsigned int y,
+                         unsigned int w,
+                         unsigned int h,
+                         GLbitfield mode)
+{
+   struct intel_miptree_map *map = calloc(1, sizeof(*map));
+
+   if (!map)
+      return NULL;
+
+   assert(mt->level[level].slice[slice].map == NULL);
+   mt->level[level].slice[slice].map = map;
+
+   map->mode = mode;
+   map->x = x;
+   map->y = y;
+   map->w = w;
+   map->h = h;
+
+   return map;
+}
+
+/**
+ * Release the map at (level, slice).
+ */
+static void
+intel_miptree_release_map(struct intel_mipmap_tree *mt,
+                         unsigned int level,
+                         unsigned int slice)
+{
+   struct intel_miptree_map **map;
+
+   map = &mt->level[level].slice[slice].map;
+   free(*map);
+   *map = NULL;
+}
+
+static void
+intel_miptree_map_singlesample(struct intel_context *intel,
+                               struct intel_mipmap_tree *mt,
+                               unsigned int level,
+                               unsigned int slice,
+                               unsigned int x,
+                               unsigned int y,
+                               unsigned int w,
+                               unsigned int h,
+                               GLbitfield mode,
+                               void **out_ptr,
+                               int *out_stride)
+{
+   struct intel_miptree_map *map;
+
+   assert(mt->num_samples <= 1);
+
+   map = intel_miptree_attach_map(mt, level, slice, x, y, w, h, mode);
+   if (!map){
+      *out_ptr = NULL;
+      *out_stride = 0;
+      return;
+   }
+
+   intel_miptree_slice_resolve_depth(intel, mt, level, slice);
+   if (map->mode & GL_MAP_WRITE_BIT) {
+      intel_miptree_slice_set_needs_hiz_resolve(mt, level, slice);
+   }
+
+   if (mt->format == MESA_FORMAT_S8) {
+      intel_miptree_map_s8(intel, mt, map, level, slice);
+   } else if (mt->etc_format != MESA_FORMAT_NONE &&
+              !(mode & BRW_MAP_DIRECT_BIT)) {
+      intel_miptree_map_etc(intel, mt, map, level, slice);
+   } else if (mt->stencil_mt && !(mode & BRW_MAP_DIRECT_BIT)) {
+      intel_miptree_map_depthstencil(intel, mt, map, level, slice);
+   }
+   /* See intel_miptree_blit() for details on the 32k pitch limit. */
+   else if (intel->has_llc &&
+            !(mode & GL_MAP_WRITE_BIT) &&
+            !mt->compressed &&
+            (mt->region->tiling == I915_TILING_X ||
+             (intel->gen >= 6 && mt->region->tiling == I915_TILING_Y)) &&
+            mt->region->pitch < 32768) {
+      intel_miptree_map_blit(intel, mt, map, level, slice);
+   } else if (mt->region->tiling != I915_TILING_NONE &&
+              mt->region->bo->size >= intel->max_gtt_map_object_size) {
+      assert(mt->region->pitch < 32768);
+      intel_miptree_map_blit(intel, mt, map, level, slice);
+   } else {
+      intel_miptree_map_gtt(intel, mt, map, level, slice);
+   }
+
+   *out_ptr = map->ptr;
+   *out_stride = map->stride;
+
+   if (map->ptr == NULL)
+      intel_miptree_release_map(mt, level, slice);
+}
+
+static void
+intel_miptree_unmap_singlesample(struct intel_context *intel,
+                                 struct intel_mipmap_tree *mt,
+                                 unsigned int level,
+                                 unsigned int slice)
+{
+   struct intel_miptree_map *map = mt->level[level].slice[slice].map;
+
+   assert(mt->num_samples <= 1);
+
+   if (!map)
+      return;
+
+   DBG("%s: mt %p (%s) level %d slice %d\n", __FUNCTION__,
+       mt, _mesa_get_format_name(mt->format), level, slice);
+
+   if (mt->format == MESA_FORMAT_S8) {
+      intel_miptree_unmap_s8(intel, mt, map, level, slice);
+   } else if (mt->etc_format != MESA_FORMAT_NONE &&
+              !(map->mode & BRW_MAP_DIRECT_BIT)) {
+      intel_miptree_unmap_etc(intel, mt, map, level, slice);
+   } else if (mt->stencil_mt && !(map->mode & BRW_MAP_DIRECT_BIT)) {
+      intel_miptree_unmap_depthstencil(intel, mt, map, level, slice);
+   } else if (map->mt) {
+      intel_miptree_unmap_blit(intel, mt, map, level, slice);
+   } else {
+      intel_miptree_unmap_gtt(intel, mt, map, level, slice);
+   }
+
+   intel_miptree_release_map(mt, level, slice);
+}
+
+static void
+intel_miptree_map_multisample(struct intel_context *intel,
+                              struct intel_mipmap_tree *mt,
+                              unsigned int level,
+                              unsigned int slice,
+                              unsigned int x,
+                              unsigned int y,
+                              unsigned int w,
+                              unsigned int h,
+                              GLbitfield mode,
+                              void **out_ptr,
+                              int *out_stride)
+{
+   struct intel_miptree_map *map;
+
+   assert(mt->num_samples > 1);
+
+   /* Only flat, renderbuffer-like miptrees are supported. */
+   if (mt->target != GL_TEXTURE_2D ||
+       mt->first_level != 0 ||
+       mt->last_level != 0) {
+      _mesa_problem(&intel->ctx, "attempt to map a multisample miptree for "
+                    "which (target, first_level, last_level != "
+                    "(GL_TEXTURE_2D, 0, 0)");
+      goto fail;
+   }
+
+   map = intel_miptree_attach_map(mt, level, slice, x, y, w, h, mode);
+   if (!map)
+      goto fail;
+
+   if (!mt->singlesample_mt) {
+      mt->singlesample_mt =
+         intel_miptree_create_for_renderbuffer(intel,
+                                               mt->format,
+                                               mt->logical_width0,
+                                               mt->logical_height0,
+                                               0 /*num_samples*/);
+      if (!mt->singlesample_mt)
+         goto fail;
+
+      map->singlesample_mt_is_tmp = true;
+      mt->need_downsample = true;
+   }
+
+   intel_miptree_downsample(intel, mt);
+   intel_miptree_map_singlesample(intel, mt->singlesample_mt,
+                                  level, slice,
+                                  x, y, w, h,
+                                  mode,
+                                  out_ptr, out_stride);
+   return;
+
+fail:
+   intel_miptree_release_map(mt, level, slice);
+   *out_ptr = NULL;
+   *out_stride = 0;
+}
+
+static void
+intel_miptree_unmap_multisample(struct intel_context *intel,
+                                struct intel_mipmap_tree *mt,
+                                unsigned int level,
+                                unsigned int slice)
+{
+   struct intel_miptree_map *map = mt->level[level].slice[slice].map;
+
+   assert(mt->num_samples > 1);
+
+   if (!map)
+      return;
+
+   intel_miptree_unmap_singlesample(intel, mt->singlesample_mt, level, slice);
+
+   mt->need_downsample = false;
+   if (map->mode & GL_MAP_WRITE_BIT)
+      intel_miptree_upsample(intel, mt);
+
+   if (map->singlesample_mt_is_tmp)
+      intel_miptree_release(&mt->singlesample_mt);
+
+   intel_miptree_release_map(mt, level, slice);
+}
+
+void
+intel_miptree_map(struct intel_context *intel,
+                 struct intel_mipmap_tree *mt,
+                 unsigned int level,
+                 unsigned int slice,
+                 unsigned int x,
+                 unsigned int y,
+                 unsigned int w,
+                 unsigned int h,
+                 GLbitfield mode,
+                 void **out_ptr,
+                 int *out_stride)
+{
+   if (mt->num_samples <= 1)
+      intel_miptree_map_singlesample(intel, mt,
+                                     level, slice,
+                                     x, y, w, h,
+                                     mode,
+                                     out_ptr, out_stride);
+   else
+      intel_miptree_map_multisample(intel, mt,
+                                    level, slice,
+                                    x, y, w, h,
+                                    mode,
+                                    out_ptr, out_stride);
+}
+
+void
+intel_miptree_unmap(struct intel_context *intel,
+                   struct intel_mipmap_tree *mt,
+                   unsigned int level,
+                   unsigned int slice)
+{
+   if (mt->num_samples <= 1)
+      intel_miptree_unmap_singlesample(intel, mt, level, slice);
+   else
+      intel_miptree_unmap_multisample(intel, mt, level, slice);
+}
deleted file mode 120000 (symlink)
index d733c5e874563faf2be92dc96255261d0b3efc6d..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_pixel.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..f58cb855e60bb6b03c03291b5ba82c191261e020
--- /dev/null
@@ -0,0 +1,135 @@
+/**************************************************************************
+ * 
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portionsalloc
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#include "main/accum.h"
+#include "main/enums.h"
+#include "main/state.h"
+#include "main/bufferobj.h"
+#include "main/context.h"
+#include "swrast/swrast.h"
+
+#include "intel_context.h"
+#include "intel_pixel.h"
+#include "intel_regions.h"
+
+#define FILE_DEBUG_FLAG DEBUG_PIXEL
+
+static GLenum
+effective_func(GLenum func, bool src_alpha_is_one)
+{
+   if (src_alpha_is_one) {
+      if (func == GL_SRC_ALPHA)
+        return GL_ONE;
+      if (func == GL_ONE_MINUS_SRC_ALPHA)
+        return GL_ZERO;
+   }
+
+   return func;
+}
+
+/**
+ * Check if any fragment operations are in effect which might effect
+ * glDraw/CopyPixels.
+ */
+bool
+intel_check_blit_fragment_ops(struct gl_context * ctx, bool src_alpha_is_one)
+{
+   if (ctx->NewState)
+      _mesa_update_state(ctx);
+
+   if (ctx->FragmentProgram._Enabled) {
+      DBG("fallback due to fragment program\n");
+      return false;
+   }
+
+   if (ctx->Color.BlendEnabled &&
+       (effective_func(ctx->Color.Blend[0].SrcRGB, src_alpha_is_one) != GL_ONE ||
+       effective_func(ctx->Color.Blend[0].DstRGB, src_alpha_is_one) != GL_ZERO ||
+       ctx->Color.Blend[0].EquationRGB != GL_FUNC_ADD ||
+       effective_func(ctx->Color.Blend[0].SrcA, src_alpha_is_one) != GL_ONE ||
+       effective_func(ctx->Color.Blend[0].DstA, src_alpha_is_one) != GL_ZERO ||
+       ctx->Color.Blend[0].EquationA != GL_FUNC_ADD)) {
+      DBG("fallback due to blend\n");
+      return false;
+   }
+
+   if (ctx->Texture._EnabledUnits) {
+      DBG("fallback due to texturing\n");
+      return false;
+   }
+
+   if (!(ctx->Color.ColorMask[0][0] &&
+        ctx->Color.ColorMask[0][1] &&
+        ctx->Color.ColorMask[0][2] &&
+        ctx->Color.ColorMask[0][3])) {
+      DBG("fallback due to color masking\n");
+      return false;
+   }
+
+   if (ctx->Color.AlphaEnabled) {
+      DBG("fallback due to alpha\n");
+      return false;
+   }
+
+   if (ctx->Depth.Test) {
+      DBG("fallback due to depth test\n");
+      return false;
+   }
+
+   if (ctx->Fog.Enabled) {
+      DBG("fallback due to fog\n");
+      return false;
+   }
+
+   if (ctx->_ImageTransferState) {
+      DBG("fallback due to image transfer\n");
+      return false;
+   }
+
+   if (ctx->Stencil._Enabled) {
+      DBG("fallback due to image stencil\n");
+      return false;
+   }
+
+   if (ctx->RenderMode != GL_RENDER) {
+      DBG("fallback due to render mode\n");
+      return false;
+   }
+
+   return true;
+}
+
+void
+intelInitPixelFuncs(struct dd_function_table *functions)
+{
+   functions->Accum = _mesa_accum;
+   functions->Bitmap = intelBitmap;
+   functions->CopyPixels = intelCopyPixels;
+   functions->DrawPixels = intelDrawPixels;
+   functions->ReadPixels = intelReadPixels;
+}
+
deleted file mode 120000 (symlink)
index 9085c7b0397448a2e3ab47ca0b803921d9175469..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_pixel_bitmap.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..8c0edf2dd8592d7f5a28bbc3b103cde81ca0465f
--- /dev/null
@@ -0,0 +1,363 @@
+/**************************************************************************
+ * 
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portionsalloc
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#include "main/glheader.h"
+#include "main/enums.h"
+#include "main/image.h"
+#include "main/colormac.h"
+#include "main/condrender.h"
+#include "main/mtypes.h"
+#include "main/macros.h"
+#include "main/pbo.h"
+#include "main/bufferobj.h"
+#include "main/state.h"
+#include "main/texobj.h"
+#include "main/context.h"
+#include "main/fbobject.h"
+#include "swrast/swrast.h"
+#include "drivers/common/meta.h"
+
+#include "intel_screen.h"
+#include "intel_context.h"
+#include "intel_batchbuffer.h"
+#include "intel_blit.h"
+#include "intel_fbo.h"
+#include "intel_regions.h"
+#include "intel_buffers.h"
+#include "intel_pixel.h"
+#include "intel_reg.h"
+
+
+#define FILE_DEBUG_FLAG DEBUG_PIXEL
+
+
+/* Unlike the other intel_pixel_* functions, the expectation here is
+ * that the incoming data is not in a PBO.  With the XY_TEXT blit
+ * method, there's no benefit haveing it in a PBO, but we could
+ * implement a path based on XY_MONO_SRC_COPY_BLIT which might benefit
+ * PBO bitmaps.  I think they are probably pretty rare though - I
+ * wonder if Xgl uses them?
+ */
+static const GLubyte *map_pbo( struct gl_context *ctx,
+                              GLsizei width, GLsizei height,
+                              const struct gl_pixelstore_attrib *unpack,
+                              const GLubyte *bitmap )
+{
+   GLubyte *buf;
+
+   if (!_mesa_validate_pbo_access(2, unpack, width, height, 1,
+                                 GL_COLOR_INDEX, GL_BITMAP,
+                                 INT_MAX, (const GLvoid *) bitmap)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,"glBitmap(invalid PBO access)");
+      return NULL;
+   }
+
+   buf = (GLubyte *) ctx->Driver.MapBufferRange(ctx, 0, unpack->BufferObj->Size,
+                                               GL_MAP_READ_BIT,
+                                               unpack->BufferObj);
+   if (!buf) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)");
+      return NULL;
+   }
+
+   return ADD_POINTERS(buf, bitmap);
+}
+
+static bool test_bit( const GLubyte *src, GLuint bit )
+{
+   return (src[bit/8] & (1<<(bit % 8))) ? 1 : 0;
+}
+
+static void set_bit( GLubyte *dest, GLuint bit )
+{
+   dest[bit/8] |= 1 << (bit % 8);
+}
+
+/* Extract a rectangle's worth of data from the bitmap.  Called
+ * per chunk of HW-sized bitmap.
+ */
+static GLuint get_bitmap_rect(GLsizei width, GLsizei height,
+                             const struct gl_pixelstore_attrib *unpack,
+                             const GLubyte *bitmap,
+                             GLuint x, GLuint y, 
+                             GLuint w, GLuint h,
+                             GLubyte *dest,
+                             GLuint row_align,
+                             bool invert)
+{
+   GLuint src_offset = (x + unpack->SkipPixels) & 0x7;
+   GLuint mask = unpack->LsbFirst ? 0 : 7;
+   GLuint bit = 0;
+   GLint row, col;
+   GLint first, last;
+   GLint incr;
+   GLuint count = 0;
+
+   DBG("%s %d,%d %dx%d bitmap %dx%d skip %d src_offset %d mask %d\n",
+       __FUNCTION__, x,y,w,h,width,height,unpack->SkipPixels, src_offset, mask);
+
+   if (invert) {
+      first = h-1;
+      last = 0;
+      incr = -1;
+   }
+   else {
+      first = 0;
+      last = h-1;
+      incr = 1;
+   }
+
+   /* Require that dest be pre-zero'd.
+    */
+   for (row = first; row != (last+incr); row += incr) {
+      const GLubyte *rowsrc = _mesa_image_address2d(unpack, bitmap, 
+                                                   width, height, 
+                                                   GL_COLOR_INDEX, GL_BITMAP, 
+                                                   y + row, x);
+
+      for (col = 0; col < w; col++, bit++) {
+        if (test_bit(rowsrc, (col + src_offset) ^ mask)) {
+           set_bit(dest, bit ^ 7);
+           count++;
+        }
+      }
+
+      if (row_align)
+        bit = ALIGN(bit, row_align);
+   }
+
+   return count;
+}
+
+/**
+ * Returns the low Y value of the vertical range given, flipped according to
+ * whether the framebuffer is or not.
+ */
+static INLINE int
+y_flip(struct gl_framebuffer *fb, int y, int height)
+{
+   if (_mesa_is_user_fbo(fb))
+      return y;
+   else
+      return fb->Height - y - height;
+}
+
+/*
+ * Render a bitmap.
+ */
+static bool
+do_blit_bitmap( struct gl_context *ctx, 
+               GLint dstx, GLint dsty,
+               GLsizei width, GLsizei height,
+               const struct gl_pixelstore_attrib *unpack,
+               const GLubyte *bitmap )
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct gl_framebuffer *fb = ctx->DrawBuffer;
+   struct intel_renderbuffer *irb;
+   GLfloat tmpColor[4];
+   GLubyte ubcolor[4];
+   GLuint color;
+   GLsizei bitmap_width = width;
+   GLsizei bitmap_height = height;
+   GLint px, py;
+   GLuint stipple[32];
+   GLint orig_dstx = dstx;
+   GLint orig_dsty = dsty;
+
+   /* Update draw buffer bounds */
+   _mesa_update_state(ctx);
+
+   if (ctx->Depth.Test) {
+      /* The blit path produces incorrect results when depth testing is on.
+       * It seems the blit Z coord is always 1.0 (the far plane) so fragments
+       * will likely be obscured by other, closer geometry.
+       */
+      return false;
+   }
+
+   intel_prepare_render(intel);
+
+   if (fb->_NumColorDrawBuffers != 1) {
+      perf_debug("accelerated glBitmap() only supports rendering to a "
+                 "single color buffer\n");
+      return false;
+   }
+
+   irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
+
+   if (_mesa_is_bufferobj(unpack->BufferObj)) {
+      bitmap = map_pbo(ctx, width, height, unpack, bitmap);
+      if (bitmap == NULL)
+        return true;   /* even though this is an error, we're done */
+   }
+
+   COPY_4V(tmpColor, ctx->Current.RasterColor);
+
+   if (_mesa_need_secondary_color(ctx)) {
+       ADD_3V(tmpColor, tmpColor, ctx->Current.RasterSecondaryColor);
+   }
+
+   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[0], tmpColor[0]);
+   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[1], tmpColor[1]);
+   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[2], tmpColor[2]);
+   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[3], tmpColor[3]);
+
+   switch (irb->mt->format) {
+   case MESA_FORMAT_ARGB8888:
+   case MESA_FORMAT_XRGB8888:
+      color = PACK_COLOR_8888(ubcolor[3], ubcolor[0], ubcolor[1], ubcolor[2]);
+      break;
+   case MESA_FORMAT_RGB565:
+      color = PACK_COLOR_565(ubcolor[0], ubcolor[1], ubcolor[2]);
+      break;
+   default:
+      perf_debug("Unsupported format %s in accelerated glBitmap()\n",
+                 _mesa_get_format_name(irb->mt->format));
+      return false;
+   }
+
+   if (!intel_check_blit_fragment_ops(ctx, tmpColor[3] == 1.0F))
+      return false;
+
+   /* Clip to buffer bounds and scissor. */
+   if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin,
+                            fb->_Xmax, fb->_Ymax,
+                            &dstx, &dsty, &width, &height))
+      goto out;
+
+   dsty = y_flip(fb, dsty, height);
+
+#define DY 32
+#define DX 32
+
+   /* The blitter has no idea about fast color clears, so we need to resolve
+    * the miptree before we do anything.
+    */
+   intel_miptree_resolve_color(intel, irb->mt);
+
+   /* Chop it all into chunks that can be digested by hardware: */
+   for (py = 0; py < height; py += DY) {
+      for (px = 0; px < width; px += DX) {
+        int h = MIN2(DY, height - py);
+        int w = MIN2(DX, width - px);
+        GLuint sz = ALIGN(ALIGN(w,8) * h, 64)/8;
+        GLenum logic_op = ctx->Color.ColorLogicOpEnabled ?
+           ctx->Color.LogicOp : GL_COPY;
+
+        assert(sz <= sizeof(stipple));
+        memset(stipple, 0, sz);
+
+        /* May need to adjust this when padding has been introduced in
+         * sz above:
+         *
+         * Have to translate destination coordinates back into source
+         * coordinates.
+         */
+         int count = get_bitmap_rect(bitmap_width, bitmap_height, unpack,
+                                     bitmap,
+                                     -orig_dstx + (dstx + px),
+                                     -orig_dsty + y_flip(fb, dsty + py, h),
+                                     w, h,
+                                     (GLubyte *)stipple,
+                                     8,
+                                     _mesa_is_winsys_fbo(fb));
+         if (count == 0)
+           continue;
+
+        if (!intelEmitImmediateColorExpandBlit(intel,
+                                               irb->mt->cpp,
+                                               (GLubyte *)stipple,
+                                               sz,
+                                               color,
+                                               irb->mt->region->pitch,
+                                               irb->mt->region->bo,
+                                               0,
+                                               irb->mt->region->tiling,
+                                               dstx + px,
+                                               dsty + py,
+                                               w, h,
+                                               logic_op)) {
+           return false;
+        }
+
+         if (ctx->Query.CurrentOcclusionObject)
+            ctx->Query.CurrentOcclusionObject->Result += count;
+      }
+   }
+out:
+
+   if (unlikely(INTEL_DEBUG & DEBUG_SYNC))
+      intel_batchbuffer_flush(intel);
+
+   if (_mesa_is_bufferobj(unpack->BufferObj)) {
+      /* done with PBO so unmap it now */
+      ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj);
+   }
+
+   intel_check_front_buffer_rendering(intel);
+
+   return true;
+}
+
+
+/* There are a large number of possible ways to implement bitmap on
+ * this hardware, most of them have some sort of drawback.  Here are a
+ * few that spring to mind:
+ * 
+ * Blit:
+ *    - XY_MONO_SRC_BLT_CMD
+ *         - use XY_SETUP_CLIP_BLT for cliprect clipping.
+ *    - XY_TEXT_BLT
+ *    - XY_TEXT_IMMEDIATE_BLT
+ *         - blit per cliprect, subject to maximum immediate data size.
+ *    - XY_COLOR_BLT 
+ *         - per pixel or run of pixels
+ *    - XY_PIXEL_BLT
+ *         - good for sparse bitmaps
+ *
+ * 3D engine:
+ *    - Point per pixel
+ *    - Translate bitmap to an alpha texture and render as a quad
+ *    - Chop bitmap up into 32x32 squares and render w/polygon stipple.
+ */
+void
+intelBitmap(struct gl_context * ctx,
+           GLint x, GLint y,
+           GLsizei width, GLsizei height,
+           const struct gl_pixelstore_attrib *unpack,
+           const GLubyte * pixels)
+{
+   if (!_mesa_check_conditional_render(ctx))
+      return;
+
+   if (do_blit_bitmap(ctx, x, y, width, height,
+                          unpack, pixels))
+      return;
+
+   _mesa_meta_Bitmap(ctx, x, y, width, height, unpack, pixels);
+}
deleted file mode 120000 (symlink)
index ee433605904902ff085b72bc2fb82e107820fb02..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_pixel_copy.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..ba8e06f1f955e5647e5e27d2ee11cc07478b4e6c
--- /dev/null
@@ -0,0 +1,210 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#include "main/glheader.h"
+#include "main/image.h"
+#include "main/state.h"
+#include "main/mtypes.h"
+#include "main/condrender.h"
+#include "main/fbobject.h"
+#include "drivers/common/meta.h"
+
+#include "intel_context.h"
+#include "intel_buffers.h"
+#include "intel_mipmap_tree.h"
+#include "intel_regions.h"
+#include "intel_pixel.h"
+#include "intel_fbo.h"
+#include "intel_blit.h"
+
+#define FILE_DEBUG_FLAG DEBUG_PIXEL
+
+/**
+ * CopyPixels with the blitter.  Don't support zooming, pixel transfer, etc.
+ */
+static bool
+do_blit_copypixels(struct gl_context * ctx,
+                   GLint srcx, GLint srcy,
+                   GLsizei width, GLsizei height,
+                   GLint dstx, GLint dsty, GLenum type)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct gl_framebuffer *fb = ctx->DrawBuffer;
+   struct gl_framebuffer *read_fb = ctx->ReadBuffer;
+   GLint orig_dstx;
+   GLint orig_dsty;
+   GLint orig_srcx;
+   GLint orig_srcy;
+   struct intel_renderbuffer *draw_irb = NULL;
+   struct intel_renderbuffer *read_irb = NULL;
+
+   /* Update draw buffer bounds */
+   _mesa_update_state(ctx);
+
+   switch (type) {
+   case GL_COLOR:
+      if (fb->_NumColorDrawBuffers != 1) {
+        perf_debug("glCopyPixels() fallback: MRT\n");
+        return false;
+      }
+
+      draw_irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
+      read_irb = intel_renderbuffer(read_fb->_ColorReadBuffer);
+      break;
+   case GL_DEPTH_STENCIL_EXT:
+      draw_irb = intel_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer);
+      read_irb =
+        intel_renderbuffer(read_fb->Attachment[BUFFER_DEPTH].Renderbuffer);
+      break;
+   case GL_DEPTH:
+      perf_debug("glCopyPixels() fallback: GL_DEPTH\n");
+      return false;
+   case GL_STENCIL:
+      perf_debug("glCopyPixels() fallback: GL_STENCIL\n");
+      return false;
+   default:
+      perf_debug("glCopyPixels(): Unknown type\n");
+      return false;
+   }
+
+   if (!draw_irb) {
+      perf_debug("glCopyPixels() fallback: missing draw buffer\n");
+      return false;
+   }
+
+   if (!read_irb) {
+      perf_debug("glCopyPixels() fallback: missing read buffer\n");
+      return false;
+   }
+
+   if (ctx->_ImageTransferState) {
+      perf_debug("glCopyPixels(): Unsupported image transfer state\n");
+      return false;
+   }
+
+   if (ctx->Depth.Test) {
+      perf_debug("glCopyPixels(): Unsupported depth test state\n");
+      return false;
+   }
+
+   if (ctx->Stencil._Enabled) {
+      perf_debug("glCopyPixels(): Unsupported stencil test state\n");
+      return false;
+   }
+
+   if (ctx->Fog.Enabled ||
+       ctx->Texture._EnabledUnits ||
+       ctx->FragmentProgram._Enabled) {
+      perf_debug("glCopyPixels(): Unsupported fragment shader state\n");
+      return false;
+   }
+
+   if (ctx->Color.AlphaEnabled ||
+       ctx->Color.BlendEnabled) {
+      perf_debug("glCopyPixels(): Unsupported blend state\n");
+      return false;
+   }
+
+   if (!ctx->Color.ColorMask[0][0] ||
+       !ctx->Color.ColorMask[0][1] ||
+       !ctx->Color.ColorMask[0][2] ||
+       !ctx->Color.ColorMask[0][3]) {
+      perf_debug("glCopyPixels(): Unsupported color mask state\n");
+      return false;
+   }
+
+   if (ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F) {
+      perf_debug("glCopyPixles(): Unsupported pixel zoom\n");
+      return false;
+   }
+
+   intel_prepare_render(intel);
+
+   intel_flush(&intel->ctx);
+
+   /* Clip to destination buffer. */
+   orig_dstx = dstx;
+   orig_dsty = dsty;
+   if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin,
+                            fb->_Xmax, fb->_Ymax,
+                            &dstx, &dsty, &width, &height))
+      goto out;
+   /* Adjust src coords for our post-clipped destination origin */
+   srcx += dstx - orig_dstx;
+   srcy += dsty - orig_dsty;
+
+   /* Clip to source buffer. */
+   orig_srcx = srcx;
+   orig_srcy = srcy;
+   if (!_mesa_clip_to_region(0, 0,
+                            read_fb->Width, read_fb->Height,
+                            &srcx, &srcy, &width, &height))
+      goto out;
+   /* Adjust dst coords for our post-clipped source origin */
+   dstx += srcx - orig_srcx;
+   dsty += srcy - orig_srcy;
+
+   if (!intel_miptree_blit(intel,
+                           read_irb->mt, read_irb->mt_level, read_irb->mt_layer,
+                           srcx, srcy, _mesa_is_winsys_fbo(read_fb),
+                           draw_irb->mt, draw_irb->mt_level, draw_irb->mt_layer,
+                           dstx, dsty, _mesa_is_winsys_fbo(fb),
+                           width, height,
+                           (ctx->Color.ColorLogicOpEnabled ?
+                            ctx->Color.LogicOp : GL_COPY))) {
+      DBG("%s: blit failure\n", __FUNCTION__);
+      return false;
+   }
+
+   if (ctx->Query.CurrentOcclusionObject)
+      ctx->Query.CurrentOcclusionObject->Result += width * height;
+
+out:
+   intel_check_front_buffer_rendering(intel);
+
+   DBG("%s: success\n", __FUNCTION__);
+   return true;
+}
+
+
+void
+intelCopyPixels(struct gl_context * ctx,
+                GLint srcx, GLint srcy,
+                GLsizei width, GLsizei height,
+                GLint destx, GLint desty, GLenum type)
+{
+   DBG("%s\n", __FUNCTION__);
+
+   if (!_mesa_check_conditional_render(ctx))
+      return;
+
+   if (do_blit_copypixels(ctx, srcx, srcy, width, height, destx, desty, type))
+      return;
+
+   /* this will use swrast if needed */
+   _mesa_meta_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type);
+}
deleted file mode 120000 (symlink)
index 8431a24edfcefe2bdde1d7606882ba22915de30f..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_pixel_draw.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..2ec7ed8e269062e69a77e565754e16fade99519f
--- /dev/null
@@ -0,0 +1,58 @@
+/**************************************************************************
+ * 
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portionsalloc
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#include "main/glheader.h"
+#include "main/enums.h"
+#include "main/image.h"
+#include "main/mtypes.h"
+#include "main/teximage.h"
+#include "main/texobj.h"
+#include "main/texstate.h"
+#include "swrast/swrast.h"
+#include "drivers/common/meta.h"
+
+#include "intel_context.h"
+#include "intel_pixel.h"
+
+void
+intelDrawPixels(struct gl_context * ctx,
+                GLint x, GLint y,
+                GLsizei width, GLsizei height,
+                GLenum format,
+                GLenum type,
+                const struct gl_pixelstore_attrib *unpack,
+                const GLvoid * pixels)
+{
+   if (format == GL_STENCIL_INDEX) {
+      _swrast_DrawPixels(ctx, x, y, width, height, format, type,
+                         unpack, pixels);
+      return;
+   }
+
+   _mesa_meta_DrawPixels(ctx, x, y, width, height, format, type,
+                         unpack, pixels);
+}
deleted file mode 120000 (symlink)
index cc4589f4d42ae631a07ff17e34a5d9846b1d821a..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_pixel_read.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..26eb4965b8dca2cb6e76550e4856c17139c47ef9
--- /dev/null
@@ -0,0 +1,202 @@
+/**************************************************************************
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "main/glheader.h"
+#include "main/enums.h"
+#include "main/mtypes.h"
+#include "main/macros.h"
+#include "main/fbobject.h"
+#include "main/image.h"
+#include "main/bufferobj.h"
+#include "main/readpix.h"
+#include "main/state.h"
+
+#include "intel_screen.h"
+#include "intel_context.h"
+#include "intel_blit.h"
+#include "intel_buffers.h"
+#include "intel_fbo.h"
+#include "intel_mipmap_tree.h"
+#include "intel_regions.h"
+#include "intel_pixel.h"
+#include "intel_buffer_objects.h"
+
+#define FILE_DEBUG_FLAG DEBUG_PIXEL
+
+/* For many applications, the new ability to pull the source buffers
+ * back out of the GTT and then do the packing/conversion operations
+ * in software will be as much of an improvement as trying to get the
+ * blitter and/or texture engine to do the work.
+ *
+ * This step is gated on private backbuffers.
+ *
+ * Obviously the frontbuffer can't be pulled back, so that is either
+ * an argument for blit/texture readpixels, or for blitting to a
+ * temporary and then pulling that back.
+ *
+ * When the destination is a pbo, however, it's not clear if it is
+ * ever going to be pulled to main memory (though the access param
+ * will be a good hint).  So it sounds like we do want to be able to
+ * choose between blit/texture implementation on the gpu and pullback
+ * and cpu-based copying.
+ *
+ * Unless you can magically turn client memory into a PBO for the
+ * duration of this call, there will be a cpu-based copying step in
+ * any case.
+ */
+
+static bool
+do_blit_readpixels(struct gl_context * ctx,
+                   GLint x, GLint y, GLsizei width, GLsizei height,
+                   GLenum format, GLenum type,
+                   const struct gl_pixelstore_attrib *pack, GLvoid * pixels)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj);
+   GLuint dst_offset;
+   drm_intel_bo *dst_buffer;
+   bool all;
+   GLint dst_x, dst_y;
+   GLuint dirty;
+
+   DBG("%s\n", __FUNCTION__);
+
+   assert(_mesa_is_bufferobj(pack->BufferObj));
+
+   struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
+   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+
+   if (ctx->_ImageTransferState ||
+       !_mesa_format_matches_format_and_type(irb->mt->format, format, type,
+                                             false)) {
+      DBG("%s - bad format for blit\n", __FUNCTION__);
+      return false;
+   }
+
+   if (pack->SwapBytes || pack->LsbFirst) {
+      DBG("%s: bad packing params\n", __FUNCTION__);
+      return false;
+   }
+
+   int dst_stride = _mesa_image_row_stride(pack, width, format, type);
+   bool dst_flip = false;
+   /* Mesa flips the dst_stride for pack->Invert, but we want our mt to have a
+    * normal dst_stride.
+    */
+   if (pack->Invert) {
+      dst_stride = -dst_stride;
+      dst_flip = true;
+   }
+
+   dst_offset = (GLintptr)pixels;
+   dst_offset += _mesa_image_offset(2, pack, width, height,
+                                   format, type, 0, 0, 0);
+
+   if (!_mesa_clip_copytexsubimage(ctx,
+                                  &dst_x, &dst_y,
+                                  &x, &y,
+                                  &width, &height)) {
+      return true;
+   }
+
+   dirty = intel->front_buffer_dirty;
+   intel_prepare_render(intel);
+   intel->front_buffer_dirty = dirty;
+
+   all = (width * height * irb->mt->cpp == dst->Base.Size &&
+         x == 0 && dst_offset == 0);
+
+   dst_buffer = intel_bufferobj_buffer(intel, dst,
+                                      all ? INTEL_WRITE_FULL :
+                                      INTEL_WRITE_PART);
+
+   struct intel_mipmap_tree *pbo_mt =
+      intel_miptree_create_for_bo(intel,
+                                  dst_buffer,
+                                  irb->mt->format,
+                                  dst_offset,
+                                  width, height,
+                                  dst_stride, I915_TILING_NONE);
+
+   if (!intel_miptree_blit(intel,
+                           irb->mt, irb->mt_level, irb->mt_layer,
+                           x, y, _mesa_is_winsys_fbo(ctx->ReadBuffer),
+                           pbo_mt, 0, 0,
+                           0, 0, dst_flip,
+                           width, height, GL_COPY)) {
+      return false;
+   }
+
+   intel_miptree_release(&pbo_mt);
+
+   DBG("%s - DONE\n", __FUNCTION__);
+
+   return true;
+}
+
+void
+intelReadPixels(struct gl_context * ctx,
+                GLint x, GLint y, GLsizei width, GLsizei height,
+                GLenum format, GLenum type,
+                const struct gl_pixelstore_attrib *pack, GLvoid * pixels)
+{
+   struct intel_context *intel = intel_context(ctx);
+   bool dirty;
+
+   intel_flush_rendering_to_batch(ctx);
+
+   DBG("%s\n", __FUNCTION__);
+
+   if (_mesa_is_bufferobj(pack->BufferObj)) {
+      /* Using PBOs, so try the BLT based path. */
+      if (do_blit_readpixels(ctx, x, y, width, height, format, type, pack,
+                             pixels)) {
+         return;
+      }
+
+      perf_debug("%s: fallback to CPU mapping in PBO case\n", __FUNCTION__);
+   }
+
+   /* glReadPixels() wont dirty the front buffer, so reset the dirty
+    * flag after calling intel_prepare_render(). */
+   dirty = intel->front_buffer_dirty;
+   intel_prepare_render(intel);
+   intel->front_buffer_dirty = dirty;
+
+   /* Update Mesa state before calling _mesa_readpixels().
+    * XXX this may not be needed since ReadPixels no longer uses the
+    * span code.
+    */
+
+   if (ctx->NewState)
+      _mesa_update_state(ctx);
+
+   _mesa_readpixels(ctx, x, y, width, height, format, type, pack, pixels);
+
+   /* There's an intel_prepare_render() call in intelSpanRenderStart(). */
+   intel->front_buffer_dirty = dirty;
+}
deleted file mode 120000 (symlink)
index 89b2f15c10f04dac958fd90355dc7f7cb84f58dd..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_regions.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..44f7030c712f4cc5a6d285709d3afc59f0c9f012
--- /dev/null
@@ -0,0 +1,353 @@
+/**************************************************************************
+ * 
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Provide additional functionality on top of bufmgr buffers:
+ *   - 2d semantics and blit operations
+ *   - refcounting of buffers for multiple images in a buffer.
+ *   - refcounting of buffer mappings.
+ *   - some logic for moving the buffers to the best memory pools for
+ *     given operations.
+ *
+ * Most of this is to make it easier to implement the fixed-layout
+ * mipmap tree required by intel hardware in the face of GL's
+ * programming interface where each image can be specifed in random
+ * order and it isn't clear what layout the tree should have until the
+ * last moment.
+ */
+
+#include <sys/ioctl.h>
+#include <errno.h>
+
+#include "main/hash.h"
+#include "intel_context.h"
+#include "intel_regions.h"
+#include "intel_blit.h"
+#include "intel_buffer_objects.h"
+#include "intel_bufmgr.h"
+#include "intel_batchbuffer.h"
+
+#define FILE_DEBUG_FLAG DEBUG_REGION
+
+/* This should be set to the maximum backtrace size desired.
+ * Set it to 0 to disable backtrace debugging.
+ */
+#define DEBUG_BACKTRACE_SIZE 0
+
+#if DEBUG_BACKTRACE_SIZE == 0
+/* Use the standard debug output */
+#define _DBG(...) DBG(__VA_ARGS__)
+#else
+/* Use backtracing debug output */
+#define _DBG(...) {debug_backtrace(); DBG(__VA_ARGS__);}
+
+/* Backtracing debug support */
+#include <execinfo.h>
+
+static void
+debug_backtrace(void)
+{
+   void *trace[DEBUG_BACKTRACE_SIZE];
+   char **strings = NULL;
+   int traceSize;
+   register int i;
+
+   traceSize = backtrace(trace, DEBUG_BACKTRACE_SIZE);
+   strings = backtrace_symbols(trace, traceSize);
+   if (strings == NULL) {
+      DBG("no backtrace:");
+      return;
+   }
+
+   /* Spit out all the strings with a colon separator.  Ignore
+    * the first, since we don't really care about the call
+    * to debug_backtrace() itself.  Skip until the final "/" in
+    * the trace to avoid really long lines.
+    */
+   for (i = 1; i < traceSize; i++) {
+      char *p = strings[i], *slash = strings[i];
+      while (*p) {
+         if (*p++ == '/') {
+            slash = p;
+         }
+      }
+
+      DBG("%s:", slash);
+   }
+
+   /* Free up the memory, and we're done */
+   free(strings);
+}
+
+#endif
+
+static struct intel_region *
+intel_region_alloc_internal(struct intel_screen *screen,
+                           GLuint cpp,
+                           GLuint width, GLuint height, GLuint pitch,
+                           uint32_t tiling, drm_intel_bo *buffer)
+{
+   struct intel_region *region;
+
+   region = calloc(sizeof(*region), 1);
+   if (region == NULL)
+      return region;
+
+   region->cpp = cpp;
+   region->width = width;
+   region->height = height;
+   region->pitch = pitch;
+   region->refcount = 1;
+   region->bo = buffer;
+   region->tiling = tiling;
+
+   _DBG("%s <-- %p\n", __FUNCTION__, region);
+   return region;
+}
+
+struct intel_region *
+intel_region_alloc(struct intel_screen *screen,
+                  uint32_t tiling,
+                   GLuint cpp, GLuint width, GLuint height,
+                  bool expect_accelerated_upload)
+{
+   drm_intel_bo *buffer;
+   unsigned long flags = 0;
+   unsigned long aligned_pitch;
+   struct intel_region *region;
+
+   if (expect_accelerated_upload)
+      flags |= BO_ALLOC_FOR_RENDER;
+
+   buffer = drm_intel_bo_alloc_tiled(screen->bufmgr, "region",
+                                    width, height, cpp,
+                                    &tiling, &aligned_pitch, flags);
+   if (buffer == NULL)
+      return NULL;
+
+   region = intel_region_alloc_internal(screen, cpp, width, height,
+                                        aligned_pitch, tiling, buffer);
+   if (region == NULL) {
+      drm_intel_bo_unreference(buffer);
+      return NULL;
+   }
+
+   return region;
+}
+
+bool
+intel_region_flink(struct intel_region *region, uint32_t *name)
+{
+   if (region->name == 0) {
+      if (drm_intel_bo_flink(region->bo, &region->name))
+        return false;
+   }
+
+   *name = region->name;
+
+   return true;
+}
+
+struct intel_region *
+intel_region_alloc_for_handle(struct intel_screen *screen,
+                             GLuint cpp,
+                             GLuint width, GLuint height, GLuint pitch,
+                             GLuint handle, const char *name)
+{
+   struct intel_region *region;
+   drm_intel_bo *buffer;
+   int ret;
+   uint32_t bit_6_swizzle, tiling;
+
+   buffer = intel_bo_gem_create_from_name(screen->bufmgr, name, handle);
+   if (buffer == NULL)
+      return NULL;
+   ret = drm_intel_bo_get_tiling(buffer, &tiling, &bit_6_swizzle);
+   if (ret != 0) {
+      fprintf(stderr, "Couldn't get tiling of buffer %d (%s): %s\n",
+             handle, name, strerror(-ret));
+      drm_intel_bo_unreference(buffer);
+      return NULL;
+   }
+
+   region = intel_region_alloc_internal(screen, cpp,
+                                       width, height, pitch, tiling, buffer);
+   if (region == NULL) {
+      drm_intel_bo_unreference(buffer);
+      return NULL;
+   }
+
+   region->name = handle;
+
+   return region;
+}
+
+struct intel_region *
+intel_region_alloc_for_fd(struct intel_screen *screen,
+                          GLuint cpp,
+                          GLuint width, GLuint height, GLuint pitch,
+                          int fd, const char *name)
+{
+   struct intel_region *region;
+   drm_intel_bo *buffer;
+   int ret;
+   uint32_t bit_6_swizzle, tiling;
+
+   buffer = drm_intel_bo_gem_create_from_prime(screen->bufmgr,
+                                               fd, height * pitch);
+   if (buffer == NULL)
+      return NULL;
+   ret = drm_intel_bo_get_tiling(buffer, &tiling, &bit_6_swizzle);
+   if (ret != 0) {
+      fprintf(stderr, "Couldn't get tiling of buffer (%s): %s\n",
+             name, strerror(-ret));
+      drm_intel_bo_unreference(buffer);
+      return NULL;
+   }
+
+   region = intel_region_alloc_internal(screen, cpp,
+                                       width, height, pitch, tiling, buffer);
+   if (region == NULL) {
+      drm_intel_bo_unreference(buffer);
+      return NULL;
+   }
+
+   return region;
+}
+
+void
+intel_region_reference(struct intel_region **dst, struct intel_region *src)
+{
+   _DBG("%s: %p(%d) -> %p(%d)\n", __FUNCTION__,
+       *dst, *dst ? (*dst)->refcount : 0, src, src ? src->refcount : 0);
+
+   if (src != *dst) {
+      if (*dst)
+        intel_region_release(dst);
+
+      if (src)
+         src->refcount++;
+      *dst = src;
+   }
+}
+
+void
+intel_region_release(struct intel_region **region_handle)
+{
+   struct intel_region *region = *region_handle;
+
+   if (region == NULL) {
+      _DBG("%s NULL\n", __FUNCTION__);
+      return;
+   }
+
+   _DBG("%s %p %d\n", __FUNCTION__, region, region->refcount - 1);
+
+   ASSERT(region->refcount > 0);
+   region->refcount--;
+
+   if (region->refcount == 0) {
+      drm_intel_bo_unreference(region->bo);
+
+      free(region);
+   }
+   *region_handle = NULL;
+}
+
+/**
+ * This function computes masks that may be used to select the bits of the X
+ * and Y coordinates that indicate the offset within a tile.  If the region is
+ * untiled, the masks are set to 0.
+ */
+void
+intel_region_get_tile_masks(struct intel_region *region,
+                            uint32_t *mask_x, uint32_t *mask_y,
+                            bool map_stencil_as_y_tiled)
+{
+   int cpp = region->cpp;
+   uint32_t tiling = region->tiling;
+
+   if (map_stencil_as_y_tiled)
+      tiling = I915_TILING_Y;
+
+   switch (tiling) {
+   default:
+      assert(false);
+   case I915_TILING_NONE:
+      *mask_x = *mask_y = 0;
+      break;
+   case I915_TILING_X:
+      *mask_x = 512 / cpp - 1;
+      *mask_y = 7;
+      break;
+   case I915_TILING_Y:
+      *mask_x = 128 / cpp - 1;
+      *mask_y = 31;
+      break;
+   }
+}
+
+/**
+ * Compute the offset (in bytes) from the start of the region to the given x
+ * and y coordinate.  For tiled regions, caller must ensure that x and y are
+ * multiples of the tile size.
+ */
+uint32_t
+intel_region_get_aligned_offset(struct intel_region *region, uint32_t x,
+                                uint32_t y, bool map_stencil_as_y_tiled)
+{
+   int cpp = region->cpp;
+   uint32_t pitch = region->pitch;
+   uint32_t tiling = region->tiling;
+
+   if (map_stencil_as_y_tiled) {
+      tiling = I915_TILING_Y;
+
+      /* When mapping a W-tiled stencil buffer as Y-tiled, each 64-high W-tile
+       * gets transformed into a 32-high Y-tile.  Accordingly, the pitch of
+       * the resulting region is twice the pitch of the original region, since
+       * each row in the Y-tiled view corresponds to two rows in the actual
+       * W-tiled surface.  So we need to correct the pitch before computing
+       * the offsets.
+       */
+      pitch *= 2;
+   }
+
+   switch (tiling) {
+   default:
+      assert(false);
+   case I915_TILING_NONE:
+      return y * pitch + x * cpp;
+   case I915_TILING_X:
+      assert((x % (512 / cpp)) == 0);
+      assert((y % 8) == 0);
+      return y * pitch + x / (512 / cpp) * 4096;
+   case I915_TILING_Y:
+      assert((x % (128 / cpp)) == 0);
+      assert((y % 32) == 0);
+      return y * pitch + x / (128 / cpp) * 4096;
+   }
+}
deleted file mode 120000 (symlink)
index 77e50fbaea488046295b5728872353d582113420..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_resolve_map.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..04b5c9424323953fec307e5204b41bfc339c5cf5
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright Â© 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "intel_resolve_map.h"
+
+#include <assert.h>
+#include <stdlib.h>
+
+/**
+ * \brief Set that the miptree slice at (level, layer) needs a resolve.
+ *
+ * If a map element already exists with the given key, then the value is
+ * changed to the given value of \c need.
+ */
+void
+intel_resolve_map_set(struct intel_resolve_map *head,
+                     uint32_t level,
+                     uint32_t layer,
+                     enum gen6_hiz_op need)
+{
+   struct intel_resolve_map **tail = &head->next;
+   struct intel_resolve_map *prev = head;
+
+   while (*tail) {
+      if ((*tail)->level == level && (*tail)->layer == layer) {
+         (*tail)->need = need;
+        return;
+      }
+      prev = *tail;
+      tail = &(*tail)->next;
+   }
+
+   *tail = malloc(sizeof(**tail));
+   (*tail)->prev = prev;
+   (*tail)->next = NULL;
+   (*tail)->level = level;
+   (*tail)->layer = layer;
+   (*tail)->need = need;
+}
+
+/**
+ * \brief Get an element from the map.
+ * \return null if element is not contained in map.
+ */
+struct intel_resolve_map*
+intel_resolve_map_get(struct intel_resolve_map *head,
+                     uint32_t level,
+                     uint32_t layer)
+{
+   struct intel_resolve_map *item = head->next;
+
+   while (item) {
+      if (item->level == level && item->layer == layer)
+        break;
+      else
+        item = item->next;
+   }
+
+   return item;
+}
+
+/**
+ * \brief Remove and free an element from the map.
+ */
+void
+intel_resolve_map_remove(struct intel_resolve_map *elem)
+{
+   if (elem->prev)
+      elem->prev->next = elem->next;
+   if (elem->next)
+      elem->next->prev = elem->prev;
+   free(elem);
+}
+
+/**
+ * \brief Remove and free all elements of the map.
+ */
+void
+intel_resolve_map_clear(struct intel_resolve_map *head)
+{
+   struct intel_resolve_map *next = head->next;
+   struct intel_resolve_map *trash;
+
+   while (next) {
+      trash = next;
+      next = next->next;
+      free(trash);
+   }
+
+   head->next = NULL;
+}
deleted file mode 120000 (symlink)
index f2db48272b935d7a584fcba8fff2ab90198a8403..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_screen.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..60a69a60648c38ad36f926b89420c424c1586d2d
--- /dev/null
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#include <errno.h>
+#include <time.h>
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/framebuffer.h"
+#include "main/renderbuffer.h"
+#include "main/texobj.h"
+#include "main/hash.h"
+#include "main/fbobject.h"
+#include "main/version.h"
+#include "swrast/s_renderbuffer.h"
+
+#include "utils.h"
+#include "xmlpool.h"
+
+PUBLIC const char __driConfigOptions[] =
+   DRI_CONF_BEGIN
+   DRI_CONF_SECTION_PERFORMANCE
+      DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_ALWAYS_SYNC)
+      /* Options correspond to DRI_CONF_BO_REUSE_DISABLED,
+       * DRI_CONF_BO_REUSE_ALL
+       */
+      DRI_CONF_OPT_BEGIN_V(bo_reuse, enum, 1, "0:1")
+        DRI_CONF_DESC_BEGIN(en, "Buffer object reuse")
+           DRI_CONF_ENUM(0, "Disable buffer object reuse")
+           DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects")
+        DRI_CONF_DESC_END
+      DRI_CONF_OPT_END
+
+      DRI_CONF_OPT_BEGIN_B(hiz, "true")
+        DRI_CONF_DESC(en, "Enable Hierarchical Z on gen6+")
+      DRI_CONF_OPT_END
+
+      DRI_CONF_OPT_BEGIN_B(early_z, "false")
+        DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).")
+      DRI_CONF_OPT_END
+
+   DRI_CONF_SECTION_END
+   DRI_CONF_SECTION_QUALITY
+      DRI_CONF_FORCE_S3TC_ENABLE("false")
+      DRI_CONF_ALLOW_LARGE_TEXTURES(2)
+   DRI_CONF_SECTION_END
+   DRI_CONF_SECTION_DEBUG
+      DRI_CONF_NO_RAST("false")
+      DRI_CONF_ALWAYS_FLUSH_BATCH("false")
+      DRI_CONF_ALWAYS_FLUSH_CACHE("false")
+      DRI_CONF_DISABLE_THROTTLING("false")
+      DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN("false")
+      DRI_CONF_DISABLE_GLSL_LINE_CONTINUATIONS("false")
+      DRI_CONF_DISABLE_BLEND_FUNC_EXTENDED("false")
+
+      DRI_CONF_OPT_BEGIN_B(shader_precompile, "true")
+        DRI_CONF_DESC(en, "Perform code generation at shader link time.")
+      DRI_CONF_OPT_END
+   DRI_CONF_SECTION_END
+DRI_CONF_END;
+
+const GLuint __driNConfigOptions = 14;
+
+#include "intel_batchbuffer.h"
+#include "intel_buffers.h"
+#include "intel_bufmgr.h"
+#include "intel_chipset.h"
+#include "intel_fbo.h"
+#include "intel_mipmap_tree.h"
+#include "intel_screen.h"
+#include "intel_tex.h"
+#include "intel_regions.h"
+
+#ifndef I915
+#include "brw_context.h"
+#endif
+
+#include "i915_drm.h"
+
+#ifdef USE_NEW_INTERFACE
+static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
+#endif /*USE_NEW_INTERFACE */
+
+/**
+ * For debugging purposes, this returns a time in seconds.
+ */
+double
+get_time(void)
+{
+   struct timespec tp;
+
+   clock_gettime(CLOCK_MONOTONIC, &tp);
+
+   return tp.tv_sec + tp.tv_nsec / 1000000000.0;
+}
+
+void
+aub_dump_bmp(struct gl_context *ctx)
+{
+   struct gl_framebuffer *fb = ctx->DrawBuffer;
+
+   for (int i = 0; i < fb->_NumColorDrawBuffers; i++) {
+      struct intel_renderbuffer *irb =
+        intel_renderbuffer(fb->_ColorDrawBuffers[i]);
+
+      if (irb && irb->mt) {
+        enum aub_dump_bmp_format format;
+
+        switch (irb->Base.Base.Format) {
+        case MESA_FORMAT_ARGB8888:
+        case MESA_FORMAT_XRGB8888:
+           format = AUB_DUMP_BMP_FORMAT_ARGB_8888;
+           break;
+        default:
+           continue;
+        }
+
+         assert(irb->mt->region->pitch % irb->mt->region->cpp == 0);
+        drm_intel_gem_bo_aub_dump_bmp(irb->mt->region->bo,
+                                      irb->draw_x,
+                                      irb->draw_y,
+                                      irb->Base.Base.Width,
+                                      irb->Base.Base.Height,
+                                      format,
+                                      irb->mt->region->pitch,
+                                      0);
+      }
+   }
+}
+
+static const __DRItexBufferExtension intelTexBufferExtension = {
+   .base = { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+
+   .setTexBuffer        = intelSetTexBuffer,
+   .setTexBuffer2       = intelSetTexBuffer2,
+   .releaseTexBuffer    = NULL,
+};
+
+static void
+intelDRI2Flush(__DRIdrawable *drawable)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct intel_context *intel = intel_context(ctx);
+   if (intel == NULL)
+      return;
+
+   if (intel->gen < 4)
+      INTEL_FIREVERTICES(intel);
+
+   intel_resolve_for_dri2_flush(intel, drawable);
+   intel->need_throttle = true;
+
+   if (intel->batch.used)
+      intel_batchbuffer_flush(intel);
+
+   if (INTEL_DEBUG & DEBUG_AUB) {
+      aub_dump_bmp(ctx);
+   }
+}
+
+static const struct __DRI2flushExtensionRec intelFlushExtension = {
+    .base = { __DRI2_FLUSH, 3 },
+
+    .flush              = intelDRI2Flush,
+    .invalidate         = dri2InvalidateDrawable,
+};
+
+static struct intel_image_format intel_image_formats[] = {
+   { __DRI_IMAGE_FOURCC_ARGB8888, __DRI_IMAGE_COMPONENTS_RGBA, 1,
+     { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } },
+
+   { __DRI_IMAGE_FOURCC_XRGB8888, __DRI_IMAGE_COMPONENTS_RGB, 1,
+     { { 0, 0, 0, __DRI_IMAGE_FORMAT_XRGB8888, 4 }, } },
+
+   { __DRI_IMAGE_FOURCC_YUV410, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
+     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+       { 1, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 },
+       { 2, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 } } },
+
+   { __DRI_IMAGE_FOURCC_YUV411, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
+     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+       { 1, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+       { 2, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
+
+   { __DRI_IMAGE_FOURCC_YUV420, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
+     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+       { 1, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 },
+       { 2, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 } } },
+
+   { __DRI_IMAGE_FOURCC_YUV422, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
+     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+       { 1, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+       { 2, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
+
+   { __DRI_IMAGE_FOURCC_YUV444, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
+     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+       { 1, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+       { 2, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
+
+   { __DRI_IMAGE_FOURCC_NV12, __DRI_IMAGE_COMPONENTS_Y_UV, 2,
+     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+       { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88, 2 } } },
+
+   { __DRI_IMAGE_FOURCC_NV16, __DRI_IMAGE_COMPONENTS_Y_UV, 2,
+     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
+       { 1, 1, 0, __DRI_IMAGE_FORMAT_GR88, 2 } } },
+
+   /* For YUYV buffers, we set up two overlapping DRI images and treat
+    * them as planar buffers in the compositors.  Plane 0 is GR88 and
+    * samples YU or YV pairs and places Y into the R component, while
+    * plane 1 is ARGB and samples YUYV clusters and places pairs and
+    * places U into the G component and V into A.  This lets the
+    * texture sampler interpolate the Y components correctly when
+    * sampling from plane 0, and interpolate U and V correctly when
+    * sampling from plane 1. */
+   { __DRI_IMAGE_FOURCC_YUYV, __DRI_IMAGE_COMPONENTS_Y_XUXV, 2,
+     { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 },
+       { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } }
+};
+
+static __DRIimage *
+intel_allocate_image(int dri_format, void *loaderPrivate)
+{
+    __DRIimage *image;
+
+    image = calloc(1, sizeof *image);
+    if (image == NULL)
+       return NULL;
+
+    image->dri_format = dri_format;
+    image->offset = 0;
+
+    switch (dri_format) {
+    case __DRI_IMAGE_FORMAT_RGB565:
+       image->format = MESA_FORMAT_RGB565;
+       break;
+    case __DRI_IMAGE_FORMAT_XRGB8888:
+       image->format = MESA_FORMAT_XRGB8888;
+       break;
+    case __DRI_IMAGE_FORMAT_ARGB8888:
+       image->format = MESA_FORMAT_ARGB8888;
+       break;
+    case __DRI_IMAGE_FORMAT_ABGR8888:
+       image->format = MESA_FORMAT_RGBA8888_REV;
+       break;
+    case __DRI_IMAGE_FORMAT_XBGR8888:
+       image->format = MESA_FORMAT_RGBX8888_REV;
+       break;
+    case __DRI_IMAGE_FORMAT_R8:
+       image->format = MESA_FORMAT_R8;
+       break;
+    case __DRI_IMAGE_FORMAT_GR88:
+       image->format = MESA_FORMAT_GR88;
+       break;
+    case __DRI_IMAGE_FORMAT_NONE:
+       image->format = MESA_FORMAT_NONE;
+       break;
+    default:
+       free(image);
+       return NULL;
+    }
+
+    image->internal_format = _mesa_get_format_base_format(image->format);
+    image->data = loaderPrivate;
+
+    return image;
+}
+
+/**
+ * Sets up a DRIImage structure to point to our shared image in a region
+ */
+static void
+intel_setup_image_from_mipmap_tree(struct intel_context *intel, __DRIimage *image,
+                                   struct intel_mipmap_tree *mt, GLuint level,
+                                   GLuint zoffset)
+{
+   unsigned int draw_x, draw_y;
+   uint32_t mask_x, mask_y;
+
+   intel_miptree_make_shareable(intel, mt);
+
+   intel_miptree_check_level_layer(mt, level, zoffset);
+
+   intel_region_get_tile_masks(mt->region, &mask_x, &mask_y, false);
+   intel_miptree_get_image_offset(mt, level, zoffset, &draw_x, &draw_y);
+
+   image->width = mt->level[level].width;
+   image->height = mt->level[level].height;
+   image->tile_x = draw_x & mask_x;
+   image->tile_y = draw_y & mask_y;
+
+   image->offset = intel_region_get_aligned_offset(mt->region,
+                                                   draw_x & ~mask_x,
+                                                   draw_y & ~mask_y,
+                                                   false);
+
+   intel_region_reference(&image->region, mt->region);
+}
+
+static void
+intel_setup_image_from_dimensions(__DRIimage *image)
+{
+   image->width    = image->region->width;
+   image->height   = image->region->height;
+   image->tile_x = 0;
+   image->tile_y = 0;
+   image->has_depthstencil = false;
+}
+
+static inline uint32_t
+intel_dri_format(GLuint format)
+{
+   switch (format) {
+   case MESA_FORMAT_RGB565:
+      return __DRI_IMAGE_FORMAT_RGB565;
+   case MESA_FORMAT_XRGB8888:
+      return __DRI_IMAGE_FORMAT_XRGB8888;
+   case MESA_FORMAT_ARGB8888:
+      return __DRI_IMAGE_FORMAT_ARGB8888;
+   case MESA_FORMAT_RGBA8888_REV:
+      return __DRI_IMAGE_FORMAT_ABGR8888;
+   case MESA_FORMAT_R8:
+      return __DRI_IMAGE_FORMAT_R8;
+   case MESA_FORMAT_RG88:
+      return __DRI_IMAGE_FORMAT_GR88;
+   }
+
+   return MESA_FORMAT_NONE;
+}
+
+static __DRIimage *
+intel_create_image_from_name(__DRIscreen *screen,
+                            int width, int height, int format,
+                            int name, int pitch, void *loaderPrivate)
+{
+    struct intel_screen *intelScreen = screen->driverPrivate;
+    __DRIimage *image;
+    int cpp;
+
+    image = intel_allocate_image(format, loaderPrivate);
+    if (image == NULL)
+       return NULL;
+
+    if (image->format == MESA_FORMAT_NONE)
+       cpp = 1;
+    else
+       cpp = _mesa_get_format_bytes(image->format);
+    image->region = intel_region_alloc_for_handle(intelScreen,
+                                                 cpp, width, height,
+                                                 pitch * cpp, name, "image");
+    if (image->region == NULL) {
+       free(image);
+       return NULL;
+    }
+
+    intel_setup_image_from_dimensions(image);
+
+    return image;      
+}
+
+static __DRIimage *
+intel_create_image_from_renderbuffer(__DRIcontext *context,
+                                    int renderbuffer, void *loaderPrivate)
+{
+   __DRIimage *image;
+   struct intel_context *intel = context->driverPrivate;
+   struct gl_renderbuffer *rb;
+   struct intel_renderbuffer *irb;
+
+   rb = _mesa_lookup_renderbuffer(&intel->ctx, renderbuffer);
+   if (!rb) {
+      _mesa_error(&intel->ctx,
+                 GL_INVALID_OPERATION, "glRenderbufferExternalMESA");
+      return NULL;
+   }
+
+   irb = intel_renderbuffer(rb);
+   intel_miptree_make_shareable(intel, irb->mt);
+   image = calloc(1, sizeof *image);
+   if (image == NULL)
+      return NULL;
+
+   image->internal_format = rb->InternalFormat;
+   image->format = rb->Format;
+   image->offset = 0;
+   image->data = loaderPrivate;
+   intel_region_reference(&image->region, irb->mt->region);
+   intel_setup_image_from_dimensions(image);
+   image->dri_format = intel_dri_format(image->format);
+   image->has_depthstencil = irb->mt->stencil_mt? true : false;
+
+   rb->NeedsFinishRenderTexture = true;
+   return image;
+}
+
+static __DRIimage *
+intel_create_image_from_texture(__DRIcontext *context, int target,
+                                unsigned texture, int zoffset,
+                                int level,
+                                unsigned *error,
+                                void *loaderPrivate)
+{
+   __DRIimage *image;
+   struct intel_context *intel = context->driverPrivate;
+   struct gl_texture_object *obj;
+   struct intel_texture_object *iobj;
+   GLuint face = 0;
+
+   obj = _mesa_lookup_texture(&intel->ctx, texture);
+   if (!obj || obj->Target != target) {
+      *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
+      return NULL;
+   }
+
+   if (target == GL_TEXTURE_CUBE_MAP)
+      face = zoffset;
+
+   _mesa_test_texobj_completeness(&intel->ctx, obj);
+   iobj = intel_texture_object(obj);
+   if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) {
+      *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
+      return NULL;
+   }
+
+   if (level < obj->BaseLevel || level > obj->_MaxLevel) {
+      *error = __DRI_IMAGE_ERROR_BAD_MATCH;
+      return NULL;
+   }
+
+   if (target == GL_TEXTURE_3D && obj->Image[face][level]->Depth < zoffset) {
+      *error = __DRI_IMAGE_ERROR_BAD_MATCH;
+      return NULL;
+   }
+   image = calloc(1, sizeof *image);
+   if (image == NULL) {
+      *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
+      return NULL;
+   }
+
+   image->internal_format = obj->Image[face][level]->InternalFormat;
+   image->format = obj->Image[face][level]->TexFormat;
+   image->data = loaderPrivate;
+   intel_setup_image_from_mipmap_tree(intel, image, iobj->mt, level, zoffset);
+   image->dri_format = intel_dri_format(image->format);
+   image->has_depthstencil = iobj->mt->stencil_mt? true : false;
+   if (image->dri_format == MESA_FORMAT_NONE) {
+      *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
+      free(image);
+      return NULL;
+   }
+
+   *error = __DRI_IMAGE_ERROR_SUCCESS;
+   return image;
+}
+
+static void
+intel_destroy_image(__DRIimage *image)
+{
+    intel_region_release(&image->region);
+    free(image);
+}
+
+static __DRIimage *
+intel_create_image(__DRIscreen *screen,
+                  int width, int height, int format,
+                  unsigned int use,
+                  void *loaderPrivate)
+{
+   __DRIimage *image;
+   struct intel_screen *intelScreen = screen->driverPrivate;
+   uint32_t tiling;
+   int cpp;
+
+   tiling = I915_TILING_X;
+   if (use & __DRI_IMAGE_USE_CURSOR) {
+      if (width != 64 || height != 64)
+        return NULL;
+      tiling = I915_TILING_NONE;
+   }
+
+   image = intel_allocate_image(format, loaderPrivate);
+   if (image == NULL)
+      return NULL;
+
+   cpp = _mesa_get_format_bytes(image->format);
+   image->region =
+      intel_region_alloc(intelScreen, tiling, cpp, width, height, true);
+   if (image->region == NULL) {
+      free(image);
+      return NULL;
+   }
+   
+   intel_setup_image_from_dimensions(image);
+
+   return image;
+}
+
+static GLboolean
+intel_query_image(__DRIimage *image, int attrib, int *value)
+{
+   switch (attrib) {
+   case __DRI_IMAGE_ATTRIB_STRIDE:
+      *value = image->region->pitch;
+      return true;
+   case __DRI_IMAGE_ATTRIB_HANDLE:
+      *value = image->region->bo->handle;
+      return true;
+   case __DRI_IMAGE_ATTRIB_NAME:
+      return intel_region_flink(image->region, (uint32_t *) value);
+   case __DRI_IMAGE_ATTRIB_FORMAT:
+      *value = image->dri_format;
+      return true;
+   case __DRI_IMAGE_ATTRIB_WIDTH:
+      *value = image->region->width;
+      return true;
+   case __DRI_IMAGE_ATTRIB_HEIGHT:
+      *value = image->region->height;
+      return true;
+   case __DRI_IMAGE_ATTRIB_COMPONENTS:
+      if (image->planar_format == NULL)
+         return false;
+      *value = image->planar_format->components;
+      return true;
+   case __DRI_IMAGE_ATTRIB_FD:
+      if (drm_intel_bo_gem_export_to_prime(image->region->bo, value) == 0)
+         return true;
+      return false;
+  default:
+      return false;
+   }
+}
+
+static __DRIimage *
+intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
+{
+   __DRIimage *image;
+
+   image = calloc(1, sizeof *image);
+   if (image == NULL)
+      return NULL;
+
+   intel_region_reference(&image->region, orig_image->region);
+   if (image->region == NULL) {
+      free(image);
+      return NULL;
+   }
+
+   image->internal_format = orig_image->internal_format;
+   image->planar_format   = orig_image->planar_format;
+   image->dri_format      = orig_image->dri_format;
+   image->format          = orig_image->format;
+   image->offset          = orig_image->offset;
+   image->width           = orig_image->width;
+   image->height          = orig_image->height;
+   image->tile_x          = orig_image->tile_x;
+   image->tile_y          = orig_image->tile_y;
+   image->has_depthstencil = orig_image->has_depthstencil;
+   image->data            = loaderPrivate;
+
+   memcpy(image->strides, orig_image->strides, sizeof(image->strides));
+   memcpy(image->offsets, orig_image->offsets, sizeof(image->offsets));
+
+   return image;
+}
+
+static GLboolean
+intel_validate_usage(__DRIimage *image, unsigned int use)
+{
+   if (use & __DRI_IMAGE_USE_CURSOR) {
+      if (image->region->width != 64 || image->region->height != 64)
+        return GL_FALSE;
+   }
+
+   return GL_TRUE;
+}
+
+static __DRIimage *
+intel_create_image_from_names(__DRIscreen *screen,
+                              int width, int height, int fourcc,
+                              int *names, int num_names,
+                              int *strides, int *offsets,
+                              void *loaderPrivate)
+{
+    struct intel_image_format *f = NULL;
+    __DRIimage *image;
+    int i, index;
+
+    if (screen == NULL || names == NULL || num_names != 1)
+        return NULL;
+
+    for (i = 0; i < ARRAY_SIZE(intel_image_formats); i++) {
+        if (intel_image_formats[i].fourcc == fourcc) {
+           f = &intel_image_formats[i];
+        }
+    }
+
+    if (f == NULL)
+        return NULL;
+
+    image = intel_create_image_from_name(screen, width, height,
+                                         __DRI_IMAGE_FORMAT_NONE,
+                                         names[0], strides[0],
+                                         loaderPrivate);
+
+   if (image == NULL)
+      return NULL;
+
+    image->planar_format = f;
+    for (i = 0; i < f->nplanes; i++) {
+        index = f->planes[i].buffer_index;
+        image->offsets[index] = offsets[index];
+        image->strides[index] = strides[index];
+    }
+
+    return image;
+}
+
+static __DRIimage *
+intel_create_image_from_fds(__DRIscreen *screen,
+                            int width, int height, int fourcc,
+                            int *fds, int num_fds, int *strides, int *offsets,
+                            void *loaderPrivate)
+{
+   struct intel_screen *intelScreen = screen->driverPrivate;
+   struct intel_image_format *f = NULL;
+   __DRIimage *image;
+   int i, index;
+
+   if (fds == NULL || num_fds != 1)
+      return NULL;
+
+   for (i = 0; i < ARRAY_SIZE(intel_image_formats); i++) {
+      if (intel_image_formats[i].fourcc == fourcc) {
+         f = &intel_image_formats[i];
+      }
+   }
+
+   if (f == NULL)
+      return NULL;
+
+   image = intel_allocate_image(__DRI_IMAGE_FORMAT_NONE, loaderPrivate);
+   if (image == NULL)
+      return NULL;
+
+   image->region = intel_region_alloc_for_fd(intelScreen,
+                                             1, width, height,
+                                             strides[0], fds[0], "image");
+   if (image->region == NULL) {
+      free(image);
+      return NULL;
+   }
+
+   image->planar_format = f;
+   for (i = 0; i < f->nplanes; i++) {
+      index = f->planes[i].buffer_index;
+      image->offsets[index] = offsets[index];
+      image->strides[index] = strides[index];
+   }
+
+   return image;
+}
+
+
+static __DRIimage *
+intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
+{
+    int width, height, offset, stride, dri_format, index;
+    struct intel_image_format *f;
+    uint32_t mask_x, mask_y;
+    __DRIimage *image;
+
+    if (parent == NULL || parent->planar_format == NULL)
+        return NULL;
+
+    f = parent->planar_format;
+
+    if (plane >= f->nplanes)
+        return NULL;
+
+    width = parent->region->width >> f->planes[plane].width_shift;
+    height = parent->region->height >> f->planes[plane].height_shift;
+    dri_format = f->planes[plane].dri_format;
+    index = f->planes[plane].buffer_index;
+    offset = parent->offsets[index];
+    stride = parent->strides[index];
+
+    image = intel_allocate_image(dri_format, loaderPrivate);
+    if (image == NULL)
+       return NULL;
+
+    if (offset + height * stride > parent->region->bo->size) {
+       _mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds");
+       free(image);
+       return NULL;
+    }
+
+    image->region = calloc(sizeof(*image->region), 1);
+    if (image->region == NULL) {
+       free(image);
+       return NULL;
+    }
+
+    image->region->cpp = _mesa_get_format_bytes(image->format);
+    image->region->width = width;
+    image->region->height = height;
+    image->region->pitch = stride;
+    image->region->refcount = 1;
+    image->region->bo = parent->region->bo;
+    drm_intel_bo_reference(image->region->bo);
+    image->region->tiling = parent->region->tiling;
+    image->offset = offset;
+    intel_setup_image_from_dimensions(image);
+
+    intel_region_get_tile_masks(image->region, &mask_x, &mask_y, false);
+    if (offset & mask_x)
+       _mesa_warning(NULL,
+                     "intel_create_sub_image: offset not on tile boundary");
+
+    return image;
+}
+
+static struct __DRIimageExtensionRec intelImageExtension = {
+    .base = { __DRI_IMAGE, 7 },
+
+    .createImageFromName                = intel_create_image_from_name,
+    .createImageFromRenderbuffer        = intel_create_image_from_renderbuffer,
+    .destroyImage                       = intel_destroy_image,
+    .createImage                        = intel_create_image,
+    .queryImage                         = intel_query_image,
+    .dupImage                           = intel_dup_image,
+    .validateUsage                      = intel_validate_usage,
+    .createImageFromNames               = intel_create_image_from_names,
+    .fromPlanar                         = intel_from_planar,
+    .createImageFromTexture             = intel_create_image_from_texture,
+    .createImageFromFds                 = intel_create_image_from_fds
+};
+
+static const __DRIextension *intelScreenExtensions[] = {
+    &intelTexBufferExtension.base,
+    &intelFlushExtension.base,
+    &intelImageExtension.base,
+    &dri2ConfigQueryExtension.base,
+    NULL
+};
+
+static bool
+intel_get_param(__DRIscreen *psp, int param, int *value)
+{
+   int ret;
+   struct drm_i915_getparam gp;
+
+   memset(&gp, 0, sizeof(gp));
+   gp.param = param;
+   gp.value = value;
+
+   ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
+   if (ret) {
+      if (ret != -EINVAL)
+        _mesa_warning(NULL, "drm_i915_getparam: %d", ret);
+      return false;
+   }
+
+   return true;
+}
+
+static bool
+intel_get_boolean(__DRIscreen *psp, int param)
+{
+   int value = 0;
+   return intel_get_param(psp, param, &value) && value;
+}
+
+static void
+intelDestroyScreen(__DRIscreen * sPriv)
+{
+   struct intel_screen *intelScreen = sPriv->driverPrivate;
+
+   dri_bufmgr_destroy(intelScreen->bufmgr);
+   driDestroyOptionInfo(&intelScreen->optionCache);
+
+   free(intelScreen);
+   sPriv->driverPrivate = NULL;
+}
+
+
+/**
+ * This is called when we need to set up GL rendering to a new X window.
+ */
+static GLboolean
+intelCreateBuffer(__DRIscreen * driScrnPriv,
+                  __DRIdrawable * driDrawPriv,
+                  const struct gl_config * mesaVis, GLboolean isPixmap)
+{
+   struct intel_renderbuffer *rb;
+   struct intel_screen *screen = (struct intel_screen*) driScrnPriv->driverPrivate;
+   gl_format rgbFormat;
+   unsigned num_samples = intel_quantize_num_samples(screen, mesaVis->samples);
+   struct gl_framebuffer *fb;
+
+   if (isPixmap)
+      return false;
+
+   fb = CALLOC_STRUCT(gl_framebuffer);
+   if (!fb)
+      return false;
+
+   _mesa_initialize_window_framebuffer(fb, mesaVis);
+
+   if (mesaVis->redBits == 5)
+      rgbFormat = MESA_FORMAT_RGB565;
+   else if (mesaVis->sRGBCapable)
+      rgbFormat = MESA_FORMAT_SARGB8;
+   else if (mesaVis->alphaBits == 0)
+      rgbFormat = MESA_FORMAT_XRGB8888;
+   else {
+      if (screen->gen >= 4) {
+         rgbFormat = MESA_FORMAT_SARGB8;
+         fb->Visual.sRGBCapable = true;
+      } else {
+         rgbFormat = MESA_FORMAT_ARGB8888;
+      }
+
+   }
+
+   /* setup the hardware-based renderbuffers */
+   rb = intel_create_renderbuffer(rgbFormat, num_samples);
+   _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &rb->Base.Base);
+
+   if (mesaVis->doubleBufferMode) {
+      rb = intel_create_renderbuffer(rgbFormat, num_samples);
+      _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &rb->Base.Base);
+   }
+
+   /*
+    * Assert here that the gl_config has an expected depth/stencil bit
+    * combination: one of d24/s8, d16/s0, d0/s0. (See intelInitScreen2(),
+    * which constructs the advertised configs.)
+    */
+   if (mesaVis->depthBits == 24) {
+      assert(mesaVis->stencilBits == 8);
+
+      if (screen->hw_has_separate_stencil) {
+         rb = intel_create_private_renderbuffer(MESA_FORMAT_X8_Z24,
+                                                num_samples);
+         _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
+         rb = intel_create_private_renderbuffer(MESA_FORMAT_S8,
+                                                num_samples);
+         _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
+      } else {
+         /*
+          * Use combined depth/stencil. Note that the renderbuffer is
+          * attached to two attachment points.
+          */
+         rb = intel_create_private_renderbuffer(MESA_FORMAT_S8_Z24,
+                                                num_samples);
+         _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
+         _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
+      }
+   }
+   else if (mesaVis->depthBits == 16) {
+      assert(mesaVis->stencilBits == 0);
+      rb = intel_create_private_renderbuffer(MESA_FORMAT_Z16,
+                                             num_samples);
+      _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
+   }
+   else {
+      assert(mesaVis->depthBits == 0);
+      assert(mesaVis->stencilBits == 0);
+   }
+
+   /* now add any/all software-based renderbuffers we may need */
+   _swrast_add_soft_renderbuffers(fb,
+                                  false, /* never sw color */
+                                  false, /* never sw depth */
+                                  false, /* never sw stencil */
+                                  mesaVis->accumRedBits > 0,
+                                  false, /* never sw alpha */
+                                  false  /* never sw aux */ );
+   driDrawPriv->driverPrivate = fb;
+
+   return true;
+}
+
+static void
+intelDestroyBuffer(__DRIdrawable * driDrawPriv)
+{
+    struct gl_framebuffer *fb = driDrawPriv->driverPrivate;
+  
+    _mesa_reference_framebuffer(&fb, NULL);
+}
+
+/* There are probably better ways to do this, such as an
+ * init-designated function to register chipids and createcontext
+ * functions.
+ */
+extern bool
+i830CreateContext(int api,
+                  const struct gl_config *mesaVis,
+                 __DRIcontext *driContextPriv,
+                 unsigned major_version,
+                 unsigned minor_version,
+                 unsigned *error,
+                 void *sharedContextPrivate);
+
+extern bool
+i915CreateContext(int api,
+                 const struct gl_config *mesaVis,
+                 __DRIcontext *driContextPriv,
+                  unsigned major_version,
+                  unsigned minor_version,
+                  unsigned *error,
+                 void *sharedContextPrivate);
+extern bool
+brwCreateContext(int api,
+                const struct gl_config *mesaVis,
+                __DRIcontext *driContextPriv,
+                 unsigned major_version,
+                 unsigned minor_version,
+                 uint32_t flags,
+                 unsigned *error,
+                void *sharedContextPrivate);
+
+static GLboolean
+intelCreateContext(gl_api api,
+                  const struct gl_config * mesaVis,
+                   __DRIcontext * driContextPriv,
+                  unsigned major_version,
+                  unsigned minor_version,
+                  uint32_t flags,
+                  unsigned *error,
+                   void *sharedContextPrivate)
+{
+   bool success = false;
+
+#ifdef I915
+   __DRIscreen *sPriv = driContextPriv->driScreenPriv;
+   struct intel_screen *intelScreen = sPriv->driverPrivate;
+
+   if (IS_9XX(intelScreen->deviceID)) {
+      success = i915CreateContext(api, mesaVis, driContextPriv,
+                                  major_version, minor_version, error,
+                                  sharedContextPrivate);
+   } else {
+      intelScreen->no_vbo = true;
+      success = i830CreateContext(api, mesaVis, driContextPriv,
+                                  major_version, minor_version, error,
+                                  sharedContextPrivate);
+   }
+#else
+   success = brwCreateContext(api, mesaVis,
+                              driContextPriv,
+                              major_version, minor_version, flags,
+                              error, sharedContextPrivate);
+#endif
+
+   if (success)
+      return true;
+
+   if (driContextPriv->driverPrivate != NULL)
+      intelDestroyContext(driContextPriv);
+
+   return false;
+}
+
+static bool
+intel_init_bufmgr(struct intel_screen *intelScreen)
+{
+   __DRIscreen *spriv = intelScreen->driScrnPriv;
+
+   intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL;
+
+   intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
+   if (intelScreen->bufmgr == NULL) {
+      fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
+             __func__, __LINE__);
+      return false;
+   }
+
+   drm_intel_bufmgr_gem_enable_fenced_relocs(intelScreen->bufmgr);
+
+   if (!intel_get_boolean(spriv, I915_PARAM_HAS_RELAXED_DELTA)) {
+      fprintf(stderr, "[%s: %u] Kernel 2.6.39 required.\n", __func__, __LINE__);
+      return false;
+   }
+
+   return true;
+}
+
+/**
+ * Override intel_screen.hw_has_separate_stencil with environment variable
+ * INTEL_SEPARATE_STENCIL.
+ *
+ * Valid values for INTEL_SEPARATE_STENCIL are "0" and "1". If an invalid
+ * valid value is encountered, a warning is emitted and INTEL_SEPARATE_STENCIL
+ * is ignored.
+ */
+static void
+intel_override_separate_stencil(struct intel_screen *screen)
+{
+   const char *s = getenv("INTEL_SEPARATE_STENCIL");
+   if (!s) {
+      return;
+   } else if (!strncmp("0", s, 2)) {
+      screen->hw_has_separate_stencil = false;
+   } else if (!strncmp("1", s, 2)) {
+      screen->hw_has_separate_stencil = true;
+   } else {
+      fprintf(stderr,
+             "warning: env variable INTEL_SEPARATE_STENCIL=\"%s\" has "
+             "invalid value and is ignored", s);
+   }
+}
+
+static bool
+intel_detect_swizzling(struct intel_screen *screen)
+{
+   drm_intel_bo *buffer;
+   unsigned long flags = 0;
+   unsigned long aligned_pitch;
+   uint32_t tiling = I915_TILING_X;
+   uint32_t swizzle_mode = 0;
+
+   buffer = drm_intel_bo_alloc_tiled(screen->bufmgr, "swizzle test",
+                                    64, 64, 4,
+                                    &tiling, &aligned_pitch, flags);
+   if (buffer == NULL)
+      return false;
+
+   drm_intel_bo_get_tiling(buffer, &tiling, &swizzle_mode);
+   drm_intel_bo_unreference(buffer);
+
+   if (swizzle_mode == I915_BIT_6_SWIZZLE_NONE)
+      return false;
+   else
+      return true;
+}
+
+static __DRIconfig**
+intel_screen_make_configs(__DRIscreen *dri_screen)
+{
+   static const gl_format formats[] = {
+      MESA_FORMAT_RGB565,
+      MESA_FORMAT_ARGB8888
+   };
+
+   /* GLX_SWAP_COPY_OML is not supported due to page flipping. */
+   static const GLenum back_buffer_modes[] = {
+       GLX_SWAP_UNDEFINED_OML, GLX_NONE,
+   };
+
+   static const uint8_t singlesample_samples[1] = {0};
+   static const uint8_t multisample_samples[2]  = {4, 8};
+
+   struct intel_screen *screen = dri_screen->driverPrivate;
+   uint8_t depth_bits[4], stencil_bits[4];
+   __DRIconfig **configs = NULL;
+
+   /* Generate singlesample configs without accumulation buffer. */
+   for (int i = 0; i < ARRAY_SIZE(formats); i++) {
+      __DRIconfig **new_configs;
+      int num_depth_stencil_bits = 2;
+
+      /* Starting with DRI2 protocol version 1.1 we can request a depth/stencil
+       * buffer that has a different number of bits per pixel than the color
+       * buffer, gen >= 6 supports this.
+       */
+      depth_bits[0] = 0;
+      stencil_bits[0] = 0;
+
+      if (formats[i] == MESA_FORMAT_RGB565) {
+         depth_bits[1] = 16;
+         stencil_bits[1] = 0;
+         if (screen->gen >= 6) {
+             depth_bits[2] = 24;
+             stencil_bits[2] = 8;
+             num_depth_stencil_bits = 3;
+         }
+      } else {
+         depth_bits[1] = 24;
+         stencil_bits[1] = 8;
+      }
+
+      new_configs = driCreateConfigs(formats[i],
+                                     depth_bits,
+                                     stencil_bits,
+                                     num_depth_stencil_bits,
+                                     back_buffer_modes, 2,
+                                     singlesample_samples, 1,
+                                     false);
+      configs = driConcatConfigs(configs, new_configs);
+   }
+
+   /* Generate the minimum possible set of configs that include an
+    * accumulation buffer.
+    */
+   for (int i = 0; i < ARRAY_SIZE(formats); i++) {
+      __DRIconfig **new_configs;
+
+      if (formats[i] == MESA_FORMAT_RGB565) {
+         depth_bits[0] = 16;
+         stencil_bits[0] = 0;
+      } else {
+         depth_bits[0] = 24;
+         stencil_bits[0] = 8;
+      }
+
+      new_configs = driCreateConfigs(formats[i],
+                                     depth_bits, stencil_bits, 1,
+                                     back_buffer_modes, 1,
+                                     singlesample_samples, 1,
+                                     true);
+      configs = driConcatConfigs(configs, new_configs);
+   }
+
+   /* Generate multisample configs.
+    *
+    * This loop breaks early, and hence is a no-op, on gen < 6.
+    *
+    * Multisample configs must follow the singlesample configs in order to
+    * work around an X server bug present in 1.12. The X server chooses to
+    * associate the first listed RGBA888-Z24S8 config, regardless of its
+    * sample count, with the 32-bit depth visual used for compositing.
+    *
+    * Only doublebuffer configs with GLX_SWAP_UNDEFINED_OML behavior are
+    * supported.  Singlebuffer configs are not supported because no one wants
+    * them.
+    */
+   for (int i = 0; i < ARRAY_SIZE(formats); i++) {
+      if (screen->gen < 6)
+         break;
+
+      __DRIconfig **new_configs;
+      const int num_depth_stencil_bits = 2;
+      int num_msaa_modes = 0;
+
+      depth_bits[0] = 0;
+      stencil_bits[0] = 0;
+
+      if (formats[i] == MESA_FORMAT_RGB565) {
+         depth_bits[1] = 16;
+         stencil_bits[1] = 0;
+      } else {
+         depth_bits[1] = 24;
+         stencil_bits[1] = 8;
+      }
+
+      if (screen->gen >= 7)
+         num_msaa_modes = 2;
+      else if (screen->gen == 6)
+         num_msaa_modes = 1;
+
+      new_configs = driCreateConfigs(formats[i],
+                                     depth_bits,
+                                     stencil_bits,
+                                     num_depth_stencil_bits,
+                                     back_buffer_modes, 1,
+                                     multisample_samples,
+                                     num_msaa_modes,
+                                     false);
+      configs = driConcatConfigs(configs, new_configs);
+   }
+
+   if (configs == NULL) {
+      fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
+              __LINE__);
+      return NULL;
+   }
+
+   return configs;
+}
+
+static void
+set_max_gl_versions(struct intel_screen *screen)
+{
+   int gl_version_override = _mesa_get_gl_version_override();
+
+   switch (screen->gen) {
+   case 7:
+      screen->max_gl_core_version = 31;
+      screen->max_gl_compat_version = 30;
+      screen->max_gl_es1_version = 11;
+      screen->max_gl_es2_version = 30;
+      break;
+   case 6:
+      screen->max_gl_core_version = 31;
+      screen->max_gl_compat_version = 30;
+      screen->max_gl_es1_version = 11;
+      screen->max_gl_es2_version = 30;
+      break;
+   case 5:
+   case 4:
+      screen->max_gl_core_version = 0;
+      screen->max_gl_compat_version = 21;
+      screen->max_gl_es1_version = 11;
+      screen->max_gl_es2_version = 20;
+      break;
+   case 3: {
+      screen->max_gl_core_version = 0;
+      screen->max_gl_es1_version = 11;
+      screen->max_gl_compat_version = 21;
+      screen->max_gl_es2_version = 20;
+
+      break;
+   }
+   case 2:
+      screen->max_gl_core_version = 0;
+      screen->max_gl_compat_version = 13;
+      screen->max_gl_es1_version = 11;
+      screen->max_gl_es2_version = 0;
+      break;
+   default:
+      assert(!"unrecognized intel_screen::gen");
+      break;
+   }
+
+   if (gl_version_override >= 31) {
+      screen->max_gl_core_version = MAX2(screen->max_gl_core_version,
+                                         gl_version_override);
+   } else {
+      screen->max_gl_compat_version = MAX2(screen->max_gl_compat_version,
+                                           gl_version_override);
+   }
+
+#ifndef FEATURE_ES1
+   screen->max_gl_es1_version = 0;
+#endif
+
+#ifndef FEATURE_ES2
+   screen->max_gl_es2_version = 0;
+#endif
+}
+
+/**
+ * This is the driver specific part of the createNewScreen entry point.
+ * Called when using DRI2.
+ *
+ * \return the struct gl_config supported by this driver
+ */
+static const
+__DRIconfig **intelInitScreen2(__DRIscreen *psp)
+{
+   struct intel_screen *intelScreen;
+
+   if (psp->dri2.loader->base.version <= 2 ||
+       psp->dri2.loader->getBuffersWithFormat == NULL) {
+      fprintf(stderr,
+             "\nERROR!  DRI2 loader with getBuffersWithFormat() "
+             "support required\n");
+      return false;
+   }
+
+   /* Allocate the private area */
+   intelScreen = calloc(1, sizeof *intelScreen);
+   if (!intelScreen) {
+      fprintf(stderr, "\nERROR!  Allocating private area failed\n");
+      return false;
+   }
+   /* parse information in __driConfigOptions */
+   driParseOptionInfo(&intelScreen->optionCache,
+                      __driConfigOptions, __driNConfigOptions);
+
+   intelScreen->driScrnPriv = psp;
+   psp->driverPrivate = (void *) intelScreen;
+
+   if (!intel_init_bufmgr(intelScreen))
+       return false;
+
+   intelScreen->deviceID = drm_intel_bufmgr_gem_get_devid(intelScreen->bufmgr);
+
+   if (IS_GEN7(intelScreen->deviceID)) {
+      intelScreen->gen = 7;
+   } else if (IS_GEN6(intelScreen->deviceID)) {
+      intelScreen->gen = 6;
+   } else if (IS_GEN5(intelScreen->deviceID)) {
+      intelScreen->gen = 5;
+   } else if (IS_965(intelScreen->deviceID)) {
+      intelScreen->gen = 4;
+   } else if (IS_9XX(intelScreen->deviceID)) {
+      intelScreen->gen = 3;
+   } else {
+      intelScreen->gen = 2;
+   }
+
+   intelScreen->hw_has_separate_stencil = intelScreen->gen >= 6;
+   intelScreen->hw_must_use_separate_stencil = intelScreen->gen >= 7;
+
+   int has_llc = 0;
+   bool success = intel_get_param(intelScreen->driScrnPriv, I915_PARAM_HAS_LLC,
+                                 &has_llc);
+   if (success && has_llc)
+      intelScreen->hw_has_llc = true;
+   else if (!success && intelScreen->gen >= 6)
+      intelScreen->hw_has_llc = true;
+
+   intel_override_separate_stencil(intelScreen);
+
+   intelScreen->hw_has_swizzling = intel_detect_swizzling(intelScreen);
+
+   set_max_gl_versions(intelScreen);
+
+   psp->api_mask = (1 << __DRI_API_OPENGL);
+   if (intelScreen->max_gl_core_version > 0)
+      psp->api_mask |= (1 << __DRI_API_OPENGL_CORE);
+   if (intelScreen->max_gl_es1_version > 0)
+      psp->api_mask |= (1 << __DRI_API_GLES);
+   if (intelScreen->max_gl_es2_version > 0)
+      psp->api_mask |= (1 << __DRI_API_GLES2);
+   if (intelScreen->max_gl_es2_version >= 30)
+      psp->api_mask |= (1 << __DRI_API_GLES3);
+
+   psp->extensions = intelScreenExtensions;
+
+   return (const __DRIconfig**) intel_screen_make_configs(psp);
+}
+
+struct intel_buffer {
+   __DRIbuffer base;
+   struct intel_region *region;
+};
+
+static __DRIbuffer *
+intelAllocateBuffer(__DRIscreen *screen,
+                   unsigned attachment, unsigned format,
+                   int width, int height)
+{
+   struct intel_buffer *intelBuffer;
+   struct intel_screen *intelScreen = screen->driverPrivate;
+
+   assert(attachment == __DRI_BUFFER_FRONT_LEFT ||
+          attachment == __DRI_BUFFER_BACK_LEFT);
+
+   intelBuffer = calloc(1, sizeof *intelBuffer);
+   if (intelBuffer == NULL)
+      return NULL;
+
+   /* The front and back buffers are color buffers, which are X tiled. */
+   intelBuffer->region = intel_region_alloc(intelScreen,
+                                            I915_TILING_X,
+                                            format / 8,
+                                            width,
+                                            height,
+                                            true);
+   
+   if (intelBuffer->region == NULL) {
+          free(intelBuffer);
+          return NULL;
+   }
+   
+   intel_region_flink(intelBuffer->region, &intelBuffer->base.name);
+
+   intelBuffer->base.attachment = attachment;
+   intelBuffer->base.cpp = intelBuffer->region->cpp;
+   intelBuffer->base.pitch = intelBuffer->region->pitch;
+
+   return &intelBuffer->base;
+}
+
+static void
+intelReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
+{
+   struct intel_buffer *intelBuffer = (struct intel_buffer *) buffer;
+
+   intel_region_release(&intelBuffer->region);
+   free(intelBuffer);
+}
+
+
+const struct __DriverAPIRec driDriverAPI = {
+   .InitScreen          = intelInitScreen2,
+   .DestroyScreen       = intelDestroyScreen,
+   .CreateContext       = intelCreateContext,
+   .DestroyContext      = intelDestroyContext,
+   .CreateBuffer        = intelCreateBuffer,
+   .DestroyBuffer       = intelDestroyBuffer,
+   .MakeCurrent                 = intelMakeCurrent,
+   .UnbindContext       = intelUnbindContext,
+   .AllocateBuffer       = intelAllocateBuffer,
+   .ReleaseBuffer        = intelReleaseBuffer
+};
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+    &driCoreExtension.base,
+    &driDRI2Extension.base,
+    NULL
+};
deleted file mode 120000 (symlink)
index 519672fc359d8b823291ad711cce1f4ac064daf5..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_state.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..6a817cdf3f6d263c08d6580824cfe873df6a554b
--- /dev/null
@@ -0,0 +1,195 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/macros.h"
+#include "main/enums.h"
+#include "main/colormac.h"
+#include "main/dd.h"
+
+#include "intel_screen.h"
+#include "intel_context.h"
+
+int
+intel_translate_shadow_compare_func(GLenum func)
+{
+   switch (func) {
+   case GL_NEVER: 
+       return COMPAREFUNC_ALWAYS;
+   case GL_LESS: 
+       return COMPAREFUNC_LEQUAL;
+   case GL_LEQUAL: 
+       return COMPAREFUNC_LESS;
+   case GL_GREATER: 
+       return COMPAREFUNC_GEQUAL;
+   case GL_GEQUAL: 
+      return COMPAREFUNC_GREATER;
+   case GL_NOTEQUAL: 
+      return COMPAREFUNC_EQUAL;
+   case GL_EQUAL: 
+      return COMPAREFUNC_NOTEQUAL;
+   case GL_ALWAYS: 
+       return COMPAREFUNC_NEVER;
+   }
+
+   fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, func);
+   return COMPAREFUNC_NEVER;
+}
+
+int
+intel_translate_compare_func(GLenum func)
+{
+   switch (func) {
+   case GL_NEVER:
+      return COMPAREFUNC_NEVER;
+   case GL_LESS:
+      return COMPAREFUNC_LESS;
+   case GL_LEQUAL:
+      return COMPAREFUNC_LEQUAL;
+   case GL_GREATER:
+      return COMPAREFUNC_GREATER;
+   case GL_GEQUAL:
+      return COMPAREFUNC_GEQUAL;
+   case GL_NOTEQUAL:
+      return COMPAREFUNC_NOTEQUAL;
+   case GL_EQUAL:
+      return COMPAREFUNC_EQUAL;
+   case GL_ALWAYS:
+      return COMPAREFUNC_ALWAYS;
+   }
+
+   fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, func);
+   return COMPAREFUNC_ALWAYS;
+}
+
+int
+intel_translate_stencil_op(GLenum op)
+{
+   switch (op) {
+   case GL_KEEP:
+      return STENCILOP_KEEP;
+   case GL_ZERO:
+      return STENCILOP_ZERO;
+   case GL_REPLACE:
+      return STENCILOP_REPLACE;
+   case GL_INCR:
+      return STENCILOP_INCRSAT;
+   case GL_DECR:
+      return STENCILOP_DECRSAT;
+   case GL_INCR_WRAP:
+      return STENCILOP_INCR;
+   case GL_DECR_WRAP:
+      return STENCILOP_DECR;
+   case GL_INVERT:
+      return STENCILOP_INVERT;
+   default:
+      return STENCILOP_ZERO;
+   }
+}
+
+int
+intel_translate_blend_factor(GLenum factor)
+{
+   switch (factor) {
+   case GL_ZERO:
+      return BLENDFACT_ZERO;
+   case GL_SRC_ALPHA:
+      return BLENDFACT_SRC_ALPHA;
+   case GL_ONE:
+      return BLENDFACT_ONE;
+   case GL_SRC_COLOR:
+      return BLENDFACT_SRC_COLR;
+   case GL_ONE_MINUS_SRC_COLOR:
+      return BLENDFACT_INV_SRC_COLR;
+   case GL_DST_COLOR:
+      return BLENDFACT_DST_COLR;
+   case GL_ONE_MINUS_DST_COLOR:
+      return BLENDFACT_INV_DST_COLR;
+   case GL_ONE_MINUS_SRC_ALPHA:
+      return BLENDFACT_INV_SRC_ALPHA;
+   case GL_DST_ALPHA:
+      return BLENDFACT_DST_ALPHA;
+   case GL_ONE_MINUS_DST_ALPHA:
+      return BLENDFACT_INV_DST_ALPHA;
+   case GL_SRC_ALPHA_SATURATE:
+      return BLENDFACT_SRC_ALPHA_SATURATE;
+   case GL_CONSTANT_COLOR:
+      return BLENDFACT_CONST_COLOR;
+   case GL_ONE_MINUS_CONSTANT_COLOR:
+      return BLENDFACT_INV_CONST_COLOR;
+   case GL_CONSTANT_ALPHA:
+      return BLENDFACT_CONST_ALPHA;
+   case GL_ONE_MINUS_CONSTANT_ALPHA:
+      return BLENDFACT_INV_CONST_ALPHA;
+   }
+
+   fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, factor);
+   return BLENDFACT_ZERO;
+}
+
+int
+intel_translate_logic_op(GLenum opcode)
+{
+   switch (opcode) {
+   case GL_CLEAR:
+      return LOGICOP_CLEAR;
+   case GL_AND:
+      return LOGICOP_AND;
+   case GL_AND_REVERSE:
+      return LOGICOP_AND_RVRSE;
+   case GL_COPY:
+      return LOGICOP_COPY;
+   case GL_COPY_INVERTED:
+      return LOGICOP_COPY_INV;
+   case GL_AND_INVERTED:
+      return LOGICOP_AND_INV;
+   case GL_NOOP:
+      return LOGICOP_NOOP;
+   case GL_XOR:
+      return LOGICOP_XOR;
+   case GL_OR:
+      return LOGICOP_OR;
+   case GL_OR_INVERTED:
+      return LOGICOP_OR_INV;
+   case GL_NOR:
+      return LOGICOP_NOR;
+   case GL_EQUIV:
+      return LOGICOP_EQUIV;
+   case GL_INVERT:
+      return LOGICOP_INV;
+   case GL_OR_REVERSE:
+      return LOGICOP_OR_RVRSE;
+   case GL_NAND:
+      return LOGICOP_NAND;
+   case GL_SET:
+      return LOGICOP_SET;
+   default:
+      return LOGICOP_SET;
+   }
+}
deleted file mode 120000 (symlink)
index 0b2e56ab246b6ffd6858aa48552c4fbbadd08fba..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_syncobj.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..9657d9af959b06e5334e2e2233654ce46d74fe48
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright Â© 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *
+ */
+
+/** @file intel_syncobj.c
+ *
+ * Support for ARB_sync
+ *
+ * ARB_sync is implemented by flushing the current batchbuffer and keeping a
+ * reference on it.  We can then check for completion or wait for completion
+ * using the normal buffer object mechanisms.  This does mean that if an
+ * application is using many sync objects, it will emit small batchbuffers
+ * which may end up being a significant overhead.  In other tests of removing
+ * gratuitous batchbuffer syncs in Mesa, it hasn't appeared to be a significant
+ * performance bottleneck, though.
+ */
+
+#include "main/simple_list.h"
+#include "main/imports.h"
+
+#include "intel_context.h"
+#include "intel_batchbuffer.h"
+#include "intel_reg.h"
+
+static struct gl_sync_object *
+intel_new_sync_object(struct gl_context *ctx, GLuint id)
+{
+   struct intel_sync_object *sync;
+
+   sync = calloc(1, sizeof(struct intel_sync_object));
+
+   return &sync->Base;
+}
+
+static void
+intel_delete_sync_object(struct gl_context *ctx, struct gl_sync_object *s)
+{
+   struct intel_sync_object *sync = (struct intel_sync_object *)s;
+
+   drm_intel_bo_unreference(sync->bo);
+   free(sync);
+}
+
+static void
+intel_fence_sync(struct gl_context *ctx, struct gl_sync_object *s,
+              GLenum condition, GLbitfield flags)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_sync_object *sync = (struct intel_sync_object *)s;
+
+   assert(condition == GL_SYNC_GPU_COMMANDS_COMPLETE);
+   intel_batchbuffer_emit_mi_flush(intel);
+
+   sync->bo = intel->batch.bo;
+   drm_intel_bo_reference(sync->bo);
+
+   intel_flush(ctx);
+}
+
+static void intel_client_wait_sync(struct gl_context *ctx, struct gl_sync_object *s,
+                                GLbitfield flags, GLuint64 timeout)
+{
+   struct intel_sync_object *sync = (struct intel_sync_object *)s;
+
+   if (sync->bo && drm_intel_gem_bo_wait(sync->bo, timeout) == 0) {
+      s->StatusFlag = 1;
+      drm_intel_bo_unreference(sync->bo);
+      sync->bo = NULL;
+   }
+}
+
+/* We have nothing to do for WaitSync.  Our GL command stream is sequential,
+ * so given that the sync object has already flushed the batchbuffer,
+ * any batchbuffers coming after this waitsync will naturally not occur until
+ * the previous one is done.
+ */
+static void intel_server_wait_sync(struct gl_context *ctx, struct gl_sync_object *s,
+                                GLbitfield flags, GLuint64 timeout)
+{
+}
+
+static void intel_check_sync(struct gl_context *ctx, struct gl_sync_object *s)
+{
+   struct intel_sync_object *sync = (struct intel_sync_object *)s;
+
+   if (sync->bo && !drm_intel_bo_busy(sync->bo)) {
+      drm_intel_bo_unreference(sync->bo);
+      sync->bo = NULL;
+      s->StatusFlag = 1;
+   }
+}
+
+void intel_init_syncobj_functions(struct dd_function_table *functions)
+{
+   functions->NewSyncObject = intel_new_sync_object;
+   functions->DeleteSyncObject = intel_delete_sync_object;
+   functions->FenceSync = intel_fence_sync;
+   functions->CheckSync = intel_check_sync;
+   functions->ClientWaitSync = intel_client_wait_sync;
+   functions->ServerWaitSync = intel_server_wait_sync;
+}
deleted file mode 120000 (symlink)
index d77ce749a3e0a9b2a6eacae06e9b1177af3775fb..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_tex.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..24f13dfee8993933345666fb0f0847223594978d
--- /dev/null
@@ -0,0 +1,189 @@
+#include "swrast/swrast.h"
+#include "main/renderbuffer.h"
+#include "main/texobj.h"
+#include "main/teximage.h"
+#include "main/mipmap.h"
+#include "drivers/common/meta.h"
+#include "intel_context.h"
+#include "intel_mipmap_tree.h"
+#include "intel_tex.h"
+#include "intel_fbo.h"
+
+#define FILE_DEBUG_FLAG DEBUG_TEXTURE
+
+static struct gl_texture_image *
+intelNewTextureImage(struct gl_context * ctx)
+{
+   DBG("%s\n", __FUNCTION__);
+   (void) ctx;
+   return (struct gl_texture_image *) CALLOC_STRUCT(intel_texture_image);
+}
+
+static void
+intelDeleteTextureImage(struct gl_context * ctx, struct gl_texture_image *img)
+{
+   /* nothing special (yet) for intel_texture_image */
+   _mesa_delete_texture_image(ctx, img);
+}
+
+
+static struct gl_texture_object *
+intelNewTextureObject(struct gl_context * ctx, GLuint name, GLenum target)
+{
+   struct intel_texture_object *obj = CALLOC_STRUCT(intel_texture_object);
+
+   (void) ctx;
+
+   DBG("%s\n", __FUNCTION__);
+
+   if (obj == NULL)
+      return NULL;
+
+   _mesa_initialize_texture_object(&obj->base, name, target);
+
+   obj->needs_validate = true;
+
+   return &obj->base;
+}
+
+static void 
+intelDeleteTextureObject(struct gl_context *ctx,
+                        struct gl_texture_object *texObj)
+{
+   struct intel_texture_object *intelObj = intel_texture_object(texObj);
+
+   intel_miptree_release(&intelObj->mt);
+   _mesa_delete_texture_object(ctx, texObj);
+}
+
+static GLboolean
+intel_alloc_texture_image_buffer(struct gl_context *ctx,
+                                struct gl_texture_image *image)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_texture_image *intel_image = intel_texture_image(image);
+   struct gl_texture_object *texobj = image->TexObject;
+   struct intel_texture_object *intel_texobj = intel_texture_object(texobj);
+
+   assert(image->Border == 0);
+
+   /* Quantize sample count */
+   if (image->NumSamples) {
+      image->NumSamples = intel_quantize_num_samples(intel->intelScreen, image->NumSamples);
+      if (!image->NumSamples)
+         return false;
+   }
+
+   /* Because the driver uses AllocTextureImageBuffer() internally, it may end
+    * up mismatched with FreeTextureImageBuffer(), but that is safe to call
+    * multiple times.
+    */
+   ctx->Driver.FreeTextureImageBuffer(ctx, image);
+
+   if (!_swrast_init_texture_image(image))
+      return false;
+
+   if (intel_texobj->mt &&
+       intel_miptree_match_image(intel_texobj->mt, image)) {
+      intel_miptree_reference(&intel_image->mt, intel_texobj->mt);
+      DBG("%s: alloc obj %p level %d %dx%dx%d using object's miptree %p\n",
+          __FUNCTION__, texobj, image->Level,
+          image->Width, image->Height, image->Depth, intel_texobj->mt);
+   } else {
+      intel_image->mt = intel_miptree_create_for_teximage(intel, intel_texobj,
+                                                          intel_image,
+                                                          false);
+
+      /* Even if the object currently has a mipmap tree associated
+       * with it, this one is a more likely candidate to represent the
+       * whole object since our level didn't fit what was there
+       * before, and any lower levels would fit into our miptree.
+       */
+      intel_miptree_reference(&intel_texobj->mt, intel_image->mt);
+
+      DBG("%s: alloc obj %p level %d %dx%dx%d using new miptree %p\n",
+          __FUNCTION__, texobj, image->Level,
+          image->Width, image->Height, image->Depth, intel_image->mt);
+   }
+
+   intel_texobj->needs_validate = true;
+
+   return true;
+}
+
+static void
+intel_free_texture_image_buffer(struct gl_context * ctx,
+                               struct gl_texture_image *texImage)
+{
+   struct intel_texture_image *intelImage = intel_texture_image(texImage);
+
+   DBG("%s\n", __FUNCTION__);
+
+   intel_miptree_release(&intelImage->mt);
+
+   _swrast_free_texture_image_buffer(ctx, texImage);
+}
+
+/**
+ * Map texture memory/buffer into user space.
+ * Note: the region of interest parameters are ignored here.
+ * \param mode  bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT
+ * \param mapOut  returns start of mapping of region of interest
+ * \param rowStrideOut  returns row stride in bytes
+ */
+static void
+intel_map_texture_image(struct gl_context *ctx,
+                       struct gl_texture_image *tex_image,
+                       GLuint slice,
+                       GLuint x, GLuint y, GLuint w, GLuint h,
+                       GLbitfield mode,
+                       GLubyte **map,
+                       GLint *stride)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_texture_image *intel_image = intel_texture_image(tex_image);
+   struct intel_mipmap_tree *mt = intel_image->mt;
+
+   /* Our texture data is always stored in a miptree. */
+   assert(mt);
+
+   /* Check that our caller wasn't confused about how to map a 1D texture. */
+   assert(tex_image->TexObject->Target != GL_TEXTURE_1D_ARRAY ||
+         h == 1);
+
+   /* intel_miptree_map operates on a unified "slice" number that references the
+    * cube face, since it's all just slices to the miptree code.
+    */
+   if (tex_image->TexObject->Target == GL_TEXTURE_CUBE_MAP)
+      slice = tex_image->Face;
+
+   intel_miptree_map(intel, mt, tex_image->Level, slice, x, y, w, h, mode,
+                    (void **)map, stride);
+}
+
+static void
+intel_unmap_texture_image(struct gl_context *ctx,
+                         struct gl_texture_image *tex_image, GLuint slice)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_texture_image *intel_image = intel_texture_image(tex_image);
+   struct intel_mipmap_tree *mt = intel_image->mt;
+
+   if (tex_image->TexObject->Target == GL_TEXTURE_CUBE_MAP)
+      slice = tex_image->Face;
+
+   intel_miptree_unmap(intel, mt, tex_image->Level, slice);
+}
+
+void
+intelInitTextureFuncs(struct dd_function_table *functions)
+{
+   functions->NewTextureObject = intelNewTextureObject;
+   functions->NewTextureImage = intelNewTextureImage;
+   functions->DeleteTextureImage = intelDeleteTextureImage;
+   functions->DeleteTexture = intelDeleteTextureObject;
+   functions->AllocTextureImageBuffer = intel_alloc_texture_image_buffer;
+   functions->FreeTextureImageBuffer = intel_free_texture_image_buffer;
+   functions->MapTextureImage = intel_map_texture_image;
+   functions->UnmapTextureImage = intel_unmap_texture_image;
+}
deleted file mode 120000 (symlink)
index 87196c5d1ed194a93bacad3a8bdf6bce80168ed5..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_tex_copy.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..d018cece1cb5137294b35ed930790fcb9d5774b5
--- /dev/null
@@ -0,0 +1,132 @@
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#include "main/mtypes.h"
+#include "main/enums.h"
+#include "main/image.h"
+#include "main/teximage.h"
+#include "main/texstate.h"
+#include "main/fbobject.h"
+
+#include "drivers/common/meta.h"
+
+#include "intel_screen.h"
+#include "intel_context.h"
+#include "intel_mipmap_tree.h"
+#include "intel_regions.h"
+#include "intel_fbo.h"
+#include "intel_tex.h"
+#include "intel_blit.h"
+#ifndef I915
+#include "brw_context.h"
+#endif
+
+#define FILE_DEBUG_FLAG DEBUG_TEXTURE
+
+
+static bool
+intel_copy_texsubimage(struct intel_context *intel,
+                       struct intel_texture_image *intelImage,
+                       GLint dstx, GLint dsty, GLint slice,
+                       struct intel_renderbuffer *irb,
+                       GLint x, GLint y, GLsizei width, GLsizei height)
+{
+   const GLenum internalFormat = intelImage->base.Base.InternalFormat;
+
+   intel_prepare_render(intel);
+
+   /* glCopyTexSubImage() can be called on a multisampled renderbuffer (if
+    * that renderbuffer is associated with the window system framebuffer),
+    * however the hardware blitter can't handle this case, so fall back to
+    * meta (which can, since it uses ReadPixels).
+    */
+   if (irb->Base.Base.NumSamples != 0)
+      return false;
+
+   /* glCopyTexSubImage() can't be called on a multisampled texture. */
+   assert(intelImage->base.Base.NumSamples == 0);
+
+   if (!intelImage->mt || !irb || !irb->mt) {
+      if (unlikely(INTEL_DEBUG & DEBUG_PERF))
+        fprintf(stderr, "%s fail %p %p (0x%08x)\n",
+                __FUNCTION__, intelImage->mt, irb, internalFormat);
+      return false;
+   }
+
+   /* blit from src buffer to texture */
+   if (!intel_miptree_blit(intel,
+                           irb->mt, irb->mt_level, irb->mt_layer,
+                           x, y, irb->Base.Base.Name == 0,
+                           intelImage->mt, intelImage->base.Base.Level,
+                           intelImage->base.Base.Face + slice,
+                           dstx, dsty, false,
+                           width, height, GL_COPY)) {
+      return false;
+   }
+
+   return true;
+}
+
+
+static void
+intelCopyTexSubImage(struct gl_context *ctx, GLuint dims,
+                     struct gl_texture_image *texImage,
+                     GLint xoffset, GLint yoffset, GLint slice,
+                     struct gl_renderbuffer *rb,
+                     GLint x, GLint y,
+                     GLsizei width, GLsizei height)
+{
+   struct intel_context *intel = intel_context(ctx);
+
+#ifndef I915
+   /* Try BLORP first.  It can handle almost everything. */
+   if (brw_blorp_copytexsubimage(intel, rb, texImage, slice, x, y,
+                                 xoffset, yoffset, width, height))
+      return;
+#endif
+
+   /* Next, try the BLT engine. */
+   if (intel_copy_texsubimage(intel,
+                              intel_texture_image(texImage),
+                              xoffset, yoffset, slice,
+                              intel_renderbuffer(rb), x, y, width, height)) {
+      return;
+   }
+
+   /* Finally, fall back to meta.  This will likely be slow. */
+   perf_debug("%s - fallback to swrast\n", __FUNCTION__);
+   _mesa_meta_CopyTexSubImage(ctx, dims, texImage,
+                              xoffset, yoffset, slice,
+                              rb, x, y, width, height);
+}
+
+
+void
+intelInitTextureCopyImageFuncs(struct dd_function_table *functions)
+{
+   functions->CopyTexSubImage = intelCopyTexSubImage;
+}
deleted file mode 120000 (symlink)
index 567abe4974e7ce941a54dadbcf47cebab2084879..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_tex_image.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..b91b2b5dccbd3084f3e10afb67429bf4ec584907
--- /dev/null
@@ -0,0 +1,399 @@
+
+#include "main/glheader.h"
+#include "main/macros.h"
+#include "main/mtypes.h"
+#include "main/enums.h"
+#include "main/bufferobj.h"
+#include "main/context.h"
+#include "main/formats.h"
+#include "main/image.h"
+#include "main/pbo.h"
+#include "main/renderbuffer.h"
+#include "main/texcompress.h"
+#include "main/texgetimage.h"
+#include "main/texobj.h"
+#include "main/teximage.h"
+#include "main/texstore.h"
+
+#include "intel_context.h"
+#include "intel_mipmap_tree.h"
+#include "intel_buffer_objects.h"
+#include "intel_batchbuffer.h"
+#include "intel_tex.h"
+#include "intel_blit.h"
+#include "intel_fbo.h"
+
+#ifndef I915
+#include "brw_context.h"
+#endif
+
+#define FILE_DEBUG_FLAG DEBUG_TEXTURE
+
+/* Work back from the specified level of the image to the baselevel and create a
+ * miptree of that size.
+ */
+struct intel_mipmap_tree *
+intel_miptree_create_for_teximage(struct intel_context *intel,
+                                 struct intel_texture_object *intelObj,
+                                 struct intel_texture_image *intelImage,
+                                 bool expect_accelerated_upload)
+{
+   GLuint firstLevel;
+   GLuint lastLevel;
+   int width, height, depth;
+   GLuint i;
+
+   intel_miptree_get_dimensions_for_image(&intelImage->base.Base,
+                                          &width, &height, &depth);
+
+   DBG("%s\n", __FUNCTION__);
+
+   if (intelImage->base.Base.Level > intelObj->base.BaseLevel &&
+       (width == 1 ||
+        (intelObj->base.Target != GL_TEXTURE_1D && height == 1) ||
+        (intelObj->base.Target == GL_TEXTURE_3D && depth == 1))) {
+      /* For this combination, we're at some lower mipmap level and
+       * some important dimension is 1.  We can't extrapolate up to a
+       * likely base level width/height/depth for a full mipmap stack
+       * from this info, so just allocate this one level.
+       */
+      firstLevel = intelImage->base.Base.Level;
+      lastLevel = intelImage->base.Base.Level;
+   } else {
+      /* If this image disrespects BaseLevel, allocate from level zero.
+       * Usually BaseLevel == 0, so it's unlikely to happen.
+       */
+      if (intelImage->base.Base.Level < intelObj->base.BaseLevel)
+        firstLevel = 0;
+      else
+        firstLevel = intelObj->base.BaseLevel;
+
+      /* Figure out image dimensions at start level. */
+      for (i = intelImage->base.Base.Level; i > firstLevel; i--) {
+        width <<= 1;
+        if (height != 1)
+           height <<= 1;
+        if (depth != 1)
+           depth <<= 1;
+      }
+
+      /* Guess a reasonable value for lastLevel.  This is probably going
+       * to be wrong fairly often and might mean that we have to look at
+       * resizable buffers, or require that buffers implement lazy
+       * pagetable arrangements.
+       */
+      if ((intelObj->base.Sampler.MinFilter == GL_NEAREST ||
+          intelObj->base.Sampler.MinFilter == GL_LINEAR) &&
+         intelImage->base.Base.Level == firstLevel &&
+         (intel->gen < 4 || firstLevel == 0)) {
+        lastLevel = firstLevel;
+      } else {
+        lastLevel = (firstLevel +
+                      _mesa_get_tex_max_num_levels(intelObj->base.Target,
+                                                   width, height, depth) - 1);
+      }
+   }
+
+   return intel_miptree_create(intel,
+                              intelObj->base.Target,
+                              intelImage->base.Base.TexFormat,
+                              firstLevel,
+                              lastLevel,
+                              width,
+                              height,
+                              depth,
+                              expect_accelerated_upload,
+                               intelImage->base.Base.NumSamples,
+                               INTEL_MIPTREE_TILING_ANY);
+}
+
+/* XXX: Do this for TexSubImage also:
+ */
+static bool
+try_pbo_upload(struct gl_context *ctx,
+               struct gl_texture_image *image,
+               const struct gl_pixelstore_attrib *unpack,
+              GLenum format, GLenum type, const void *pixels)
+{
+   struct intel_texture_image *intelImage = intel_texture_image(image);
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj);
+   GLuint src_offset;
+   drm_intel_bo *src_buffer;
+
+   if (!_mesa_is_bufferobj(unpack->BufferObj))
+      return false;
+
+   DBG("trying pbo upload\n");
+
+   if (intel->ctx._ImageTransferState ||
+       unpack->SkipPixels || unpack->SkipRows) {
+      DBG("%s: image transfer\n", __FUNCTION__);
+      return false;
+   }
+
+   ctx->Driver.AllocTextureImageBuffer(ctx, image);
+
+   if (!intelImage->mt) {
+      DBG("%s: no miptree\n", __FUNCTION__);
+      return false;
+   }
+
+   if (!_mesa_format_matches_format_and_type(intelImage->mt->format,
+                                             format, type, false)) {
+      DBG("%s: format mismatch (upload to %s with format 0x%x, type 0x%x)\n",
+         __FUNCTION__, _mesa_get_format_name(intelImage->mt->format),
+         format, type);
+      return false;
+   }
+
+   if (image->TexObject->Target == GL_TEXTURE_1D_ARRAY ||
+       image->TexObject->Target == GL_TEXTURE_2D_ARRAY) {
+      DBG("%s: no support for array textures\n", __FUNCTION__);
+      return false;
+   }
+
+   src_buffer = intel_bufferobj_source(intel, pbo, 64, &src_offset);
+   /* note: potential 64-bit ptr to 32-bit int cast */
+   src_offset += (GLuint) (unsigned long) pixels;
+
+   int src_stride =
+      _mesa_image_row_stride(unpack, image->Width, format, type);
+
+   struct intel_mipmap_tree *pbo_mt =
+      intel_miptree_create_for_bo(intel,
+                                  src_buffer,
+                                  intelImage->mt->format,
+                                  src_offset,
+                                  image->Width, image->Height,
+                                  src_stride, I915_TILING_NONE);
+   if (!pbo_mt)
+      return false;
+
+   if (!intel_miptree_blit(intel,
+                           pbo_mt, 0, 0,
+                           0, 0, false,
+                           intelImage->mt, image->Level, image->Face,
+                           0, 0, false,
+                           image->Width, image->Height, GL_COPY)) {
+      DBG("%s: blit failed\n", __FUNCTION__);
+      return false;
+   }
+
+   intel_miptree_release(&pbo_mt);
+
+   DBG("%s: success\n", __FUNCTION__);
+   return true;
+}
+
+static void
+intelTexImage(struct gl_context * ctx,
+              GLuint dims,
+              struct gl_texture_image *texImage,
+              GLenum format, GLenum type, const void *pixels,
+              const struct gl_pixelstore_attrib *unpack)
+{
+   bool ok;
+
+   DBG("%s target %s level %d %dx%dx%d\n", __FUNCTION__,
+       _mesa_lookup_enum_by_nr(texImage->TexObject->Target),
+       texImage->Level, texImage->Width, texImage->Height, texImage->Depth);
+
+   ok = intel_texsubimage_tiled_memcpy(ctx, dims, texImage,
+                                       0, 0, 0, /*x,y,z offsets*/
+                                       texImage->Width,
+                                       texImage->Height,
+                                       texImage->Depth,
+                                       format, type, pixels, unpack,
+                                       true /*for_glTexImage*/);
+   if (ok)
+      return;
+
+   /* Attempt to use the blitter for PBO image uploads.
+    */
+   if (dims <= 2 &&
+       try_pbo_upload(ctx, texImage, unpack, format, type, pixels)) {
+      return;
+   }
+
+   DBG("%s: upload image %dx%dx%d pixels %p\n",
+       __FUNCTION__, texImage->Width, texImage->Height, texImage->Depth,
+       pixels);
+
+   _mesa_store_teximage(ctx, dims, texImage,
+                        format, type, pixels, unpack);
+}
+
+
+/**
+ * Binds a region to a texture image, like it was uploaded by glTexImage2D().
+ *
+ * Used for GLX_EXT_texture_from_pixmap and EGL image extensions,
+ */
+static void
+intel_set_texture_image_region(struct gl_context *ctx,
+                              struct gl_texture_image *image,
+                              struct intel_region *region,
+                              GLenum target,
+                              GLenum internalFormat,
+                              gl_format format,
+                               uint32_t offset,
+                               GLuint width,
+                               GLuint height,
+                               GLuint tile_x,
+                               GLuint tile_y)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_texture_image *intel_image = intel_texture_image(image);
+   struct gl_texture_object *texobj = image->TexObject;
+   struct intel_texture_object *intel_texobj = intel_texture_object(texobj);
+   bool has_surface_tile_offset = false;
+   uint32_t draw_x, draw_y;
+
+   _mesa_init_teximage_fields(&intel->ctx, image,
+                             width, height, 1,
+                             0, internalFormat, format);
+
+   ctx->Driver.FreeTextureImageBuffer(ctx, image);
+
+   intel_image->mt = intel_miptree_create_layout(intel, target, image->TexFormat,
+                                                 0, 0,
+                                                 width, height, 1,
+                                                 true, 0 /* num_samples */);
+   if (intel_image->mt == NULL)
+       return;
+   intel_region_reference(&intel_image->mt->region, region);
+   intel_image->mt->total_width = width;
+   intel_image->mt->total_height = height;
+   intel_image->mt->level[0].slice[0].x_offset = tile_x;
+   intel_image->mt->level[0].slice[0].y_offset = tile_y;
+
+   intel_miptree_get_tile_offsets(intel_image->mt, 0, 0, &draw_x, &draw_y);
+#ifndef I915
+   has_surface_tile_offset = brw_context(ctx)->has_surface_tile_offset;
+#endif
+
+   /* From "OES_EGL_image" error reporting. We report GL_INVALID_OPERATION
+    * for EGL images from non-tile aligned sufaces in gen4 hw and earlier which has
+    * trouble resolving back to destination image due to alignment issues.
+    */
+   if (!has_surface_tile_offset &&
+       (draw_x != 0 || draw_y != 0)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, __func__);
+      intel_miptree_release(&intel_image->mt);
+      return;
+   }
+
+   intel_texobj->needs_validate = true;
+
+   intel_image->mt->offset = offset;
+   assert(region->pitch % region->cpp == 0);
+   intel_image->base.RowStride = region->pitch / region->cpp;
+
+   /* Immediately validate the image to the object. */
+   intel_miptree_reference(&intel_texobj->mt, intel_image->mt);
+}
+
+void
+intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
+                  GLint texture_format,
+                  __DRIdrawable *dPriv)
+{
+   struct gl_framebuffer *fb = dPriv->driverPrivate;
+   struct intel_context *intel = pDRICtx->driverPrivate;
+   struct gl_context *ctx = &intel->ctx;
+   struct intel_texture_object *intelObj;
+   struct intel_renderbuffer *rb;
+   struct gl_texture_object *texObj;
+   struct gl_texture_image *texImage;
+   int level = 0, internalFormat = 0;
+   gl_format texFormat = MESA_FORMAT_NONE;
+
+   texObj = _mesa_get_current_tex_object(ctx, target);
+   intelObj = intel_texture_object(texObj);
+
+   if (!intelObj)
+      return;
+
+   if (dPriv->lastStamp != dPriv->dri2.stamp ||
+       !pDRICtx->driScreenPriv->dri2.useInvalidate)
+      intel_update_renderbuffers(pDRICtx, dPriv);
+
+   rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
+   /* If the region isn't set, then intel_update_renderbuffers was unable
+    * to get the buffers for the drawable.
+    */
+   if (!rb || !rb->mt)
+      return;
+
+   if (rb->mt->cpp == 4) {
+      if (texture_format == __DRI_TEXTURE_FORMAT_RGB) {
+         internalFormat = GL_RGB;
+         texFormat = MESA_FORMAT_XRGB8888;
+      }
+      else {
+         internalFormat = GL_RGBA;
+         texFormat = MESA_FORMAT_ARGB8888;
+      }
+   } else if (rb->mt->cpp == 2) {
+      internalFormat = GL_RGB;
+      texFormat = MESA_FORMAT_RGB565;
+   }
+
+   _mesa_lock_texture(&intel->ctx, texObj);
+   texImage = _mesa_get_tex_image(ctx, texObj, target, level);
+   intel_miptree_make_shareable(intel, rb->mt);
+   intel_set_texture_image_region(ctx, texImage, rb->mt->region, target,
+                                  internalFormat, texFormat, 0,
+                                  rb->mt->region->width,
+                                  rb->mt->region->height,
+                                  0, 0);
+   _mesa_unlock_texture(&intel->ctx, texObj);
+}
+
+void
+intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
+{
+   /* The old interface didn't have the format argument, so copy our
+    * implementation's behavior at the time.
+    */
+   intelSetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
+}
+
+static void
+intel_image_target_texture_2d(struct gl_context *ctx, GLenum target,
+                             struct gl_texture_object *texObj,
+                             struct gl_texture_image *texImage,
+                             GLeglImageOES image_handle)
+{
+   struct intel_context *intel = intel_context(ctx);
+   __DRIscreen *screen;
+   __DRIimage *image;
+
+   screen = intel->intelScreen->driScrnPriv;
+   image = screen->dri2.image->lookupEGLImage(screen, image_handle,
+                                             screen->loaderPrivate);
+   if (image == NULL)
+      return;
+
+   /* Disallow depth/stencil textures: we don't have a way to pass the
+    * separate stencil miptree of a GL_DEPTH_STENCIL texture through.
+    */
+   if (image->has_depthstencil) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, __func__);
+      return;
+   }
+
+   intel_set_texture_image_region(ctx, texImage, image->region,
+                                 target, image->internal_format,
+                                  image->format, image->offset,
+                                  image->width,  image->height,
+                                  image->tile_x, image->tile_y);
+}
+
+void
+intelInitTextureImageFuncs(struct dd_function_table *functions)
+{
+   functions->TexImage = intelTexImage;
+   functions->EGLImageTargetTexture2D = intel_image_target_texture_2d;
+}
deleted file mode 120000 (symlink)
index fe61b441945e5da392ab2885bc12cca826004a55..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_tex_layout.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..fbb6520e7a1f62d9213e473d37a80e07bb68a7d3
--- /dev/null
@@ -0,0 +1,214 @@
+/**************************************************************************
+ * 
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+ /*
+  * Authors:
+  *   Keith Whitwell <keith@tungstengraphics.com>
+  *   Michel Dänzer <michel@tungstengraphics.com>
+  */
+
+#include "intel_mipmap_tree.h"
+#include "intel_tex_layout.h"
+#include "intel_context.h"
+
+#include "main/image.h"
+#include "main/macros.h"
+
+static unsigned int
+intel_horizontal_texture_alignment_unit(struct intel_context *intel,
+                                       gl_format format)
+{
+   /**
+    * From the "Alignment Unit Size" section of various specs, namely:
+    * - Gen3 Spec: "Memory Data Formats" Volume,         Section 1.20.1.4
+    * - i965 and G45 PRMs:             Volume 1,         Section 6.17.3.4.
+    * - Ironlake and Sandybridge PRMs: Volume 1, Part 1, Section 7.18.3.4
+    * - BSpec (for Ivybridge and slight variations in separate stencil)
+    *
+    * +----------------------------------------------------------------------+
+    * |                                        | alignment unit width  ("i") |
+    * | Surface Property                       |-----------------------------|
+    * |                                        | 915 | 965 | ILK | SNB | IVB |
+    * +----------------------------------------------------------------------+
+    * | YUV 4:2:2 format                       |  8  |  4  |  4  |  4  |  4  |
+    * | BC1-5 compressed format (DXTn/S3TC)    |  4  |  4  |  4  |  4  |  4  |
+    * | FXT1  compressed format                |  8  |  8  |  8  |  8  |  8  |
+    * | Depth Buffer (16-bit)                  |  4  |  4  |  4  |  4  |  8  |
+    * | Depth Buffer (other)                   |  4  |  4  |  4  |  4  |  4  |
+    * | Separate Stencil Buffer                | N/A | N/A |  8  |  8  |  8  |
+    * | All Others                             |  4  |  4  |  4  |  4  |  4  |
+    * +----------------------------------------------------------------------+
+    *
+    * On IVB+, non-special cases can be overridden by setting the SURFACE_STATE
+    * "Surface Horizontal Alignment" field to HALIGN_4 or HALIGN_8.
+    */
+    if (_mesa_is_format_compressed(format)) {
+       /* The hardware alignment requirements for compressed textures
+        * happen to match the block boundaries.
+        */
+      unsigned int i, j;
+      _mesa_get_format_block_size(format, &i, &j);
+      return i;
+    }
+
+   if (format == MESA_FORMAT_S8)
+      return 8;
+
+   /* The depth alignment requirements in the table above are for rendering to
+    * depth miplevels using the LOD control fields.  We don't use LOD control
+    * fields, and instead use page offsets plus intra-tile x/y offsets, which
+    * require that the low 3 bits are zero.  To reduce the number of x/y
+    * offset workaround blits we do, align the X to 8, which depth texturing
+    * can handle (sadly, it can't handle 8 in the Y direction).
+    */
+   if (intel->gen >= 7 &&
+       _mesa_get_format_base_format(format) == GL_DEPTH_COMPONENT)
+      return 8;
+
+   return 4;
+}
+
+static unsigned int
+intel_vertical_texture_alignment_unit(struct intel_context *intel,
+                                     gl_format format)
+{
+   /**
+    * From the "Alignment Unit Size" section of various specs, namely:
+    * - Gen3 Spec: "Memory Data Formats" Volume,         Section 1.20.1.4
+    * - i965 and G45 PRMs:             Volume 1,         Section 6.17.3.4.
+    * - Ironlake and Sandybridge PRMs: Volume 1, Part 1, Section 7.18.3.4
+    * - BSpec (for Ivybridge and slight variations in separate stencil)
+    *
+    * +----------------------------------------------------------------------+
+    * |                                        | alignment unit height ("j") |
+    * | Surface Property                       |-----------------------------|
+    * |                                        | 915 | 965 | ILK | SNB | IVB |
+    * +----------------------------------------------------------------------+
+    * | BC1-5 compressed format (DXTn/S3TC)    |  4  |  4  |  4  |  4  |  4  |
+    * | FXT1  compressed format                |  4  |  4  |  4  |  4  |  4  |
+    * | Depth Buffer                           |  2  |  2  |  2  |  4  |  4  |
+    * | Separate Stencil Buffer                | N/A | N/A | N/A |  4  |  8  |
+    * | Multisampled (4x or 8x) render target  | N/A | N/A | N/A |  4  |  4  |
+    * | All Others                             |  2  |  2  |  2  |  2  |  2  |
+    * +----------------------------------------------------------------------+
+    *
+    * On SNB+, non-special cases can be overridden by setting the SURFACE_STATE
+    * "Surface Vertical Alignment" field to VALIGN_2 or VALIGN_4.
+    *
+    * We currently don't support multisampling.
+    */
+   if (_mesa_is_format_compressed(format))
+      return 4;
+
+   if (format == MESA_FORMAT_S8)
+      return intel->gen >= 7 ? 8 : 4;
+
+   GLenum base_format = _mesa_get_format_base_format(format);
+
+   if (intel->gen >= 6 &&
+       (base_format == GL_DEPTH_COMPONENT ||
+       base_format == GL_DEPTH_STENCIL)) {
+      return 4;
+   }
+
+   return 2;
+}
+
+void
+intel_get_texture_alignment_unit(struct intel_context *intel,
+                                gl_format format,
+                                unsigned int *w, unsigned int *h)
+{
+   *w = intel_horizontal_texture_alignment_unit(intel, format);
+   *h = intel_vertical_texture_alignment_unit(intel, format);
+}
+
+void i945_miptree_layout_2d(struct intel_mipmap_tree *mt)
+{
+   GLuint level;
+   GLuint x = 0;
+   GLuint y = 0;
+   GLuint width = mt->physical_width0;
+   GLuint height = mt->physical_height0;
+   GLuint depth = mt->physical_depth0; /* number of array layers. */
+
+   mt->total_width = mt->physical_width0;
+
+   if (mt->compressed) {
+       mt->total_width = ALIGN(mt->physical_width0, mt->align_w);
+   }
+
+   /* May need to adjust width to accomodate the placement of
+    * the 2nd mipmap.  This occurs when the alignment
+    * constraints of mipmap placement push the right edge of the
+    * 2nd mipmap out past the width of its parent.
+    */
+   if (mt->first_level != mt->last_level) {
+       GLuint mip1_width;
+
+       if (mt->compressed) {
+          mip1_width = ALIGN(minify(mt->physical_width0, 1), mt->align_w) +
+             ALIGN(minify(mt->physical_width0, 2), mt->align_w);
+       } else {
+          mip1_width = ALIGN(minify(mt->physical_width0, 1), mt->align_w) +
+             minify(mt->physical_width0, 2);
+       }
+
+       if (mip1_width > mt->total_width) {
+           mt->total_width = mip1_width;
+       }
+   }
+
+   mt->total_height = 0;
+
+   for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
+      GLuint img_height;
+
+      intel_miptree_set_level_info(mt, level, x, y, width,
+                                  height, depth);
+
+      img_height = ALIGN(height, mt->align_h);
+      if (mt->compressed)
+        img_height /= mt->align_h;
+
+      /* Because the images are packed better, the final offset
+       * might not be the maximal one:
+       */
+      mt->total_height = MAX2(mt->total_height, y + img_height);
+
+      /* Layout_below: step right after second mipmap.
+       */
+      if (level == mt->first_level + 1) {
+        x += ALIGN(width, mt->align_w);
+      }
+      else {
+        y += img_height;
+      }
+
+      width  = minify(width, 1);
+      height = minify(height, 1);
+   }
+}
deleted file mode 120000 (symlink)
index b3a8a3d7ca7ac339f4d30e3c6f8c3047c5123807..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_tex_subimage.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..f936e9b17e6602085e3a67cbbcb2902a63323fc7
--- /dev/null
@@ -0,0 +1,335 @@
+
+/**************************************************************************
+ * 
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+#include "main/bufferobj.h"
+#include "main/macros.h"
+#include "main/mtypes.h"
+#include "main/pbo.h"
+#include "main/texobj.h"
+#include "main/texstore.h"
+#include "main/texcompress.h"
+#include "main/enums.h"
+
+#include "intel_batchbuffer.h"
+#include "intel_context.h"
+#include "intel_tex.h"
+#include "intel_mipmap_tree.h"
+#include "intel_blit.h"
+
+#define FILE_DEBUG_FLAG DEBUG_TEXTURE
+
+static bool
+intel_blit_texsubimage(struct gl_context * ctx,
+                      struct gl_texture_image *texImage,
+                      GLint xoffset, GLint yoffset,
+                      GLint width, GLint height,
+                      GLenum format, GLenum type, const void *pixels,
+                      const struct gl_pixelstore_attrib *packing)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_texture_image *intelImage = intel_texture_image(texImage);
+
+   /* Try to do a blit upload of the subimage if the texture is
+    * currently busy.
+    */
+   if (!intelImage->mt)
+      return false;
+
+   /* The blitter can't handle Y tiling */
+   if (intelImage->mt->region->tiling == I915_TILING_Y)
+      return false;
+
+   if (texImage->TexObject->Target != GL_TEXTURE_2D)
+      return false;
+
+   /* On gen6, it's probably not worth swapping to the blit ring to do
+    * this because of all the overhead involved.
+    */
+   if (intel->gen >= 6)
+      return false;
+
+   if (!drm_intel_bo_busy(intelImage->mt->region->bo))
+      return false;
+
+   DBG("BLT subimage %s target %s level %d offset %d,%d %dx%d\n",
+       __FUNCTION__,
+       _mesa_lookup_enum_by_nr(texImage->TexObject->Target),
+       texImage->Level, xoffset, yoffset, width, height);
+
+   pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1,
+                                       format, type, pixels, packing,
+                                       "glTexSubImage");
+   if (!pixels)
+      return false;
+
+   struct intel_mipmap_tree *temp_mt =
+      intel_miptree_create(intel, GL_TEXTURE_2D, texImage->TexFormat,
+                           0, 0,
+                           width, height, 1,
+                           false, 0, INTEL_MIPTREE_TILING_NONE);
+   if (!temp_mt)
+      goto err;
+
+   GLubyte *dst = intel_miptree_map_raw(intel, temp_mt);
+   if (!dst)
+      goto err;
+
+   if (!_mesa_texstore(ctx, 2, texImage->_BaseFormat,
+                      texImage->TexFormat,
+                      temp_mt->region->pitch,
+                      &dst,
+                      width, height, 1,
+                      format, type, pixels, packing)) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
+   }
+
+   intel_miptree_unmap_raw(intel, temp_mt);
+
+   bool ret;
+
+   ret = intel_miptree_blit(intel,
+                            temp_mt, 0, 0,
+                            0, 0, false,
+                            intelImage->mt, texImage->Level, texImage->Face,
+                            xoffset, yoffset, false,
+                            width, height, GL_COPY);
+   assert(ret);
+
+   intel_miptree_release(&temp_mt);
+   _mesa_unmap_teximage_pbo(ctx, packing);
+
+   return ret;
+
+err:
+   _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
+   intel_miptree_release(&temp_mt);
+   _mesa_unmap_teximage_pbo(ctx, packing);
+   return false;
+}
+
+/**
+ * \brief A fast path for glTexImage and glTexSubImage.
+ *
+ * \param for_glTexImage Was this called from glTexImage or glTexSubImage?
+ *
+ * This fast path is taken when the hardware natively supports the texture
+ * format (such as GL_BGRA) and when the texture memory is X-tiled. It uploads
+ * the texture data by mapping the texture memory without a GTT fence, thus
+ * acquiring a tiled view of the memory, and then memcpy'ing sucessive
+ * subspans within each tile.
+ *
+ * This is a performance win over the conventional texture upload path because
+ * it avoids the performance penalty of writing through the write-combine
+ * buffer. In the conventional texture upload path,
+ * texstore.c:store_texsubimage(), the texture memory is mapped through a GTT
+ * fence, thus acquiring a linear view of the memory, then each row in the
+ * image is memcpy'd. In this fast path, we replace each row's memcpy with
+ * a sequence of memcpy's over each bit6 swizzle span in the row.
+ *
+ * This fast path's use case is Google Chrome's paint rectangles.  Chrome (as
+ * of version 21) renders each page as a tiling of 256x256 GL_BGRA textures.
+ * Each page's content is initially uploaded with glTexImage2D and damaged
+ * regions are updated with glTexSubImage2D. On some workloads, the
+ * performance gain of this fastpath on Sandybridge is over 5x.
+ */
+bool
+intel_texsubimage_tiled_memcpy(struct gl_context * ctx,
+                               GLuint dims,
+                               struct gl_texture_image *texImage,
+                               GLint xoffset, GLint yoffset, GLint zoffset,
+                               GLsizei width, GLsizei height, GLsizei depth,
+                               GLenum format, GLenum type,
+                               const GLvoid *pixels,
+                               const struct gl_pixelstore_attrib *packing,
+                               bool for_glTexImage)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_texture_image *image = intel_texture_image(texImage);
+
+   /* The miptree's buffer. */
+   drm_intel_bo *bo;
+
+   int error = 0;
+
+   /* This fastpath is restricted to a specific texture type: level 0 of
+    * a 2D BGRA texture. It could be generalized to support more types by
+    * varying the arithmetic loop below.
+    */
+   if (!intel->has_llc ||
+       format != GL_BGRA ||
+       type != GL_UNSIGNED_BYTE ||
+       texImage->TexFormat != MESA_FORMAT_ARGB8888 ||
+       texImage->TexObject->Target != GL_TEXTURE_2D ||
+       texImage->Level != 0 ||
+       pixels == NULL ||
+       _mesa_is_bufferobj(packing->BufferObj) ||
+       packing->Alignment > 4 ||
+       packing->SkipPixels > 0 ||
+       packing->SkipRows > 0 ||
+       (packing->RowLength != 0 && packing->RowLength != width) ||
+       packing->SwapBytes ||
+       packing->LsbFirst ||
+       packing->Invert)
+      return false;
+
+   if (for_glTexImage)
+      ctx->Driver.AllocTextureImageBuffer(ctx, texImage);
+
+   if (!image->mt ||
+       image->mt->region->tiling != I915_TILING_X) {
+      /* The algorithm below is written only for X-tiled memory. */
+      return false;
+   }
+
+   /* Since we are going to write raw data to the miptree, we need to resolve
+    * any pending fast color clears before we start.
+    */
+   intel_miptree_resolve_color(intel, image->mt);
+
+   bo = image->mt->region->bo;
+
+   if (drm_intel_bo_references(intel->batch.bo, bo)) {
+      perf_debug("Flushing before mapping a referenced bo.\n");
+      intel_batchbuffer_flush(intel);
+   }
+
+   if (unlikely(intel->perf_debug)) {
+      if (drm_intel_bo_busy(bo)) {
+         perf_debug("Mapping a busy BO, causing a stall on the GPU.\n");
+      }
+   }
+
+   error = drm_intel_bo_map(bo, true /*write_enable*/);
+   if (error || bo->virtual == NULL) {
+      DBG("%s: failed to map bo\n", __FUNCTION__);
+      return false;
+   }
+
+   /* We postponed printing this message until having committed to executing
+    * the function.
+    */
+   DBG("%s: level=%d offset=(%d,%d) (w,h)=(%d,%d)\n",
+       __FUNCTION__, texImage->Level, xoffset, yoffset, width, height);
+
+   /* In the tiling algorithm below, some variables are in units of pixels,
+    * others are in units of bytes, and others (such as height) are unitless.
+    * Each variable name is suffixed with its units.
+    */
+
+   const uint32_t x_max_pixels = xoffset + width;
+   const uint32_t y_max_pixels = yoffset + height;
+
+   const uint32_t tile_size_bytes = 4096;
+
+   const uint32_t tile_width_bytes = 512;
+   const uint32_t tile_width_pixels = 128;
+
+   const uint32_t tile_height = 8;
+
+   const uint32_t cpp = 4; /* chars per pixel of GL_BGRA */
+   const uint32_t swizzle_width_pixels = 16;
+
+   const uint32_t stride_bytes = image->mt->region->pitch;
+   const uint32_t width_tiles = stride_bytes / tile_width_bytes;
+
+   for (uint32_t y_pixels = yoffset; y_pixels < y_max_pixels; ++y_pixels) {
+      const uint32_t y_offset_bytes = (y_pixels / tile_height) * width_tiles * tile_size_bytes
+                                    + (y_pixels % tile_height) * tile_width_bytes;
+
+      for (uint32_t x_pixels = xoffset; x_pixels < x_max_pixels; x_pixels += swizzle_width_pixels) {
+         const uint32_t x_offset_bytes = (x_pixels / tile_width_pixels) * tile_size_bytes
+                                       + (x_pixels % tile_width_pixels) * cpp;
+
+         intptr_t offset_bytes = y_offset_bytes + x_offset_bytes;
+         if (intel->has_swizzling) {
+#if 0
+            /* Clear, unoptimized version. */
+            bool bit6 = (offset_bytes >> 6) & 1;
+            bool bit9 = (offset_bytes >> 9) & 1;
+            bool bit10 = (offset_bytes >> 10) & 1;
+
+            if (bit9 ^ bit10)
+               offset_bytes ^= (1 << 6);
+#else
+            /* Optimized, obfuscated version. */
+            offset_bytes ^= ((offset_bytes >> 3) ^ (offset_bytes >> 4))
+                          & (1 << 6);
+#endif
+         }
+
+         const uint32_t swizzle_bound_pixels = ALIGN(x_pixels + 1, swizzle_width_pixels);
+         const uint32_t memcpy_bound_pixels = MIN2(x_max_pixels, swizzle_bound_pixels);
+         const uint32_t copy_size = cpp * (memcpy_bound_pixels - x_pixels);
+
+         memcpy(bo->virtual + offset_bytes, pixels, copy_size);
+         pixels += copy_size;
+         x_pixels -= (x_pixels % swizzle_width_pixels);
+      }
+   }
+
+   drm_intel_bo_unmap(bo);
+   return true;
+}
+
+static void
+intelTexSubImage(struct gl_context * ctx,
+                 GLuint dims,
+                 struct gl_texture_image *texImage,
+                 GLint xoffset, GLint yoffset, GLint zoffset,
+                 GLsizei width, GLsizei height, GLsizei depth,
+                 GLenum format, GLenum type,
+                 const GLvoid * pixels,
+                 const struct gl_pixelstore_attrib *packing)
+{
+   bool ok;
+
+   ok = intel_texsubimage_tiled_memcpy(ctx, dims, texImage,
+                                       xoffset, yoffset, zoffset,
+                                       width, height, depth,
+                                       format, type, pixels, packing,
+                                       false /*for_glTexImage*/);
+   if (ok)
+     return;
+
+   /* The intel_blit_texsubimage() function only handles 2D images */
+   if (dims != 2 || !intel_blit_texsubimage(ctx, texImage,
+                              xoffset, yoffset,
+                              width, height,
+                              format, type, pixels, packing)) {
+      _mesa_store_texsubimage(ctx, dims, texImage,
+                              xoffset, yoffset, zoffset,
+                              width, height, depth,
+                              format, type, pixels, packing);
+   }
+}
+
+void
+intelInitTextureSubImageFuncs(struct dd_function_table *functions)
+{
+   functions->TexSubImage = intelTexSubImage;
+}
deleted file mode 120000 (symlink)
index 41a75674c275b6c88ccd379c7a5a656a856ce46f..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-../intel/intel_tex_validate.c
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..a8a8647eb3cfcd74aeb56f5810605076f2b36472
--- /dev/null
@@ -0,0 +1,141 @@
+#include "main/mtypes.h"
+#include "main/macros.h"
+#include "main/samplerobj.h"
+#include "main/texobj.h"
+
+#include "intel_context.h"
+#include "intel_mipmap_tree.h"
+#include "intel_blit.h"
+#include "intel_tex.h"
+#include "intel_tex_layout.h"
+
+#define FILE_DEBUG_FLAG DEBUG_TEXTURE
+
+/**
+ * When validating, we only care about the texture images that could
+ * be seen, so for non-mipmapped modes we want to ignore everything
+ * but BaseLevel.
+ */
+static void
+intel_update_max_level(struct intel_texture_object *intelObj,
+                      struct gl_sampler_object *sampler)
+{
+   struct gl_texture_object *tObj = &intelObj->base;
+   int maxlevel;
+
+   if (sampler->MinFilter == GL_NEAREST ||
+       sampler->MinFilter == GL_LINEAR) {
+      maxlevel = tObj->BaseLevel;
+   } else {
+      maxlevel = tObj->_MaxLevel;
+   }
+
+   if (intelObj->_MaxLevel != maxlevel) {
+      intelObj->_MaxLevel = maxlevel;
+      intelObj->needs_validate = true;
+   }
+}
+
+/*  
+ */
+GLuint
+intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
+{
+   struct gl_context *ctx = &intel->ctx;
+   struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current;
+   struct intel_texture_object *intelObj = intel_texture_object(tObj);
+   struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit);
+   GLuint face, i;
+   GLuint nr_faces = 0;
+   struct intel_texture_image *firstImage;
+   int width, height, depth;
+
+   /* TBOs require no validation -- they always just point to their BO. */
+   if (tObj->Target == GL_TEXTURE_BUFFER)
+      return true;
+
+   /* We know/require this is true by now: 
+    */
+   assert(intelObj->base._BaseComplete);
+
+   /* What levels must the tree include at a minimum?
+    */
+   intel_update_max_level(intelObj, sampler);
+   if (intelObj->mt && intelObj->mt->first_level != tObj->BaseLevel)
+      intelObj->needs_validate = true;
+
+   if (!intelObj->needs_validate)
+      return true;
+
+   firstImage = intel_texture_image(tObj->Image[0][tObj->BaseLevel]);
+
+   /* Check tree can hold all active levels.  Check tree matches
+    * target, imageFormat, etc.
+    *
+    * For pre-gen4, we have to match first_level == tObj->BaseLevel,
+    * because we don't have the control that gen4 does to make min/mag
+    * determination happen at a nonzero (hardware) baselevel.  Because
+    * of that, we just always relayout on baselevel change.
+    */
+   if (intelObj->mt &&
+       (!intel_miptree_match_image(intelObj->mt, &firstImage->base.Base) ||
+       intelObj->mt->first_level != tObj->BaseLevel ||
+       intelObj->mt->last_level < intelObj->_MaxLevel)) {
+      intel_miptree_release(&intelObj->mt);
+   }
+
+
+   /* May need to create a new tree:
+    */
+   if (!intelObj->mt) {
+      intel_miptree_get_dimensions_for_image(&firstImage->base.Base,
+                                            &width, &height, &depth);
+
+      perf_debug("Creating new %s %dx%dx%d %d..%d miptree to handle finalized "
+                 "texture miptree.\n",
+                 _mesa_get_format_name(firstImage->base.Base.TexFormat),
+                 width, height, depth, tObj->BaseLevel, intelObj->_MaxLevel);
+
+      intelObj->mt = intel_miptree_create(intel,
+                                          intelObj->base.Target,
+                                         firstImage->base.Base.TexFormat,
+                                          tObj->BaseLevel,
+                                          intelObj->_MaxLevel,
+                                          width,
+                                          height,
+                                          depth,
+                                         true,
+                                          0 /* num_samples */,
+                                          INTEL_MIPTREE_TILING_ANY);
+      if (!intelObj->mt)
+         return false;
+   }
+
+   /* Pull in any images not in the object's tree:
+    */
+   nr_faces = _mesa_num_tex_faces(intelObj->base.Target);
+   for (face = 0; face < nr_faces; face++) {
+      for (i = tObj->BaseLevel; i <= intelObj->_MaxLevel; i++) {
+         struct intel_texture_image *intelImage =
+            intel_texture_image(intelObj->base.Image[face][i]);
+        /* skip too small size mipmap */
+        if (intelImage == NULL)
+                break;
+
+         if (intelObj->mt != intelImage->mt) {
+            intel_miptree_copy_teximage(intel, intelImage, intelObj->mt,
+                                        false /* invalidate */);
+         }
+
+         /* After we're done, we'd better agree that our layout is
+          * appropriate, or we'll end up hitting this function again on the
+          * next draw
+          */
+         assert(intel_miptree_match_image(intelObj->mt, &intelImage->base.Base));
+      }
+   }
+
+   intelObj->needs_validate = false;
+
+   return true;
+}
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
deleted file mode 100644 (file)
index 8c6524e..0000000
+++ /dev/null
@@ -1,560 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-#include "intel_context.h"
-#include "intel_batchbuffer.h"
-#include "intel_buffer_objects.h"
-#include "intel_reg.h"
-#include "intel_bufmgr.h"
-#include "intel_buffers.h"
-
-static void
-intel_batchbuffer_reset(struct intel_context *intel);
-
-struct cached_batch_item {
-   struct cached_batch_item *next;
-   uint16_t header;
-   uint16_t size;
-};
-
-static void clear_cache( struct intel_context *intel )
-{
-   struct cached_batch_item *item = intel->batch.cached_items;
-
-   while (item) {
-      struct cached_batch_item *next = item->next;
-      free(item);
-      item = next;
-   }
-
-   intel->batch.cached_items = NULL;
-}
-
-void
-intel_batchbuffer_init(struct intel_context *intel)
-{
-   intel_batchbuffer_reset(intel);
-
-   if (intel->gen >= 6) {
-      /* We can't just use brw_state_batch to get a chunk of space for
-       * the gen6 workaround because it involves actually writing to
-       * the buffer, and the kernel doesn't let us write to the batch.
-       */
-      intel->batch.workaround_bo = drm_intel_bo_alloc(intel->bufmgr,
-                                                     "pipe_control workaround",
-                                                     4096, 4096);
-   }
-
-   if (!intel->has_llc) {
-      intel->batch.cpu_map = malloc(intel->maxBatchSize);
-      intel->batch.map = intel->batch.cpu_map;
-   }
-}
-
-static void
-intel_batchbuffer_reset(struct intel_context *intel)
-{
-   if (intel->batch.last_bo != NULL) {
-      drm_intel_bo_unreference(intel->batch.last_bo);
-      intel->batch.last_bo = NULL;
-   }
-   intel->batch.last_bo = intel->batch.bo;
-
-   clear_cache(intel);
-
-   intel->batch.bo = drm_intel_bo_alloc(intel->bufmgr, "batchbuffer",
-                                       intel->maxBatchSize, 4096);
-   if (intel->has_llc) {
-      drm_intel_bo_map(intel->batch.bo, true);
-      intel->batch.map = intel->batch.bo->virtual;
-   }
-
-   intel->batch.reserved_space = BATCH_RESERVED;
-   intel->batch.state_batch_offset = intel->batch.bo->size;
-   intel->batch.used = 0;
-   intel->batch.needs_sol_reset = false;
-}
-
-void
-intel_batchbuffer_save_state(struct intel_context *intel)
-{
-   intel->batch.saved.used = intel->batch.used;
-   intel->batch.saved.reloc_count =
-      drm_intel_gem_bo_get_reloc_count(intel->batch.bo);
-}
-
-void
-intel_batchbuffer_reset_to_saved(struct intel_context *intel)
-{
-   drm_intel_gem_bo_clear_relocs(intel->batch.bo, intel->batch.saved.reloc_count);
-
-   intel->batch.used = intel->batch.saved.used;
-
-   /* Cached batch state is dead, since we just cleared some unknown part of the
-    * batchbuffer.  Assume that the caller resets any other state necessary.
-    */
-   clear_cache(intel);
-}
-
-void
-intel_batchbuffer_free(struct intel_context *intel)
-{
-   free(intel->batch.cpu_map);
-   drm_intel_bo_unreference(intel->batch.last_bo);
-   drm_intel_bo_unreference(intel->batch.bo);
-   drm_intel_bo_unreference(intel->batch.workaround_bo);
-   clear_cache(intel);
-}
-
-static void
-do_batch_dump(struct intel_context *intel)
-{
-   struct drm_intel_decode *decode;
-   struct intel_batchbuffer *batch = &intel->batch;
-   int ret;
-
-   decode = drm_intel_decode_context_alloc(intel->intelScreen->deviceID);
-   if (!decode)
-      return;
-
-   ret = drm_intel_bo_map(batch->bo, false);
-   if (ret == 0) {
-      drm_intel_decode_set_batch_pointer(decode,
-                                        batch->bo->virtual,
-                                        batch->bo->offset,
-                                        batch->used);
-   } else {
-      fprintf(stderr,
-             "WARNING: failed to map batchbuffer (%s), "
-             "dumping uploaded data instead.\n", strerror(ret));
-
-      drm_intel_decode_set_batch_pointer(decode,
-                                        batch->map,
-                                        batch->bo->offset,
-                                        batch->used);
-   }
-
-   drm_intel_decode(decode);
-
-   drm_intel_decode_context_free(decode);
-
-   if (ret == 0) {
-      drm_intel_bo_unmap(batch->bo);
-
-      if (intel->vtbl.debug_batch != NULL)
-        intel->vtbl.debug_batch(intel);
-   }
-}
-
-/* TODO: Push this whole function into bufmgr.
- */
-static int
-do_flush_locked(struct intel_context *intel)
-{
-   struct intel_batchbuffer *batch = &intel->batch;
-   int ret = 0;
-
-   if (intel->has_llc) {
-      drm_intel_bo_unmap(batch->bo);
-   } else {
-      ret = drm_intel_bo_subdata(batch->bo, 0, 4*batch->used, batch->map);
-      if (ret == 0 && batch->state_batch_offset != batch->bo->size) {
-        ret = drm_intel_bo_subdata(batch->bo,
-                                   batch->state_batch_offset,
-                                   batch->bo->size - batch->state_batch_offset,
-                                   (char *)batch->map + batch->state_batch_offset);
-      }
-   }
-
-   if (!intel->intelScreen->no_hw) {
-      int flags;
-
-      if (intel->gen < 6 || !batch->is_blit) {
-        flags = I915_EXEC_RENDER;
-      } else {
-        flags = I915_EXEC_BLT;
-      }
-
-      if (batch->needs_sol_reset)
-        flags |= I915_EXEC_GEN7_SOL_RESET;
-
-      if (ret == 0) {
-         if (unlikely(INTEL_DEBUG & DEBUG_AUB) && intel->vtbl.annotate_aub)
-            intel->vtbl.annotate_aub(intel);
-        if (intel->hw_ctx == NULL || batch->is_blit) {
-           ret = drm_intel_bo_mrb_exec(batch->bo, 4 * batch->used, NULL, 0, 0,
-                                       flags);
-        } else {
-           ret = drm_intel_gem_bo_context_exec(batch->bo, intel->hw_ctx,
-                                               4 * batch->used, flags);
-        }
-      }
-   }
-
-   if (unlikely(INTEL_DEBUG & DEBUG_BATCH))
-      do_batch_dump(intel);
-
-   if (ret != 0) {
-      fprintf(stderr, "intel_do_flush_locked failed: %s\n", strerror(-ret));
-      exit(1);
-   }
-   intel->vtbl.new_batch(intel);
-
-   return ret;
-}
-
-int
-_intel_batchbuffer_flush(struct intel_context *intel,
-                        const char *file, int line)
-{
-   int ret;
-
-   if (intel->batch.used == 0)
-      return 0;
-
-   if (intel->first_post_swapbuffers_batch == NULL) {
-      intel->first_post_swapbuffers_batch = intel->batch.bo;
-      drm_intel_bo_reference(intel->first_post_swapbuffers_batch);
-   }
-
-   if (unlikely(INTEL_DEBUG & DEBUG_BATCH))
-      fprintf(stderr, "%s:%d: Batchbuffer flush with %db used\n", file, line,
-             4*intel->batch.used);
-
-   intel->batch.reserved_space = 0;
-
-   if (intel->vtbl.finish_batch)
-      intel->vtbl.finish_batch(intel);
-
-   /* Mark the end of the buffer. */
-   intel_batchbuffer_emit_dword(intel, MI_BATCH_BUFFER_END);
-   if (intel->batch.used & 1) {
-      /* Round batchbuffer usage to 2 DWORDs. */
-      intel_batchbuffer_emit_dword(intel, MI_NOOP);
-   }
-
-   intel_upload_finish(intel);
-
-   /* Check that we didn't just wrap our batchbuffer at a bad time. */
-   assert(!intel->no_batch_wrap);
-
-   ret = do_flush_locked(intel);
-
-   if (unlikely(INTEL_DEBUG & DEBUG_SYNC)) {
-      fprintf(stderr, "waiting for idle\n");
-      drm_intel_bo_wait_rendering(intel->batch.bo);
-   }
-
-   /* Reset the buffer:
-    */
-   intel_batchbuffer_reset(intel);
-
-   return ret;
-}
-
-
-/*  This is the only way buffers get added to the validate list.
- */
-bool
-intel_batchbuffer_emit_reloc(struct intel_context *intel,
-                             drm_intel_bo *buffer,
-                             uint32_t read_domains, uint32_t write_domain,
-                            uint32_t delta)
-{
-   int ret;
-
-   ret = drm_intel_bo_emit_reloc(intel->batch.bo, 4*intel->batch.used,
-                                buffer, delta,
-                                read_domains, write_domain);
-   assert(ret == 0);
-   (void)ret;
-
-   /*
-    * Using the old buffer offset, write in what the right data would be, in case
-    * the buffer doesn't move and we can short-circuit the relocation processing
-    * in the kernel
-    */
-   intel_batchbuffer_emit_dword(intel, buffer->offset + delta);
-
-   return true;
-}
-
-bool
-intel_batchbuffer_emit_reloc_fenced(struct intel_context *intel,
-                                   drm_intel_bo *buffer,
-                                   uint32_t read_domains,
-                                   uint32_t write_domain,
-                                   uint32_t delta)
-{
-   int ret;
-
-   ret = drm_intel_bo_emit_reloc_fence(intel->batch.bo, 4*intel->batch.used,
-                                      buffer, delta,
-                                      read_domains, write_domain);
-   assert(ret == 0);
-   (void)ret;
-
-   /*
-    * Using the old buffer offset, write in what the right data would
-    * be, in case the buffer doesn't move and we can short-circuit the
-    * relocation processing in the kernel
-    */
-   intel_batchbuffer_emit_dword(intel, buffer->offset + delta);
-
-   return true;
-}
-
-void
-intel_batchbuffer_data(struct intel_context *intel,
-                       const void *data, GLuint bytes, bool is_blit)
-{
-   assert((bytes & 3) == 0);
-   intel_batchbuffer_require_space(intel, bytes, is_blit);
-   __memcpy(intel->batch.map + intel->batch.used, data, bytes);
-   intel->batch.used += bytes >> 2;
-}
-
-void
-intel_batchbuffer_cached_advance(struct intel_context *intel)
-{
-   struct cached_batch_item **prev = &intel->batch.cached_items, *item;
-   uint32_t sz = (intel->batch.used - intel->batch.emit) * sizeof(uint32_t);
-   uint32_t *start = intel->batch.map + intel->batch.emit;
-   uint16_t op = *start >> 16;
-
-   while (*prev) {
-      uint32_t *old;
-
-      item = *prev;
-      old = intel->batch.map + item->header;
-      if (op == *old >> 16) {
-        if (item->size == sz && memcmp(old, start, sz) == 0) {
-           if (prev != &intel->batch.cached_items) {
-              *prev = item->next;
-              item->next = intel->batch.cached_items;
-              intel->batch.cached_items = item;
-           }
-           intel->batch.used = intel->batch.emit;
-           return;
-        }
-
-        goto emit;
-      }
-      prev = &item->next;
-   }
-
-   item = malloc(sizeof(struct cached_batch_item));
-   if (item == NULL)
-      return;
-
-   item->next = intel->batch.cached_items;
-   intel->batch.cached_items = item;
-
-emit:
-   item->size = sz;
-   item->header = intel->batch.emit;
-}
-
-/**
- * Restriction [DevSNB, DevIVB]:
- *
- * Prior to changing Depth/Stencil Buffer state (i.e. any combination of
- * 3DSTATE_DEPTH_BUFFER, 3DSTATE_CLEAR_PARAMS, 3DSTATE_STENCIL_BUFFER,
- * 3DSTATE_HIER_DEPTH_BUFFER) SW must first issue a pipelined depth stall
- * (PIPE_CONTROL with Depth Stall bit set), followed by a pipelined depth
- * cache flush (PIPE_CONTROL with Depth Flush Bit set), followed by
- * another pipelined depth stall (PIPE_CONTROL with Depth Stall bit set),
- * unless SW can otherwise guarantee that the pipeline from WM onwards is
- * already flushed (e.g., via a preceding MI_FLUSH).
- */
-void
-intel_emit_depth_stall_flushes(struct intel_context *intel)
-{
-   assert(intel->gen >= 6 && intel->gen <= 7);
-
-   BEGIN_BATCH(4);
-   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
-   OUT_BATCH(PIPE_CONTROL_DEPTH_STALL);
-   OUT_BATCH(0); /* address */
-   OUT_BATCH(0); /* write data */
-   ADVANCE_BATCH()
-
-   BEGIN_BATCH(4);
-   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
-   OUT_BATCH(PIPE_CONTROL_DEPTH_CACHE_FLUSH);
-   OUT_BATCH(0); /* address */
-   OUT_BATCH(0); /* write data */
-   ADVANCE_BATCH();
-
-   BEGIN_BATCH(4);
-   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
-   OUT_BATCH(PIPE_CONTROL_DEPTH_STALL);
-   OUT_BATCH(0); /* address */
-   OUT_BATCH(0); /* write data */
-   ADVANCE_BATCH();
-}
-
-/**
- * From the BSpec, volume 2a.03: VS Stage Input / State:
- * "[DevIVB] A PIPE_CONTROL with Post-Sync Operation set to 1h and a depth
- *  stall needs to be sent just prior to any 3DSTATE_VS, 3DSTATE_URB_VS,
- *  3DSTATE_CONSTANT_VS, 3DSTATE_BINDING_TABLE_POINTER_VS,
- *  3DSTATE_SAMPLER_STATE_POINTER_VS command.  Only one PIPE_CONTROL needs
- *  to be sent before any combination of VS associated 3DSTATE."
- */
-void
-gen7_emit_vs_workaround_flush(struct intel_context *intel)
-{
-   assert(intel->gen == 7);
-
-   BEGIN_BATCH(4);
-   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
-   OUT_BATCH(PIPE_CONTROL_DEPTH_STALL | PIPE_CONTROL_WRITE_IMMEDIATE);
-   OUT_RELOC(intel->batch.workaround_bo,
-            I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, 0);
-   OUT_BATCH(0); /* write data */
-   ADVANCE_BATCH();
-}
-
-/**
- * Emits a PIPE_CONTROL with a non-zero post-sync operation, for
- * implementing two workarounds on gen6.  From section 1.4.7.1
- * "PIPE_CONTROL" of the Sandy Bridge PRM volume 2 part 1:
- *
- * [DevSNB-C+{W/A}] Before any depth stall flush (including those
- * produced by non-pipelined state commands), software needs to first
- * send a PIPE_CONTROL with no bits set except Post-Sync Operation !=
- * 0.
- *
- * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache Flush Enable
- * =1, a PIPE_CONTROL with any non-zero post-sync-op is required.
- *
- * And the workaround for these two requires this workaround first:
- *
- * [Dev-SNB{W/A}]: Pipe-control with CS-stall bit set must be sent
- * BEFORE the pipe-control with a post-sync op and no write-cache
- * flushes.
- *
- * And this last workaround is tricky because of the requirements on
- * that bit.  From section 1.4.7.2.3 "Stall" of the Sandy Bridge PRM
- * volume 2 part 1:
- *
- *     "1 of the following must also be set:
- *      - Render Target Cache Flush Enable ([12] of DW1)
- *      - Depth Cache Flush Enable ([0] of DW1)
- *      - Stall at Pixel Scoreboard ([1] of DW1)
- *      - Depth Stall ([13] of DW1)
- *      - Post-Sync Operation ([13] of DW1)
- *      - Notify Enable ([8] of DW1)"
- *
- * The cache flushes require the workaround flush that triggered this
- * one, so we can't use it.  Depth stall would trigger the same.
- * Post-sync nonzero is what triggered this second workaround, so we
- * can't use that one either.  Notify enable is IRQs, which aren't
- * really our business.  That leaves only stall at scoreboard.
- */
-void
-intel_emit_post_sync_nonzero_flush(struct intel_context *intel)
-{
-   if (!intel->batch.need_workaround_flush)
-      return;
-
-   BEGIN_BATCH(4);
-   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
-   OUT_BATCH(PIPE_CONTROL_CS_STALL |
-            PIPE_CONTROL_STALL_AT_SCOREBOARD);
-   OUT_BATCH(0); /* address */
-   OUT_BATCH(0); /* write data */
-   ADVANCE_BATCH();
-
-   BEGIN_BATCH(4);
-   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
-   OUT_BATCH(PIPE_CONTROL_WRITE_IMMEDIATE);
-   OUT_RELOC(intel->batch.workaround_bo,
-            I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION, 0);
-   OUT_BATCH(0); /* write data */
-   ADVANCE_BATCH();
-
-   intel->batch.need_workaround_flush = false;
-}
-
-/* Emit a pipelined flush to either flush render and texture cache for
- * reading from a FBO-drawn texture, or flush so that frontbuffer
- * render appears on the screen in DRI1.
- *
- * This is also used for the always_flush_cache driconf debug option.
- */
-void
-intel_batchbuffer_emit_mi_flush(struct intel_context *intel)
-{
-   if (intel->gen >= 6) {
-      if (intel->batch.is_blit) {
-        BEGIN_BATCH_BLT(4);
-        OUT_BATCH(MI_FLUSH_DW);
-        OUT_BATCH(0);
-        OUT_BATCH(0);
-        OUT_BATCH(0);
-        ADVANCE_BATCH();
-      } else {
-        if (intel->gen == 6) {
-           /* Hardware workaround: SNB B-Spec says:
-            *
-            * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache
-            * Flush Enable =1, a PIPE_CONTROL with any non-zero
-            * post-sync-op is required.
-            */
-           intel_emit_post_sync_nonzero_flush(intel);
-        }
-
-        BEGIN_BATCH(4);
-        OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
-        OUT_BATCH(PIPE_CONTROL_INSTRUCTION_FLUSH |
-                  PIPE_CONTROL_WRITE_FLUSH |
-                  PIPE_CONTROL_DEPTH_CACHE_FLUSH |
-                   PIPE_CONTROL_VF_CACHE_INVALIDATE |
-                  PIPE_CONTROL_TC_FLUSH |
-                  PIPE_CONTROL_NO_WRITE |
-                   PIPE_CONTROL_CS_STALL);
-        OUT_BATCH(0); /* write address */
-        OUT_BATCH(0); /* write data */
-        ADVANCE_BATCH();
-      }
-   } else if (intel->gen >= 4) {
-      BEGIN_BATCH(4);
-      OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2) |
-               PIPE_CONTROL_WRITE_FLUSH |
-               PIPE_CONTROL_NO_WRITE);
-      OUT_BATCH(0); /* write address */
-      OUT_BATCH(0); /* write data */
-      OUT_BATCH(0); /* write data */
-      ADVANCE_BATCH();
-   } else {
-      BEGIN_BATCH(1);
-      OUT_BATCH(MI_FLUSH);
-      ADVANCE_BATCH();
-   }
-}
diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c
deleted file mode 100644 (file)
index da56f55..0000000
+++ /dev/null
@@ -1,770 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-
-#include "main/mtypes.h"
-#include "main/context.h"
-#include "main/enums.h"
-#include "main/colormac.h"
-#include "main/fbobject.h"
-
-#include "intel_blit.h"
-#include "intel_buffers.h"
-#include "intel_context.h"
-#include "intel_fbo.h"
-#include "intel_reg.h"
-#include "intel_regions.h"
-#include "intel_batchbuffer.h"
-#include "intel_mipmap_tree.h"
-
-#define FILE_DEBUG_FLAG DEBUG_BLIT
-
-static void
-intel_miptree_set_alpha_to_one(struct intel_context *intel,
-                               struct intel_mipmap_tree *mt,
-                               int x, int y, int width, int height);
-
-static GLuint translate_raster_op(GLenum logicop)
-{
-   switch(logicop) {
-   case GL_CLEAR: return 0x00;
-   case GL_AND: return 0x88;
-   case GL_AND_REVERSE: return 0x44;
-   case GL_COPY: return 0xCC;
-   case GL_AND_INVERTED: return 0x22;
-   case GL_NOOP: return 0xAA;
-   case GL_XOR: return 0x66;
-   case GL_OR: return 0xEE;
-   case GL_NOR: return 0x11;
-   case GL_EQUIV: return 0x99;
-   case GL_INVERT: return 0x55;
-   case GL_OR_REVERSE: return 0xDD;
-   case GL_COPY_INVERTED: return 0x33;
-   case GL_OR_INVERTED: return 0xBB;
-   case GL_NAND: return 0x77;
-   case GL_SET: return 0xFF;
-   default: return 0;
-   }
-}
-
-static uint32_t
-br13_for_cpp(int cpp)
-{
-   switch (cpp) {
-   case 4:
-      return BR13_8888;
-      break;
-   case 2:
-      return BR13_565;
-      break;
-   case 1:
-      return BR13_8;
-      break;
-   default:
-      assert(0);
-      return 0;
-   }
-}
-
-/**
- * Emits the packet for switching the blitter from X to Y tiled or back.
- *
- * This has to be called in a single BEGIN_BATCH_BLT_TILED() /
- * ADVANCE_BATCH_TILED().  This is because BCS_SWCTRL is saved and restored as
- * part of the power context, not a render context, and if the batchbuffer was
- * to get flushed between setting and blitting, or blitting and restoring, our
- * tiling state would leak into other unsuspecting applications (like the X
- * server).
- */
-static void
-set_blitter_tiling(struct intel_context *intel,
-                   bool dst_y_tiled, bool src_y_tiled)
-{
-   assert(intel->gen >= 6);
-
-   /* Idle the blitter before we update how tiling is interpreted. */
-   OUT_BATCH(MI_FLUSH_DW);
-   OUT_BATCH(0);
-   OUT_BATCH(0);
-   OUT_BATCH(0);
-
-   OUT_BATCH(MI_LOAD_REGISTER_IMM | (3 - 2));
-   OUT_BATCH(BCS_SWCTRL);
-   OUT_BATCH((BCS_SWCTRL_DST_Y | BCS_SWCTRL_SRC_Y) << 16 |
-             (dst_y_tiled ? BCS_SWCTRL_DST_Y : 0) |
-             (src_y_tiled ? BCS_SWCTRL_SRC_Y : 0));
-}
-
-#define BEGIN_BATCH_BLT_TILED(n, dst_y_tiled, src_y_tiled) do {         \
-      BEGIN_BATCH_BLT(n + ((dst_y_tiled || src_y_tiled) ? 14 : 0));     \
-      if (dst_y_tiled || src_y_tiled)                                   \
-         set_blitter_tiling(intel, dst_y_tiled, src_y_tiled);           \
-   } while (0)
-
-#define ADVANCE_BATCH_TILED(dst_y_tiled, src_y_tiled) do {              \
-      if (dst_y_tiled || src_y_tiled)                                   \
-         set_blitter_tiling(intel, false, false);                       \
-      ADVANCE_BATCH();                                                  \
-   } while (0)
-
-/**
- * Implements a rectangular block transfer (blit) of pixels between two
- * miptrees.
- *
- * Our blitter can operate on 1, 2, or 4-byte-per-pixel data, with generous,
- * but limited, pitches and sizes allowed.
- *
- * The src/dst coordinates are relative to the given level/slice of the
- * miptree.
- *
- * If @src_flip or @dst_flip is set, then the rectangle within that miptree
- * will be inverted (including scanline order) when copying.  This is common
- * in GL when copying between window system and user-created
- * renderbuffers/textures.
- */
-bool
-intel_miptree_blit(struct intel_context *intel,
-                   struct intel_mipmap_tree *src_mt,
-                   int src_level, int src_slice,
-                   uint32_t src_x, uint32_t src_y, bool src_flip,
-                   struct intel_mipmap_tree *dst_mt,
-                   int dst_level, int dst_slice,
-                   uint32_t dst_x, uint32_t dst_y, bool dst_flip,
-                   uint32_t width, uint32_t height,
-                   GLenum logicop)
-{
-   /* No sRGB decode or encode is done by the hardware blitter, which is
-    * consistent with what we want in the callers (glCopyTexSubImage(),
-    * glBlitFramebuffer(), texture validation, etc.).
-    */
-   gl_format src_format = _mesa_get_srgb_format_linear(src_mt->format);
-   gl_format dst_format = _mesa_get_srgb_format_linear(dst_mt->format);
-
-   /* The blitter doesn't support doing any format conversions.  We do also
-    * support blitting ARGB8888 to XRGB8888 (trivial, the values dropped into
-    * the X channel don't matter), and XRGB8888 to ARGB8888 by setting the A
-    * channel to 1.0 at the end.
-    */
-   if (src_format != dst_format &&
-      ((src_format != MESA_FORMAT_ARGB8888 &&
-        src_format != MESA_FORMAT_XRGB8888) ||
-       (dst_format != MESA_FORMAT_ARGB8888 &&
-        dst_format != MESA_FORMAT_XRGB8888))) {
-      perf_debug("%s: Can't use hardware blitter from %s to %s, "
-                 "falling back.\n", __FUNCTION__,
-                 _mesa_get_format_name(src_format),
-                 _mesa_get_format_name(dst_format));
-      return false;
-   }
-
-   /* According to the Ivy Bridge PRM, Vol1 Part4, section 1.2.1.2 (Graphics
-    * Data Size Limitations):
-    *
-    *    The BLT engine is capable of transferring very large quantities of
-    *    graphics data. Any graphics data read from and written to the
-    *    destination is permitted to represent a number of pixels that
-    *    occupies up to 65,536 scan lines and up to 32,768 bytes per scan line
-    *    at the destination. The maximum number of pixels that may be
-    *    represented per scan line’s worth of graphics data depends on the
-    *    color depth.
-    *
-    * Furthermore, intelEmitCopyBlit (which is called below) uses a signed
-    * 16-bit integer to represent buffer pitch, so it can only handle buffer
-    * pitches < 32k.
-    *
-    * As a result of these two limitations, we can only use the blitter to do
-    * this copy when the region's pitch is less than 32k.
-    */
-   if (src_mt->region->pitch > 32768 ||
-       dst_mt->region->pitch > 32768) {
-      perf_debug("Falling back due to >32k pitch\n");
-      return false;
-   }
-
-   /* The blitter has no idea about HiZ or fast color clears, so we need to
-    * resolve the miptrees before we do anything.
-    */
-   intel_miptree_slice_resolve_depth(intel, src_mt, src_level, src_slice);
-   intel_miptree_slice_resolve_depth(intel, dst_mt, dst_level, dst_slice);
-   intel_miptree_resolve_color(intel, src_mt);
-   intel_miptree_resolve_color(intel, dst_mt);
-
-   if (src_flip)
-      src_y = src_mt->level[src_level].height - src_y - height;
-
-   if (dst_flip)
-      dst_y = dst_mt->level[dst_level].height - dst_y - height;
-
-   int src_pitch = src_mt->region->pitch;
-   if (src_flip != dst_flip)
-      src_pitch = -src_pitch;
-
-   uint32_t src_image_x, src_image_y;
-   intel_miptree_get_image_offset(src_mt, src_level, src_slice,
-                                  &src_image_x, &src_image_y);
-   src_x += src_image_x;
-   src_y += src_image_y;
-
-   uint32_t dst_image_x, dst_image_y;
-   intel_miptree_get_image_offset(dst_mt, dst_level, dst_slice,
-                                  &dst_image_x, &dst_image_y);
-   dst_x += dst_image_x;
-   dst_y += dst_image_y;
-
-   if (!intelEmitCopyBlit(intel,
-                          src_mt->cpp,
-                          src_pitch,
-                          src_mt->region->bo, src_mt->offset,
-                          src_mt->region->tiling,
-                          dst_mt->region->pitch,
-                          dst_mt->region->bo, dst_mt->offset,
-                          dst_mt->region->tiling,
-                          src_x, src_y,
-                          dst_x, dst_y,
-                          width, height,
-                          logicop)) {
-      return false;
-   }
-
-   if (src_mt->format == MESA_FORMAT_XRGB8888 &&
-       dst_mt->format == MESA_FORMAT_ARGB8888) {
-      intel_miptree_set_alpha_to_one(intel, dst_mt,
-                                     dst_x, dst_y,
-                                     width, height);
-   }
-
-   return true;
-}
-
-/* Copy BitBlt
- */
-bool
-intelEmitCopyBlit(struct intel_context *intel,
-                 GLuint cpp,
-                 GLshort src_pitch,
-                 drm_intel_bo *src_buffer,
-                 GLuint src_offset,
-                 uint32_t src_tiling,
-                 GLshort dst_pitch,
-                 drm_intel_bo *dst_buffer,
-                 GLuint dst_offset,
-                 uint32_t dst_tiling,
-                 GLshort src_x, GLshort src_y,
-                 GLshort dst_x, GLshort dst_y,
-                 GLshort w, GLshort h,
-                 GLenum logic_op)
-{
-   GLuint CMD, BR13, pass = 0;
-   int dst_y2 = dst_y + h;
-   int dst_x2 = dst_x + w;
-   drm_intel_bo *aper_array[3];
-   bool dst_y_tiled = dst_tiling == I915_TILING_Y;
-   bool src_y_tiled = src_tiling == I915_TILING_Y;
-   BATCH_LOCALS;
-
-   if (dst_tiling != I915_TILING_NONE) {
-      if (dst_offset & 4095)
-        return false;
-   }
-   if (src_tiling != I915_TILING_NONE) {
-      if (src_offset & 4095)
-        return false;
-   }
-   if ((dst_y_tiled || src_y_tiled) && intel->gen < 6)
-      return false;
-
-   /* do space check before going any further */
-   do {
-       aper_array[0] = intel->batch.bo;
-       aper_array[1] = dst_buffer;
-       aper_array[2] = src_buffer;
-
-       if (dri_bufmgr_check_aperture_space(aper_array, 3) != 0) {
-           intel_batchbuffer_flush(intel);
-           pass++;
-       } else
-           break;
-   } while (pass < 2);
-
-   if (pass >= 2)
-      return false;
-
-   intel_batchbuffer_require_space(intel, 8 * 4, true);
-   DBG("%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
-       __FUNCTION__,
-       src_buffer, src_pitch, src_offset, src_x, src_y,
-       dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h);
-
-   /* Blit pitch must be dword-aligned.  Otherwise, the hardware appears to drop
-    * the low bits.
-    */
-   if (src_pitch % 4 != 0 || dst_pitch % 4 != 0)
-      return false;
-
-   /* For big formats (such as floating point), do the copy using 16 or 32bpp
-    * and multiply the coordinates.
-    */
-   if (cpp > 4) {
-      if (cpp % 4 == 2) {
-         dst_x *= cpp / 2;
-         dst_x2 *= cpp / 2;
-         src_x *= cpp / 2;
-         cpp = 2;
-      } else {
-         assert(cpp % 4 == 0);
-         dst_x *= cpp / 4;
-         dst_x2 *= cpp / 4;
-         src_x *= cpp / 4;
-         cpp = 4;
-      }
-   }
-
-   BR13 = br13_for_cpp(cpp) | translate_raster_op(logic_op) << 16;
-
-   switch (cpp) {
-   case 1:
-   case 2:
-      CMD = XY_SRC_COPY_BLT_CMD;
-      break;
-   case 4:
-      CMD = XY_SRC_COPY_BLT_CMD | XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
-      break;
-   default:
-      return false;
-   }
-
-#ifndef I915
-   if (dst_tiling != I915_TILING_NONE) {
-      CMD |= XY_DST_TILED;
-      dst_pitch /= 4;
-   }
-   if (src_tiling != I915_TILING_NONE) {
-      CMD |= XY_SRC_TILED;
-      src_pitch /= 4;
-   }
-#endif
-
-   if (dst_y2 <= dst_y || dst_x2 <= dst_x) {
-      return true;
-   }
-
-   assert(dst_x < dst_x2);
-   assert(dst_y < dst_y2);
-
-   BEGIN_BATCH_BLT_TILED(8, dst_y_tiled, src_y_tiled);
-
-   OUT_BATCH(CMD | (8 - 2));
-   OUT_BATCH(BR13 | (uint16_t)dst_pitch);
-   OUT_BATCH((dst_y << 16) | dst_x);
-   OUT_BATCH((dst_y2 << 16) | dst_x2);
-   OUT_RELOC_FENCED(dst_buffer,
-                   I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
-                   dst_offset);
-   OUT_BATCH((src_y << 16) | src_x);
-   OUT_BATCH((uint16_t)src_pitch);
-   OUT_RELOC_FENCED(src_buffer,
-                   I915_GEM_DOMAIN_RENDER, 0,
-                   src_offset);
-
-   ADVANCE_BATCH_TILED(dst_y_tiled, src_y_tiled);
-
-   intel_batchbuffer_emit_mi_flush(intel);
-
-   return true;
-}
-
-
-/**
- * Use blitting to clear the renderbuffers named by 'flags'.
- * Note: we can't use the ctx->DrawBuffer->_ColorDrawBufferIndexes field
- * since that might include software renderbuffers or renderbuffers
- * which we're clearing with triangles.
- * \param mask  bitmask of BUFFER_BIT_* values indicating buffers to clear
- */
-GLbitfield
-intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct gl_framebuffer *fb = ctx->DrawBuffer;
-   GLuint clear_depth_value, clear_depth_mask;
-   GLint cx, cy, cw, ch;
-   GLbitfield fail_mask = 0;
-   BATCH_LOCALS;
-
-   /* Note: we don't use this function on Gen7+ hardware, so we can safely
-    * ignore fast color clear issues.
-    */
-   assert(intel->gen < 7);
-
-   /*
-    * Compute values for clearing the buffers.
-    */
-   clear_depth_value = 0;
-   clear_depth_mask = 0;
-   if (mask & BUFFER_BIT_DEPTH) {
-      clear_depth_value = (GLuint) (fb->_DepthMax * ctx->Depth.Clear);
-      clear_depth_mask = XY_BLT_WRITE_RGB;
-   }
-   if (mask & BUFFER_BIT_STENCIL) {
-      clear_depth_value |= (ctx->Stencil.Clear & 0xff) << 24;
-      clear_depth_mask |= XY_BLT_WRITE_ALPHA;
-   }
-
-   cx = fb->_Xmin;
-   if (_mesa_is_winsys_fbo(fb))
-      cy = ctx->DrawBuffer->Height - fb->_Ymax;
-   else
-      cy = fb->_Ymin;
-   cw = fb->_Xmax - fb->_Xmin;
-   ch = fb->_Ymax - fb->_Ymin;
-
-   if (cw == 0 || ch == 0)
-      return 0;
-
-   /* Loop over all renderbuffers */
-   mask &= (1 << BUFFER_COUNT) - 1;
-   while (mask) {
-      GLuint buf = ffs(mask) - 1;
-      bool is_depth_stencil = buf == BUFFER_DEPTH || buf == BUFFER_STENCIL;
-      struct intel_renderbuffer *irb;
-      int x1, y1, x2, y2;
-      uint32_t clear_val;
-      uint32_t BR13, CMD;
-      struct intel_region *region;
-      int pitch, cpp;
-      drm_intel_bo *aper_array[2];
-
-      mask &= ~(1 << buf);
-
-      irb = intel_get_renderbuffer(fb, buf);
-      if (irb && irb->mt) {
-        region = irb->mt->region;
-        assert(region);
-        assert(region->bo);
-      } else {
-         fail_mask |= 1 << buf;
-         continue;
-      }
-
-      /* OK, clear this renderbuffer */
-      x1 = cx + irb->draw_x;
-      y1 = cy + irb->draw_y;
-      x2 = cx + cw + irb->draw_x;
-      y2 = cy + ch + irb->draw_y;
-
-      pitch = region->pitch;
-      cpp = region->cpp;
-
-      DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n",
-         __FUNCTION__,
-         region->bo, pitch,
-         x1, y1, x2 - x1, y2 - y1);
-
-      BR13 = 0xf0 << 16;
-      CMD = XY_COLOR_BLT_CMD;
-
-      /* Setup the blit command */
-      if (cpp == 4) {
-        if (is_depth_stencil) {
-           CMD |= clear_depth_mask;
-        } else {
-           /* clearing RGBA */
-           CMD |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
-        }
-      }
-
-      assert(region->tiling != I915_TILING_Y);
-
-#ifndef I915
-      if (region->tiling != I915_TILING_NONE) {
-        CMD |= XY_DST_TILED;
-        pitch /= 4;
-      }
-#endif
-      BR13 |= pitch;
-
-      if (is_depth_stencil) {
-        clear_val = clear_depth_value;
-      } else {
-        uint8_t clear[4];
-        GLfloat *color = ctx->Color.ClearColor.f;
-
-        _mesa_unclamped_float_rgba_to_ubyte(clear, color);
-
-        switch (intel_rb_format(irb)) {
-        case MESA_FORMAT_ARGB8888:
-        case MESA_FORMAT_XRGB8888:
-           clear_val = PACK_COLOR_8888(clear[3], clear[0],
-                                       clear[1], clear[2]);
-           break;
-        case MESA_FORMAT_RGB565:
-           clear_val = PACK_COLOR_565(clear[0], clear[1], clear[2]);
-           break;
-        case MESA_FORMAT_ARGB4444:
-           clear_val = PACK_COLOR_4444(clear[3], clear[0],
-                                       clear[1], clear[2]);
-           break;
-        case MESA_FORMAT_ARGB1555:
-           clear_val = PACK_COLOR_1555(clear[3], clear[0],
-                                       clear[1], clear[2]);
-           break;
-        case MESA_FORMAT_A8:
-           clear_val = PACK_COLOR_8888(clear[3], clear[3],
-                                       clear[3], clear[3]);
-           break;
-        default:
-           fail_mask |= 1 << buf;
-           continue;
-        }
-      }
-
-      BR13 |= br13_for_cpp(cpp);
-
-      assert(x1 < x2);
-      assert(y1 < y2);
-
-      /* do space check before going any further */
-      aper_array[0] = intel->batch.bo;
-      aper_array[1] = region->bo;
-
-      if (drm_intel_bufmgr_check_aperture_space(aper_array,
-                                               ARRAY_SIZE(aper_array)) != 0) {
-        intel_batchbuffer_flush(intel);
-      }
-
-      BEGIN_BATCH_BLT(6);
-      OUT_BATCH(CMD | (6 - 2));
-      OUT_BATCH(BR13);
-      OUT_BATCH((y1 << 16) | x1);
-      OUT_BATCH((y2 << 16) | x2);
-      OUT_RELOC_FENCED(region->bo,
-                      I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
-                      0);
-      OUT_BATCH(clear_val);
-      ADVANCE_BATCH();
-
-      if (intel->always_flush_cache)
-        intel_batchbuffer_emit_mi_flush(intel);
-
-      if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL)
-        mask &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
-   }
-
-   return fail_mask;
-}
-
-bool
-intelEmitImmediateColorExpandBlit(struct intel_context *intel,
-                                 GLuint cpp,
-                                 GLubyte *src_bits, GLuint src_size,
-                                 GLuint fg_color,
-                                 GLshort dst_pitch,
-                                 drm_intel_bo *dst_buffer,
-                                 GLuint dst_offset,
-                                 uint32_t dst_tiling,
-                                 GLshort x, GLshort y,
-                                 GLshort w, GLshort h,
-                                 GLenum logic_op)
-{
-   int dwords = ALIGN(src_size, 8) / 4;
-   uint32_t opcode, br13, blit_cmd;
-
-   if (dst_tiling != I915_TILING_NONE) {
-      if (dst_offset & 4095)
-        return false;
-      if (dst_tiling == I915_TILING_Y)
-        return false;
-   }
-
-   assert( logic_op - GL_CLEAR >= 0 );
-   assert( logic_op - GL_CLEAR < 0x10 );
-   assert(dst_pitch > 0);
-
-   if (w < 0 || h < 0)
-      return true;
-
-   DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d, %d bytes %d dwords\n",
-       __FUNCTION__,
-       dst_buffer, dst_pitch, dst_offset, x, y, w, h, src_size, dwords);
-
-   intel_batchbuffer_require_space(intel,
-                                  (8 * 4) +
-                                  (3 * 4) +
-                                  dwords * 4, true);
-
-   opcode = XY_SETUP_BLT_CMD;
-   if (cpp == 4)
-      opcode |= XY_BLT_WRITE_ALPHA | XY_BLT_WRITE_RGB;
-#ifndef I915
-   if (dst_tiling != I915_TILING_NONE) {
-      opcode |= XY_DST_TILED;
-      dst_pitch /= 4;
-   }
-#endif
-
-   br13 = dst_pitch | (translate_raster_op(logic_op) << 16) | (1 << 29);
-   br13 |= br13_for_cpp(cpp);
-
-   blit_cmd = XY_TEXT_IMMEDIATE_BLIT_CMD | XY_TEXT_BYTE_PACKED; /* packing? */
-   if (dst_tiling != I915_TILING_NONE)
-      blit_cmd |= XY_DST_TILED;
-
-   BEGIN_BATCH_BLT(8 + 3);
-   OUT_BATCH(opcode | (8 - 2));
-   OUT_BATCH(br13);
-   OUT_BATCH((0 << 16) | 0); /* clip x1, y1 */
-   OUT_BATCH((100 << 16) | 100); /* clip x2, y2 */
-   OUT_RELOC_FENCED(dst_buffer,
-                   I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
-                   dst_offset);
-   OUT_BATCH(0); /* bg */
-   OUT_BATCH(fg_color); /* fg */
-   OUT_BATCH(0); /* pattern base addr */
-
-   OUT_BATCH(blit_cmd | ((3 - 2) + dwords));
-   OUT_BATCH((y << 16) | x);
-   OUT_BATCH(((y + h) << 16) | (x + w));
-   ADVANCE_BATCH();
-
-   intel_batchbuffer_data(intel, src_bits, dwords * 4, true);
-
-   intel_batchbuffer_emit_mi_flush(intel);
-
-   return true;
-}
-
-/* We don't have a memmove-type blit like some other hardware, so we'll do a
- * rectangular blit covering a large space, then emit 1-scanline blit at the
- * end to cover the last if we need.
- */
-void
-intel_emit_linear_blit(struct intel_context *intel,
-                      drm_intel_bo *dst_bo,
-                      unsigned int dst_offset,
-                      drm_intel_bo *src_bo,
-                      unsigned int src_offset,
-                      unsigned int size)
-{
-   struct gl_context *ctx = &intel->ctx;
-   GLuint pitch, height;
-   bool ok;
-
-   /* The pitch given to the GPU must be DWORD aligned, and
-    * we want width to match pitch. Max width is (1 << 15 - 1),
-    * rounding that down to the nearest DWORD is 1 << 15 - 4
-    */
-   pitch = ROUND_DOWN_TO(MIN2(size, (1 << 15) - 1), 4);
-   height = (pitch == 0) ? 1 : size / pitch;
-   ok = intelEmitCopyBlit(intel, 1,
-                         pitch, src_bo, src_offset, I915_TILING_NONE,
-                         pitch, dst_bo, dst_offset, I915_TILING_NONE,
-                         0, 0, /* src x/y */
-                         0, 0, /* dst x/y */
-                         pitch, height, /* w, h */
-                         GL_COPY);
-   if (!ok)
-      _mesa_problem(ctx, "Failed to linear blit %dx%d\n", pitch, height);
-
-   src_offset += pitch * height;
-   dst_offset += pitch * height;
-   size -= pitch * height;
-   assert (size < (1 << 15));
-   pitch = ALIGN(size, 4);
-   if (size != 0) {
-      ok = intelEmitCopyBlit(intel, 1,
-                            pitch, src_bo, src_offset, I915_TILING_NONE,
-                            pitch, dst_bo, dst_offset, I915_TILING_NONE,
-                            0, 0, /* src x/y */
-                            0, 0, /* dst x/y */
-                            size, 1, /* w, h */
-                            GL_COPY);
-      if (!ok)
-         _mesa_problem(ctx, "Failed to linear blit %dx%d\n", size, 1);
-   }
-}
-
-/**
- * Used to initialize the alpha value of an ARGB8888 miptree after copying
- * into it from an XRGB8888 source.
- *
- * This is very common with glCopyTexImage2D().  Note that the coordinates are
- * relative to the start of the miptree, not relative to a slice within the
- * miptree.
- */
-static void
-intel_miptree_set_alpha_to_one(struct intel_context *intel,
-                              struct intel_mipmap_tree *mt,
-                              int x, int y, int width, int height)
-{
-   struct intel_region *region = mt->region;
-   uint32_t BR13, CMD;
-   int pitch, cpp;
-   drm_intel_bo *aper_array[2];
-   BATCH_LOCALS;
-
-   pitch = region->pitch;
-   cpp = region->cpp;
-
-   DBG("%s dst:buf(%p)/%d %d,%d sz:%dx%d\n",
-       __FUNCTION__, region->bo, pitch, x, y, width, height);
-
-   BR13 = br13_for_cpp(cpp) | 0xf0 << 16;
-   CMD = XY_COLOR_BLT_CMD;
-   CMD |= XY_BLT_WRITE_ALPHA;
-
-#ifndef I915
-   if (region->tiling != I915_TILING_NONE) {
-      CMD |= XY_DST_TILED;
-      pitch /= 4;
-   }
-#endif
-   BR13 |= pitch;
-
-   /* do space check before going any further */
-   aper_array[0] = intel->batch.bo;
-   aper_array[1] = region->bo;
-
-   if (drm_intel_bufmgr_check_aperture_space(aper_array,
-                                            ARRAY_SIZE(aper_array)) != 0) {
-      intel_batchbuffer_flush(intel);
-   }
-
-   bool dst_y_tiled = region->tiling == I915_TILING_Y;
-
-   BEGIN_BATCH_BLT_TILED(6, dst_y_tiled, false);
-   OUT_BATCH(CMD | (6 - 2));
-   OUT_BATCH(BR13);
-   OUT_BATCH((y << 16) | x);
-   OUT_BATCH(((y + height) << 16) | (x + width));
-   OUT_RELOC_FENCED(region->bo,
-                   I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
-                   0);
-   OUT_BATCH(0xffffffff); /* white, but only alpha gets written */
-   ADVANCE_BATCH_TILED(dst_y_tiled, false);
-
-   intel_batchbuffer_emit_mi_flush(intel);
-}
diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
deleted file mode 100644 (file)
index f568864..0000000
+++ /dev/null
@@ -1,853 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-
-#include "main/imports.h"
-#include "main/mtypes.h"
-#include "main/macros.h"
-#include "main/bufferobj.h"
-
-#include "intel_blit.h"
-#include "intel_buffer_objects.h"
-#include "intel_batchbuffer.h"
-#include "intel_context.h"
-#include "intel_fbo.h"
-#include "intel_mipmap_tree.h"
-#include "intel_regions.h"
-
-#ifndef I915
-#include "brw_context.h"
-#endif
-
-static GLboolean
-intel_bufferobj_unmap(struct gl_context * ctx, struct gl_buffer_object *obj);
-
-/** Allocates a new drm_intel_bo to store the data for the buffer object. */
-static void
-intel_bufferobj_alloc_buffer(struct intel_context *intel,
-                            struct intel_buffer_object *intel_obj)
-{
-   intel_obj->buffer = drm_intel_bo_alloc(intel->bufmgr, "bufferobj",
-                                         intel_obj->Base.Size, 64);
-
-#ifndef I915
-   /* the buffer might be bound as a uniform buffer, need to update it
-    */
-   {
-      struct brw_context *brw = brw_context(&intel->ctx);
-      brw->state.dirty.brw |= BRW_NEW_UNIFORM_BUFFER;
-   }
-#endif
-}
-
-static void
-release_buffer(struct intel_buffer_object *intel_obj)
-{
-   drm_intel_bo_unreference(intel_obj->buffer);
-   intel_obj->buffer = NULL;
-   intel_obj->offset = 0;
-   intel_obj->source = 0;
-}
-
-/**
- * There is some duplication between mesa's bufferobjects and our
- * bufmgr buffers.  Both have an integer handle and a hashtable to
- * lookup an opaque structure.  It would be nice if the handles and
- * internal structure where somehow shared.
- */
-static struct gl_buffer_object *
-intel_bufferobj_alloc(struct gl_context * ctx, GLuint name, GLenum target)
-{
-   struct intel_buffer_object *obj = CALLOC_STRUCT(intel_buffer_object);
-
-   _mesa_initialize_buffer_object(ctx, &obj->Base, name, target);
-
-   obj->buffer = NULL;
-
-   return &obj->Base;
-}
-
-/**
- * Deallocate/free a vertex/pixel buffer object.
- * Called via glDeleteBuffersARB().
- */
-static void
-intel_bufferobj_free(struct gl_context * ctx, struct gl_buffer_object *obj)
-{
-   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
-
-   assert(intel_obj);
-
-   /* Buffer objects are automatically unmapped when deleting according
-    * to the spec, but Mesa doesn't do UnmapBuffer for us at context destroy
-    * (though it does if you call glDeleteBuffers)
-    */
-   if (obj->Pointer)
-      intel_bufferobj_unmap(ctx, obj);
-
-   free(intel_obj->sys_buffer);
-
-   drm_intel_bo_unreference(intel_obj->buffer);
-   free(intel_obj);
-}
-
-
-
-/**
- * Allocate space for and store data in a buffer object.  Any data that was
- * previously stored in the buffer object is lost.  If data is NULL,
- * memory will be allocated, but no copy will occur.
- * Called via ctx->Driver.BufferData().
- * \return true for success, false if out of memory
- */
-static GLboolean
-intel_bufferobj_data(struct gl_context * ctx,
-                     GLenum target,
-                     GLsizeiptrARB size,
-                     const GLvoid * data,
-                     GLenum usage, struct gl_buffer_object *obj)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
-
-   /* Part of the ABI, but this function doesn't use it.
-    */
-#ifndef I915
-   (void) target;
-#endif
-
-   intel_obj->Base.Size = size;
-   intel_obj->Base.Usage = usage;
-
-   assert(!obj->Pointer); /* Mesa should have unmapped it */
-
-   if (intel_obj->buffer != NULL)
-      release_buffer(intel_obj);
-
-   free(intel_obj->sys_buffer);
-   intel_obj->sys_buffer = NULL;
-
-   if (size != 0) {
-#ifdef I915
-      /* On pre-965, stick VBOs in system memory, as we're always doing
-       * swtnl with their contents anyway.
-       */
-      if (target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER) {
-        intel_obj->sys_buffer = malloc(size);
-        if (intel_obj->sys_buffer != NULL) {
-           if (data != NULL)
-              memcpy(intel_obj->sys_buffer, data, size);
-           return true;
-        }
-      }
-#endif
-      intel_bufferobj_alloc_buffer(intel, intel_obj);
-      if (!intel_obj->buffer)
-         return false;
-
-      if (data != NULL)
-        drm_intel_bo_subdata(intel_obj->buffer, 0, size, data);
-   }
-
-   return true;
-}
-
-
-/**
- * Replace data in a subrange of buffer object.  If the data range
- * specified by size + offset extends beyond the end of the buffer or
- * if data is NULL, no copy is performed.
- * Called via glBufferSubDataARB().
- */
-static void
-intel_bufferobj_subdata(struct gl_context * ctx,
-                        GLintptrARB offset,
-                        GLsizeiptrARB size,
-                        const GLvoid * data, struct gl_buffer_object *obj)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
-   bool busy;
-
-   if (size == 0)
-      return;
-
-   assert(intel_obj);
-
-   /* If we have a single copy in system memory, update that */
-   if (intel_obj->sys_buffer) {
-      if (intel_obj->source)
-        release_buffer(intel_obj);
-
-      if (intel_obj->buffer == NULL) {
-        memcpy((char *)intel_obj->sys_buffer + offset, data, size);
-        return;
-      }
-
-      free(intel_obj->sys_buffer);
-      intel_obj->sys_buffer = NULL;
-   }
-
-   /* Otherwise we need to update the copy in video memory. */
-   busy =
-      drm_intel_bo_busy(intel_obj->buffer) ||
-      drm_intel_bo_references(intel->batch.bo, intel_obj->buffer);
-
-   if (busy) {
-      if (size == intel_obj->Base.Size) {
-        /* Replace the current busy bo with fresh data. */
-        drm_intel_bo_unreference(intel_obj->buffer);
-        intel_bufferobj_alloc_buffer(intel, intel_obj);
-        drm_intel_bo_subdata(intel_obj->buffer, 0, size, data);
-      } else {
-         perf_debug("Using a blit copy to avoid stalling on %ldb "
-                    "glBufferSubData() to a busy buffer object.\n",
-                    (long)size);
-        drm_intel_bo *temp_bo =
-           drm_intel_bo_alloc(intel->bufmgr, "subdata temp", size, 64);
-
-        drm_intel_bo_subdata(temp_bo, 0, size, data);
-
-        intel_emit_linear_blit(intel,
-                               intel_obj->buffer, offset,
-                               temp_bo, 0,
-                               size);
-
-        drm_intel_bo_unreference(temp_bo);
-      }
-   } else {
-      drm_intel_bo_subdata(intel_obj->buffer, offset, size, data);
-   }
-}
-
-
-/**
- * Called via glGetBufferSubDataARB().
- */
-static void
-intel_bufferobj_get_subdata(struct gl_context * ctx,
-                            GLintptrARB offset,
-                            GLsizeiptrARB size,
-                            GLvoid * data, struct gl_buffer_object *obj)
-{
-   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
-   struct intel_context *intel = intel_context(ctx);
-
-   assert(intel_obj);
-   if (intel_obj->sys_buffer)
-      memcpy(data, (char *)intel_obj->sys_buffer + offset, size);
-   else {
-      if (drm_intel_bo_references(intel->batch.bo, intel_obj->buffer)) {
-        intel_batchbuffer_flush(intel);
-      }
-      drm_intel_bo_get_subdata(intel_obj->buffer, offset, size, data);
-   }
-}
-
-
-
-/**
- * Called via glMapBufferRange and glMapBuffer
- *
- * The goal of this extension is to allow apps to accumulate their rendering
- * at the same time as they accumulate their buffer object.  Without it,
- * you'd end up blocking on execution of rendering every time you mapped
- * the buffer to put new data in.
- *
- * We support it in 3 ways: If unsynchronized, then don't bother
- * flushing the batchbuffer before mapping the buffer, which can save blocking
- * in many cases.  If we would still block, and they allow the whole buffer
- * to be invalidated, then just allocate a new buffer to replace the old one.
- * If not, and we'd block, and they allow the subrange of the buffer to be
- * invalidated, then we can make a new little BO, let them write into that,
- * and blit it into the real BO at unmap time.
- */
-static void *
-intel_bufferobj_map_range(struct gl_context * ctx,
-                         GLintptr offset, GLsizeiptr length,
-                         GLbitfield access, struct gl_buffer_object *obj)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
-
-   assert(intel_obj);
-
-   /* _mesa_MapBufferRange (GL entrypoint) sets these, but the vbo module also
-    * internally uses our functions directly.
-    */
-   obj->Offset = offset;
-   obj->Length = length;
-   obj->AccessFlags = access;
-
-   if (intel_obj->sys_buffer) {
-      const bool read_only =
-        (access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == GL_MAP_READ_BIT;
-
-      if (!read_only && intel_obj->source)
-        release_buffer(intel_obj);
-
-      if (!intel_obj->buffer || intel_obj->source) {
-        obj->Pointer = intel_obj->sys_buffer + offset;
-        return obj->Pointer;
-      }
-
-      free(intel_obj->sys_buffer);
-      intel_obj->sys_buffer = NULL;
-   }
-
-   if (intel_obj->buffer == NULL) {
-      obj->Pointer = NULL;
-      return NULL;
-   }
-
-   /* If the access is synchronized (like a normal buffer mapping), then get
-    * things flushed out so the later mapping syncs appropriately through GEM.
-    * If the user doesn't care about existing buffer contents and mapping would
-    * cause us to block, then throw out the old buffer.
-    *
-    * If they set INVALIDATE_BUFFER, we can pitch the current contents to
-    * achieve the required synchronization.
-    */
-   if (!(access & GL_MAP_UNSYNCHRONIZED_BIT)) {
-      if (drm_intel_bo_references(intel->batch.bo, intel_obj->buffer)) {
-        if (access & GL_MAP_INVALIDATE_BUFFER_BIT) {
-           drm_intel_bo_unreference(intel_obj->buffer);
-           intel_bufferobj_alloc_buffer(intel, intel_obj);
-        } else {
-            perf_debug("Stalling on the GPU for mapping a busy buffer "
-                       "object\n");
-           intel_flush(ctx);
-        }
-      } else if (drm_intel_bo_busy(intel_obj->buffer) &&
-                (access & GL_MAP_INVALIDATE_BUFFER_BIT)) {
-        drm_intel_bo_unreference(intel_obj->buffer);
-        intel_bufferobj_alloc_buffer(intel, intel_obj);
-      }
-   }
-
-   /* If the user is mapping a range of an active buffer object but
-    * doesn't require the current contents of that range, make a new
-    * BO, and we'll copy what they put in there out at unmap or
-    * FlushRange time.
-    */
-   if ((access & GL_MAP_INVALIDATE_RANGE_BIT) &&
-       drm_intel_bo_busy(intel_obj->buffer)) {
-      if (access & GL_MAP_FLUSH_EXPLICIT_BIT) {
-        intel_obj->range_map_buffer = malloc(length);
-        obj->Pointer = intel_obj->range_map_buffer;
-      } else {
-        intel_obj->range_map_bo = drm_intel_bo_alloc(intel->bufmgr,
-                                                     "range map",
-                                                     length, 64);
-        if (!(access & GL_MAP_READ_BIT)) {
-           drm_intel_gem_bo_map_gtt(intel_obj->range_map_bo);
-        } else {
-           drm_intel_bo_map(intel_obj->range_map_bo,
-                            (access & GL_MAP_WRITE_BIT) != 0);
-        }
-        obj->Pointer = intel_obj->range_map_bo->virtual;
-      }
-      return obj->Pointer;
-   }
-
-   if (access & GL_MAP_UNSYNCHRONIZED_BIT)
-      drm_intel_gem_bo_map_unsynchronized(intel_obj->buffer);
-   else if (!(access & GL_MAP_READ_BIT)) {
-      drm_intel_gem_bo_map_gtt(intel_obj->buffer);
-   } else {
-      drm_intel_bo_map(intel_obj->buffer, (access & GL_MAP_WRITE_BIT) != 0);
-   }
-
-   obj->Pointer = intel_obj->buffer->virtual + offset;
-   return obj->Pointer;
-}
-
-/* Ideally we'd use a BO to avoid taking up cache space for the temporary
- * data, but FlushMappedBufferRange may be followed by further writes to
- * the pointer, so we would have to re-map after emitting our blit, which
- * would defeat the point.
- */
-static void
-intel_bufferobj_flush_mapped_range(struct gl_context *ctx,
-                                  GLintptr offset, GLsizeiptr length,
-                                  struct gl_buffer_object *obj)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
-   drm_intel_bo *temp_bo;
-
-   /* Unless we're in the range map using a temporary system buffer,
-    * there's no work to do.
-    */
-   if (intel_obj->range_map_buffer == NULL)
-      return;
-
-   if (length == 0)
-      return;
-
-   temp_bo = drm_intel_bo_alloc(intel->bufmgr, "range map flush", length, 64);
-
-   drm_intel_bo_subdata(temp_bo, 0, length, intel_obj->range_map_buffer);
-
-   intel_emit_linear_blit(intel,
-                         intel_obj->buffer, obj->Offset + offset,
-                         temp_bo, 0,
-                         length);
-
-   drm_intel_bo_unreference(temp_bo);
-}
-
-
-/**
- * Called via glUnmapBuffer().
- */
-static GLboolean
-intel_bufferobj_unmap(struct gl_context * ctx, struct gl_buffer_object *obj)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
-
-   assert(intel_obj);
-   assert(obj->Pointer);
-   if (intel_obj->sys_buffer != NULL) {
-      /* always keep the mapping around. */
-   } else if (intel_obj->range_map_buffer != NULL) {
-      /* Since we've emitted some blits to buffers that will (likely) be used
-       * in rendering operations in other cache domains in this batch, emit a
-       * flush.  Once again, we wish for a domain tracker in libdrm to cover
-       * usage inside of a batchbuffer.
-       */
-      intel_batchbuffer_emit_mi_flush(intel);
-      free(intel_obj->range_map_buffer);
-      intel_obj->range_map_buffer = NULL;
-   } else if (intel_obj->range_map_bo != NULL) {
-      drm_intel_bo_unmap(intel_obj->range_map_bo);
-
-      intel_emit_linear_blit(intel,
-                            intel_obj->buffer, obj->Offset,
-                            intel_obj->range_map_bo, 0,
-                            obj->Length);
-
-      /* Since we've emitted some blits to buffers that will (likely) be used
-       * in rendering operations in other cache domains in this batch, emit a
-       * flush.  Once again, we wish for a domain tracker in libdrm to cover
-       * usage inside of a batchbuffer.
-       */
-      intel_batchbuffer_emit_mi_flush(intel);
-
-      drm_intel_bo_unreference(intel_obj->range_map_bo);
-      intel_obj->range_map_bo = NULL;
-   } else if (intel_obj->buffer != NULL) {
-      drm_intel_bo_unmap(intel_obj->buffer);
-   }
-   obj->Pointer = NULL;
-   obj->Offset = 0;
-   obj->Length = 0;
-
-   return true;
-}
-
-drm_intel_bo *
-intel_bufferobj_buffer(struct intel_context *intel,
-                       struct intel_buffer_object *intel_obj,
-                      GLuint flag)
-{
-   if (intel_obj->source)
-      release_buffer(intel_obj);
-
-   if (intel_obj->buffer == NULL) {
-      intel_bufferobj_alloc_buffer(intel, intel_obj);
-      drm_intel_bo_subdata(intel_obj->buffer,
-                          0, intel_obj->Base.Size,
-                          intel_obj->sys_buffer);
-
-      free(intel_obj->sys_buffer);
-      intel_obj->sys_buffer = NULL;
-      intel_obj->offset = 0;
-   }
-
-   return intel_obj->buffer;
-}
-
-#define INTEL_UPLOAD_SIZE (64*1024)
-
-void
-intel_upload_finish(struct intel_context *intel)
-{
-   if (!intel->upload.bo)
-          return;
-
-   if (intel->upload.buffer_len) {
-          drm_intel_bo_subdata(intel->upload.bo,
-                               intel->upload.buffer_offset,
-                               intel->upload.buffer_len,
-                               intel->upload.buffer);
-          intel->upload.buffer_len = 0;
-   }
-
-   drm_intel_bo_unreference(intel->upload.bo);
-   intel->upload.bo = NULL;
-}
-
-static void wrap_buffers(struct intel_context *intel, GLuint size)
-{
-   intel_upload_finish(intel);
-
-   if (size < INTEL_UPLOAD_SIZE)
-      size = INTEL_UPLOAD_SIZE;
-
-   intel->upload.bo = drm_intel_bo_alloc(intel->bufmgr, "upload", size, 0);
-   intel->upload.offset = 0;
-}
-
-void intel_upload_data(struct intel_context *intel,
-                      const void *ptr, GLuint size, GLuint align,
-                      drm_intel_bo **return_bo,
-                      GLuint *return_offset)
-{
-   GLuint base, delta;
-
-   base = (intel->upload.offset + align - 1) / align * align;
-   if (intel->upload.bo == NULL || base + size > intel->upload.bo->size) {
-      wrap_buffers(intel, size);
-      base = 0;
-   }
-
-   drm_intel_bo_reference(intel->upload.bo);
-   *return_bo = intel->upload.bo;
-   *return_offset = base;
-
-   delta = base - intel->upload.offset;
-   if (intel->upload.buffer_len &&
-       intel->upload.buffer_len + delta + size > sizeof(intel->upload.buffer))
-   {
-      drm_intel_bo_subdata(intel->upload.bo,
-                          intel->upload.buffer_offset,
-                          intel->upload.buffer_len,
-                          intel->upload.buffer);
-      intel->upload.buffer_len = 0;
-   }
-
-   if (size < sizeof(intel->upload.buffer))
-   {
-      if (intel->upload.buffer_len == 0)
-        intel->upload.buffer_offset = base;
-      else
-        intel->upload.buffer_len += delta;
-
-      memcpy(intel->upload.buffer + intel->upload.buffer_len, ptr, size);
-      intel->upload.buffer_len += size;
-   }
-   else
-   {
-      drm_intel_bo_subdata(intel->upload.bo, base, size, ptr);
-   }
-
-   intel->upload.offset = base + size;
-}
-
-void *intel_upload_map(struct intel_context *intel, GLuint size, GLuint align)
-{
-   GLuint base, delta;
-   char *ptr;
-
-   base = (intel->upload.offset + align - 1) / align * align;
-   if (intel->upload.bo == NULL || base + size > intel->upload.bo->size) {
-      wrap_buffers(intel, size);
-      base = 0;
-   }
-
-   delta = base - intel->upload.offset;
-   if (intel->upload.buffer_len &&
-       intel->upload.buffer_len + delta + size > sizeof(intel->upload.buffer))
-   {
-      drm_intel_bo_subdata(intel->upload.bo,
-                          intel->upload.buffer_offset,
-                          intel->upload.buffer_len,
-                          intel->upload.buffer);
-      intel->upload.buffer_len = 0;
-   }
-
-   if (size <= sizeof(intel->upload.buffer)) {
-      if (intel->upload.buffer_len == 0)
-        intel->upload.buffer_offset = base;
-      else
-        intel->upload.buffer_len += delta;
-
-      ptr = intel->upload.buffer + intel->upload.buffer_len;
-      intel->upload.buffer_len += size;
-   } else
-      ptr = malloc(size);
-
-   return ptr;
-}
-
-void intel_upload_unmap(struct intel_context *intel,
-                       const void *ptr, GLuint size, GLuint align,
-                       drm_intel_bo **return_bo,
-                       GLuint *return_offset)
-{
-   GLuint base;
-
-   base = (intel->upload.offset + align - 1) / align * align;
-   if (size > sizeof(intel->upload.buffer)) {
-      drm_intel_bo_subdata(intel->upload.bo, base, size, ptr);
-      free((void*)ptr);
-   }
-
-   drm_intel_bo_reference(intel->upload.bo);
-   *return_bo = intel->upload.bo;
-   *return_offset = base;
-
-   intel->upload.offset = base + size;
-}
-
-drm_intel_bo *
-intel_bufferobj_source(struct intel_context *intel,
-                       struct intel_buffer_object *intel_obj,
-                      GLuint align, GLuint *offset)
-{
-   if (intel_obj->buffer == NULL) {
-      intel_upload_data(intel,
-                       intel_obj->sys_buffer, intel_obj->Base.Size, align,
-                       &intel_obj->buffer, &intel_obj->offset);
-      intel_obj->source = 1;
-   }
-
-   *offset = intel_obj->offset;
-   return intel_obj->buffer;
-}
-
-static void
-intel_bufferobj_copy_subdata(struct gl_context *ctx,
-                            struct gl_buffer_object *src,
-                            struct gl_buffer_object *dst,
-                            GLintptr read_offset, GLintptr write_offset,
-                            GLsizeiptr size)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_buffer_object *intel_src = intel_buffer_object(src);
-   struct intel_buffer_object *intel_dst = intel_buffer_object(dst);
-   drm_intel_bo *src_bo, *dst_bo;
-   GLuint src_offset;
-
-   if (size == 0)
-      return;
-
-   /* If we're in system memory, just map and memcpy. */
-   if (intel_src->sys_buffer || intel_dst->sys_buffer) {
-      /* The same buffer may be used, but note that regions copied may
-       * not overlap.
-       */
-      if (src == dst) {
-        char *ptr = intel_bufferobj_map_range(ctx, 0, dst->Size,
-                                              GL_MAP_READ_BIT |
-                                              GL_MAP_WRITE_BIT,
-                                              dst);
-        memmove(ptr + write_offset, ptr + read_offset, size);
-        intel_bufferobj_unmap(ctx, dst);
-      } else {
-        const char *src_ptr;
-        char *dst_ptr;
-
-        src_ptr =  intel_bufferobj_map_range(ctx, 0, src->Size,
-                                             GL_MAP_READ_BIT, src);
-        dst_ptr =  intel_bufferobj_map_range(ctx, 0, dst->Size,
-                                             GL_MAP_WRITE_BIT, dst);
-
-        memcpy(dst_ptr + write_offset, src_ptr + read_offset, size);
-
-        intel_bufferobj_unmap(ctx, src);
-        intel_bufferobj_unmap(ctx, dst);
-      }
-      return;
-   }
-
-   /* Otherwise, we have real BOs, so blit them. */
-
-   dst_bo = intel_bufferobj_buffer(intel, intel_dst, INTEL_WRITE_PART);
-   src_bo = intel_bufferobj_source(intel, intel_src, 64, &src_offset);
-
-   intel_emit_linear_blit(intel,
-                         dst_bo, write_offset,
-                         src_bo, read_offset + src_offset, size);
-
-   /* Since we've emitted some blits to buffers that will (likely) be used
-    * in rendering operations in other cache domains in this batch, emit a
-    * flush.  Once again, we wish for a domain tracker in libdrm to cover
-    * usage inside of a batchbuffer.
-    */
-   intel_batchbuffer_emit_mi_flush(intel);
-}
-
-static GLenum
-intel_buffer_purgeable(drm_intel_bo *buffer)
-{
-   int retained = 0;
-
-   if (buffer != NULL)
-      retained = drm_intel_bo_madvise (buffer, I915_MADV_DONTNEED);
-
-   return retained ? GL_VOLATILE_APPLE : GL_RELEASED_APPLE;
-}
-
-static GLenum
-intel_buffer_object_purgeable(struct gl_context * ctx,
-                              struct gl_buffer_object *obj,
-                              GLenum option)
-{
-   struct intel_buffer_object *intel_obj = intel_buffer_object (obj);
-
-   if (intel_obj->buffer != NULL)
-      return intel_buffer_purgeable(intel_obj->buffer);
-
-   if (option == GL_RELEASED_APPLE) {
-      free(intel_obj->sys_buffer);
-      intel_obj->sys_buffer = NULL;
-
-      return GL_RELEASED_APPLE;
-   } else {
-      /* XXX Create the buffer and madvise(MADV_DONTNEED)? */
-      struct intel_context *intel = intel_context(ctx);
-      drm_intel_bo *bo = intel_bufferobj_buffer(intel, intel_obj, INTEL_READ);
-
-      return intel_buffer_purgeable(bo);
-   }
-}
-
-static GLenum
-intel_texture_object_purgeable(struct gl_context * ctx,
-                               struct gl_texture_object *obj,
-                               GLenum option)
-{
-   struct intel_texture_object *intel;
-
-   (void) ctx;
-   (void) option;
-
-   intel = intel_texture_object(obj);
-   if (intel->mt == NULL || intel->mt->region == NULL)
-      return GL_RELEASED_APPLE;
-
-   return intel_buffer_purgeable(intel->mt->region->bo);
-}
-
-static GLenum
-intel_render_object_purgeable(struct gl_context * ctx,
-                              struct gl_renderbuffer *obj,
-                              GLenum option)
-{
-   struct intel_renderbuffer *intel;
-
-   (void) ctx;
-   (void) option;
-
-   intel = intel_renderbuffer(obj);
-   if (intel->mt == NULL)
-      return GL_RELEASED_APPLE;
-
-   return intel_buffer_purgeable(intel->mt->region->bo);
-}
-
-static GLenum
-intel_buffer_unpurgeable(drm_intel_bo *buffer)
-{
-   int retained;
-
-   retained = 0;
-   if (buffer != NULL)
-      retained = drm_intel_bo_madvise (buffer, I915_MADV_WILLNEED);
-
-   return retained ? GL_RETAINED_APPLE : GL_UNDEFINED_APPLE;
-}
-
-static GLenum
-intel_buffer_object_unpurgeable(struct gl_context * ctx,
-                                struct gl_buffer_object *obj,
-                                GLenum option)
-{
-   (void) ctx;
-   (void) option;
-
-   return intel_buffer_unpurgeable(intel_buffer_object (obj)->buffer);
-}
-
-static GLenum
-intel_texture_object_unpurgeable(struct gl_context * ctx,
-                                 struct gl_texture_object *obj,
-                                 GLenum option)
-{
-   struct intel_texture_object *intel;
-
-   (void) ctx;
-   (void) option;
-
-   intel = intel_texture_object(obj);
-   if (intel->mt == NULL || intel->mt->region == NULL)
-      return GL_UNDEFINED_APPLE;
-
-   return intel_buffer_unpurgeable(intel->mt->region->bo);
-}
-
-static GLenum
-intel_render_object_unpurgeable(struct gl_context * ctx,
-                                struct gl_renderbuffer *obj,
-                                GLenum option)
-{
-   struct intel_renderbuffer *intel;
-
-   (void) ctx;
-   (void) option;
-
-   intel = intel_renderbuffer(obj);
-   if (intel->mt == NULL)
-      return GL_UNDEFINED_APPLE;
-
-   return intel_buffer_unpurgeable(intel->mt->region->bo);
-}
-
-void
-intelInitBufferObjectFuncs(struct dd_function_table *functions)
-{
-   functions->NewBufferObject = intel_bufferobj_alloc;
-   functions->DeleteBuffer = intel_bufferobj_free;
-   functions->BufferData = intel_bufferobj_data;
-   functions->BufferSubData = intel_bufferobj_subdata;
-   functions->GetBufferSubData = intel_bufferobj_get_subdata;
-   functions->MapBufferRange = intel_bufferobj_map_range;
-   functions->FlushMappedBufferRange = intel_bufferobj_flush_mapped_range;
-   functions->UnmapBuffer = intel_bufferobj_unmap;
-   functions->CopyBufferSubData = intel_bufferobj_copy_subdata;
-
-   functions->BufferObjectPurgeable = intel_buffer_object_purgeable;
-   functions->TextureObjectPurgeable = intel_texture_object_purgeable;
-   functions->RenderObjectPurgeable = intel_render_object_purgeable;
-
-   functions->BufferObjectUnpurgeable = intel_buffer_object_unpurgeable;
-   functions->TextureObjectUnpurgeable = intel_texture_object_unpurgeable;
-   functions->RenderObjectUnpurgeable = intel_render_object_unpurgeable;
-}
diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c
deleted file mode 100644 (file)
index fdad480..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-#include "intel_context.h"
-#include "intel_buffers.h"
-#include "intel_fbo.h"
-#include "intel_mipmap_tree.h"
-
-#include "main/fbobject.h"
-#include "main/framebuffer.h"
-#include "main/renderbuffer.h"
-
-/**
- * Return pointer to current color reading region, or NULL.
- */
-struct intel_region *
-intel_readbuf_region(struct intel_context *intel)
-{
-   struct intel_renderbuffer *irb
-      = intel_renderbuffer(intel->ctx.ReadBuffer->_ColorReadBuffer);
-   if (irb && irb->mt)
-      return irb->mt->region;
-   else
-      return NULL;
-}
-
-/**
- * Check if we're about to draw into the front color buffer.
- * If so, set the intel->front_buffer_dirty field to true.
- */
-void
-intel_check_front_buffer_rendering(struct intel_context *intel)
-{
-   const struct gl_framebuffer *fb = intel->ctx.DrawBuffer;
-   if (_mesa_is_winsys_fbo(fb)) {
-      /* drawing to window system buffer */
-      if (fb->_NumColorDrawBuffers > 0) {
-         if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
-           intel->front_buffer_dirty = true;
-        }
-      }
-   }
-}
-
-static void
-intelDrawBuffer(struct gl_context * ctx, GLenum mode)
-{
-   if (ctx->DrawBuffer && _mesa_is_winsys_fbo(ctx->DrawBuffer)) {
-      struct intel_context *const intel = intel_context(ctx);
-      const bool was_front_buffer_rendering =
-       intel->is_front_buffer_rendering;
-
-      intel->is_front_buffer_rendering = (mode == GL_FRONT_LEFT)
-       || (mode == GL_FRONT) || (mode == GL_FRONT_AND_BACK);
-
-      /* If we weren't front-buffer rendering before but we are now,
-       * invalidate our DRI drawable so we'll ask for new buffers
-       * (including the fake front) before we start rendering again.
-       */
-      if (!was_front_buffer_rendering && intel->is_front_buffer_rendering)
-        dri2InvalidateDrawable(intel->driContext->driDrawablePriv);
-   }
-
-   intel_draw_buffer(ctx);
-}
-
-
-static void
-intelReadBuffer(struct gl_context * ctx, GLenum mode)
-{
-   if (ctx->DrawBuffer && _mesa_is_winsys_fbo(ctx->DrawBuffer)) {
-      struct intel_context *const intel = intel_context(ctx);
-      const bool was_front_buffer_reading =
-       intel->is_front_buffer_reading;
-
-      intel->is_front_buffer_reading = (mode == GL_FRONT_LEFT)
-       || (mode == GL_FRONT);
-
-      /* If we weren't front-buffer reading before but we are now,
-       * invalidate our DRI drawable so we'll ask for new buffers
-       * (including the fake front) before we start reading again.
-       */
-      if (!was_front_buffer_reading && intel->is_front_buffer_reading)
-        dri2InvalidateDrawable(intel->driContext->driReadablePriv);
-   }
-}
-
-
-void
-intelInitBufferFuncs(struct dd_function_table *functions)
-{
-   functions->DrawBuffer = intelDrawBuffer;
-   functions->ReadBuffer = intelReadBuffer;
-}
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
deleted file mode 100644 (file)
index 23d8281..0000000
+++ /dev/null
@@ -1,1010 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/extensions.h"
-#include "main/fbobject.h"
-#include "main/framebuffer.h"
-#include "main/imports.h"
-#include "main/points.h"
-#include "main/renderbuffer.h"
-
-#include "swrast/swrast.h"
-#include "swrast_setup/swrast_setup.h"
-#include "tnl/tnl.h"
-#include "drivers/common/driverfuncs.h"
-#include "drivers/common/meta.h"
-
-#include "intel_chipset.h"
-#include "intel_buffers.h"
-#include "intel_tex.h"
-#include "intel_batchbuffer.h"
-#include "intel_clear.h"
-#include "intel_extensions.h"
-#include "intel_pixel.h"
-#include "intel_regions.h"
-#include "intel_buffer_objects.h"
-#include "intel_fbo.h"
-#include "intel_bufmgr.h"
-#include "intel_screen.h"
-#include "intel_mipmap_tree.h"
-
-#include "utils.h"
-#include "../glsl/ralloc.h"
-
-#ifndef INTEL_DEBUG
-int INTEL_DEBUG = (0);
-#endif
-
-
-static const GLubyte *
-intelGetString(struct gl_context * ctx, GLenum name)
-{
-   const struct intel_context *const intel = intel_context(ctx);
-   const char *chipset;
-   static char buffer[128];
-
-   switch (name) {
-   case GL_VENDOR:
-      return (GLubyte *) "Intel Open Source Technology Center";
-      break;
-
-   case GL_RENDERER:
-      switch (intel->intelScreen->deviceID) {
-#undef CHIPSET
-#define CHIPSET(id, symbol, str) case id: chipset = str; break;
-#include "pci_ids/i915_pci_ids.h"
-#include "pci_ids/i965_pci_ids.h"
-      default:
-         chipset = "Unknown Intel Chipset";
-         break;
-      }
-
-      (void) driGetRendererString(buffer, chipset, 0);
-      return (GLubyte *) buffer;
-
-   default:
-      return NULL;
-   }
-}
-
-void
-intel_resolve_for_dri2_flush(struct intel_context *intel,
-                             __DRIdrawable *drawable)
-{
-   if (intel->gen < 6) {
-      /* MSAA and fast color clear are not supported, so don't waste time
-       * checking whether a resolve is needed.
-       */
-      return;
-   }
-
-   struct gl_framebuffer *fb = drawable->driverPrivate;
-   struct intel_renderbuffer *rb;
-
-   /* Usually, only the back buffer will need to be downsampled. However,
-    * the front buffer will also need it if the user has rendered into it.
-    */
-   static const gl_buffer_index buffers[2] = {
-         BUFFER_BACK_LEFT,
-         BUFFER_FRONT_LEFT,
-   };
-
-   for (int i = 0; i < 2; ++i) {
-      rb = intel_get_renderbuffer(fb, buffers[i]);
-      if (rb == NULL || rb->mt == NULL)
-         continue;
-      if (rb->mt->num_samples <= 1)
-         intel_miptree_resolve_color(intel, rb->mt);
-      else
-         intel_miptree_downsample(intel, rb->mt);
-   }
-}
-
-static void
-intel_flush_front(struct gl_context *ctx)
-{
-   struct intel_context *intel = intel_context(ctx);
-    __DRIcontext *driContext = intel->driContext;
-    __DRIdrawable *driDrawable = driContext->driDrawablePriv;
-    __DRIscreen *const screen = intel->intelScreen->driScrnPriv;
-
-    if (intel->front_buffer_dirty && _mesa_is_winsys_fbo(ctx->DrawBuffer)) {
-      if (screen->dri2.loader->flushFrontBuffer != NULL &&
-          driDrawable &&
-          driDrawable->loaderPrivate) {
-
-         /* Resolve before flushing FAKE_FRONT_LEFT to FRONT_LEFT.
-          *
-          * This potentially resolves both front and back buffer. It
-          * is unnecessary to resolve the back, but harms nothing except
-          * performance. And no one cares about front-buffer render
-          * performance.
-          */
-         intel_resolve_for_dri2_flush(intel, driDrawable);
-
-         screen->dri2.loader->flushFrontBuffer(driDrawable,
-                                               driDrawable->loaderPrivate);
-
-        /* We set the dirty bit in intel_prepare_render() if we're
-         * front buffer rendering once we get there.
-         */
-        intel->front_buffer_dirty = false;
-      }
-   }
-}
-
-static unsigned
-intel_bits_per_pixel(const struct intel_renderbuffer *rb)
-{
-   return _mesa_get_format_bytes(intel_rb_format(rb)) * 8;
-}
-
-static void
-intel_query_dri2_buffers(struct intel_context *intel,
-                        __DRIdrawable *drawable,
-                        __DRIbuffer **buffers,
-                        int *count);
-
-static void
-intel_process_dri2_buffer(struct intel_context *intel,
-                         __DRIdrawable *drawable,
-                         __DRIbuffer *buffer,
-                         struct intel_renderbuffer *rb,
-                         const char *buffer_name);
-
-void
-intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
-{
-   struct gl_framebuffer *fb = drawable->driverPrivate;
-   struct intel_renderbuffer *rb;
-   struct intel_context *intel = context->driverPrivate;
-   __DRIbuffer *buffers = NULL;
-   int i, count;
-   const char *region_name;
-
-   /* Set this up front, so that in case our buffers get invalidated
-    * while we're getting new buffers, we don't clobber the stamp and
-    * thus ignore the invalidate. */
-   drawable->lastStamp = drawable->dri2.stamp;
-
-   if (unlikely(INTEL_DEBUG & DEBUG_DRI))
-      fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
-
-   intel_query_dri2_buffers(intel, drawable, &buffers, &count);
-
-   if (buffers == NULL)
-      return;
-
-   for (i = 0; i < count; i++) {
-       switch (buffers[i].attachment) {
-       case __DRI_BUFFER_FRONT_LEFT:
-          rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
-          region_name = "dri2 front buffer";
-          break;
-
-       case __DRI_BUFFER_FAKE_FRONT_LEFT:
-          rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
-          region_name = "dri2 fake front buffer";
-          break;
-
-       case __DRI_BUFFER_BACK_LEFT:
-          rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
-          region_name = "dri2 back buffer";
-          break;
-
-       case __DRI_BUFFER_DEPTH:
-       case __DRI_BUFFER_HIZ:
-       case __DRI_BUFFER_DEPTH_STENCIL:
-       case __DRI_BUFFER_STENCIL:
-       case __DRI_BUFFER_ACCUM:
-       default:
-          fprintf(stderr,
-                  "unhandled buffer attach event, attachment type %d\n",
-                  buffers[i].attachment);
-          return;
-       }
-
-       intel_process_dri2_buffer(intel, drawable, &buffers[i], rb, region_name);
-   }
-
-   driUpdateFramebufferSize(&intel->ctx, drawable);
-}
-
-/**
- * intel_prepare_render should be called anywhere that curent read/drawbuffer
- * state is required.
- */
-void
-intel_prepare_render(struct intel_context *intel)
-{
-   __DRIcontext *driContext = intel->driContext;
-   __DRIdrawable *drawable;
-
-   drawable = driContext->driDrawablePriv;
-   if (drawable && drawable->dri2.stamp != driContext->dri2.draw_stamp) {
-      if (drawable->lastStamp != drawable->dri2.stamp)
-        intel_update_renderbuffers(driContext, drawable);
-      intel_draw_buffer(&intel->ctx);
-      driContext->dri2.draw_stamp = drawable->dri2.stamp;
-   }
-
-   drawable = driContext->driReadablePriv;
-   if (drawable && drawable->dri2.stamp != driContext->dri2.read_stamp) {
-      if (drawable->lastStamp != drawable->dri2.stamp)
-        intel_update_renderbuffers(driContext, drawable);
-      driContext->dri2.read_stamp = drawable->dri2.stamp;
-   }
-
-   /* If we're currently rendering to the front buffer, the rendering
-    * that will happen next will probably dirty the front buffer.  So
-    * mark it as dirty here.
-    */
-   if (intel->is_front_buffer_rendering)
-      intel->front_buffer_dirty = true;
-
-   /* Wait for the swapbuffers before the one we just emitted, so we
-    * don't get too many swaps outstanding for apps that are GPU-heavy
-    * but not CPU-heavy.
-    *
-    * We're using intelDRI2Flush (called from the loader before
-    * swapbuffer) and glFlush (for front buffer rendering) as the
-    * indicator that a frame is done and then throttle when we get
-    * here as we prepare to render the next frame.  At this point for
-    * round trips for swap/copy and getting new buffers are done and
-    * we'll spend less time waiting on the GPU.
-    *
-    * Unfortunately, we don't have a handle to the batch containing
-    * the swap, and getting our hands on that doesn't seem worth it,
-    * so we just us the first batch we emitted after the last swap.
-    */
-   if (intel->need_throttle && intel->first_post_swapbuffers_batch) {
-      if (!intel->disable_throttling)
-         drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch);
-      drm_intel_bo_unreference(intel->first_post_swapbuffers_batch);
-      intel->first_post_swapbuffers_batch = NULL;
-      intel->need_throttle = false;
-   }
-}
-
-static void
-intel_viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
-{
-    struct intel_context *intel = intel_context(ctx);
-    __DRIcontext *driContext = intel->driContext;
-
-    if (intel->saved_viewport)
-       intel->saved_viewport(ctx, x, y, w, h);
-
-    if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) {
-       dri2InvalidateDrawable(driContext->driDrawablePriv);
-       dri2InvalidateDrawable(driContext->driReadablePriv);
-    }
-}
-
-static const struct dri_debug_control debug_control[] = {
-   { "tex",   DEBUG_TEXTURE},
-   { "state", DEBUG_STATE},
-   { "ioctl", DEBUG_IOCTL},
-   { "blit",  DEBUG_BLIT},
-   { "mip",   DEBUG_MIPTREE},
-   { "fall",  DEBUG_PERF},
-   { "perf",  DEBUG_PERF},
-   { "bat",   DEBUG_BATCH},
-   { "pix",   DEBUG_PIXEL},
-   { "buf",   DEBUG_BUFMGR},
-   { "reg",   DEBUG_REGION},
-   { "fbo",   DEBUG_FBO},
-   { "fs",    DEBUG_WM },
-   { "gs",    DEBUG_GS},
-   { "sync",  DEBUG_SYNC},
-   { "prim",  DEBUG_PRIMS },
-   { "vert",  DEBUG_VERTS },
-   { "dri",   DEBUG_DRI },
-   { "sf",    DEBUG_SF },
-   { "stats", DEBUG_STATS },
-   { "wm",    DEBUG_WM },
-   { "urb",   DEBUG_URB },
-   { "vs",    DEBUG_VS },
-   { "clip",  DEBUG_CLIP },
-   { "aub",   DEBUG_AUB },
-   { "shader_time", DEBUG_SHADER_TIME },
-   { "no16",  DEBUG_NO16 },
-   { "blorp", DEBUG_BLORP },
-   { NULL,    0 }
-};
-
-
-static void
-intelInvalidateState(struct gl_context * ctx, GLuint new_state)
-{
-    struct intel_context *intel = intel_context(ctx);
-
-    if (ctx->swrast_context)
-       _swrast_InvalidateState(ctx, new_state);
-   _vbo_InvalidateState(ctx, new_state);
-
-   intel->NewGLState |= new_state;
-
-   if (intel->vtbl.invalidate_state)
-      intel->vtbl.invalidate_state( intel, new_state );
-}
-
-void
-intel_flush_rendering_to_batch(struct gl_context *ctx)
-{
-   struct intel_context *intel = intel_context(ctx);
-
-   if (intel->Fallback)
-      _swrast_flush(ctx);
-
-   if (intel->gen < 4)
-      INTEL_FIREVERTICES(intel);
-}
-
-void
-_intel_flush(struct gl_context *ctx, const char *file, int line)
-{
-   struct intel_context *intel = intel_context(ctx);
-
-   intel_flush_rendering_to_batch(ctx);
-
-   if (intel->batch.used)
-      _intel_batchbuffer_flush(intel, file, line);
-}
-
-static void
-intel_glFlush(struct gl_context *ctx)
-{
-   struct intel_context *intel = intel_context(ctx);
-
-   intel_flush(ctx);
-   intel_flush_front(ctx);
-   if (intel->is_front_buffer_rendering)
-      intel->need_throttle = true;
-}
-
-void
-intelFinish(struct gl_context * ctx)
-{
-   struct intel_context *intel = intel_context(ctx);
-
-   intel_flush(ctx);
-   intel_flush_front(ctx);
-
-   if (intel->batch.last_bo)
-      drm_intel_bo_wait_rendering(intel->batch.last_bo);
-}
-
-void
-intelInitDriverFunctions(struct dd_function_table *functions)
-{
-   _mesa_init_driver_functions(functions);
-
-   functions->Flush = intel_glFlush;
-   functions->Finish = intelFinish;
-   functions->GetString = intelGetString;
-   functions->UpdateState = intelInvalidateState;
-
-   intelInitTextureFuncs(functions);
-   intelInitTextureImageFuncs(functions);
-   intelInitTextureSubImageFuncs(functions);
-   intelInitTextureCopyImageFuncs(functions);
-   intelInitClearFuncs(functions);
-   intelInitBufferFuncs(functions);
-   intelInitPixelFuncs(functions);
-   intelInitBufferObjectFuncs(functions);
-   intel_init_syncobj_functions(functions);
-}
-
-static bool
-validate_context_version(struct intel_screen *screen,
-                         int mesa_api,
-                         unsigned major_version,
-                         unsigned minor_version,
-                         unsigned *dri_ctx_error)
-{
-   unsigned req_version = 10 * major_version + minor_version;
-   unsigned max_version = 0;
-
-   switch (mesa_api) {
-   case API_OPENGL_COMPAT:
-      max_version = screen->max_gl_compat_version;
-      break;
-   case API_OPENGL_CORE:
-      max_version = screen->max_gl_core_version;
-      break;
-   case API_OPENGLES:
-      max_version = screen->max_gl_es1_version;
-      break;
-   case API_OPENGLES2:
-      max_version = screen->max_gl_es2_version;
-      break;
-   default:
-      max_version = 0;
-      break;
-   }
-
-   if (max_version == 0) {
-      *dri_ctx_error = __DRI_CTX_ERROR_BAD_API;
-      return false;
-   } else if (req_version > max_version) {
-      *dri_ctx_error = __DRI_CTX_ERROR_BAD_VERSION;
-      return false;
-   }
-
-   return true;
-}
-
-bool
-intelInitContext(struct intel_context *intel,
-                 int api,
-                 unsigned major_version,
-                 unsigned minor_version,
-                 const struct gl_config * mesaVis,
-                 __DRIcontext * driContextPriv,
-                 void *sharedContextPrivate,
-                 struct dd_function_table *functions,
-                 unsigned *dri_ctx_error)
-{
-   struct gl_context *ctx = &intel->ctx;
-   struct gl_context *shareCtx = (struct gl_context *) sharedContextPrivate;
-   __DRIscreen *sPriv = driContextPriv->driScreenPriv;
-   struct intel_screen *intelScreen = sPriv->driverPrivate;
-   int bo_reuse_mode;
-   struct gl_config visual;
-
-   /* we can't do anything without a connection to the device */
-   if (intelScreen->bufmgr == NULL) {
-      *dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY;
-      return false;
-   }
-
-   if (!validate_context_version(intelScreen,
-                                 api, major_version, minor_version,
-                                 dri_ctx_error))
-      return false;
-
-   /* Can't rely on invalidate events, fall back to glViewport hack */
-   if (!driContextPriv->driScreenPriv->dri2.useInvalidate) {
-      intel->saved_viewport = functions->Viewport;
-      functions->Viewport = intel_viewport;
-   }
-
-   if (mesaVis == NULL) {
-      memset(&visual, 0, sizeof visual);
-      mesaVis = &visual;
-   }
-
-   intel->intelScreen = intelScreen;
-
-   if (!_mesa_initialize_context(&intel->ctx, api, mesaVis, shareCtx,
-                                 functions)) {
-      *dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY;
-      printf("%s: failed to init mesa context\n", __FUNCTION__);
-      return false;
-   }
-
-   driContextPriv->driverPrivate = intel;
-   intel->driContext = driContextPriv;
-   intel->driFd = sPriv->fd;
-
-   intel->gen = intelScreen->gen;
-
-   const int devID = intelScreen->deviceID;
-   if (IS_SNB_GT1(devID) || IS_IVB_GT1(devID) || IS_HSW_GT1(devID))
-      intel->gt = 1;
-   else if (IS_SNB_GT2(devID) || IS_IVB_GT2(devID) || IS_HSW_GT2(devID))
-      intel->gt = 2;
-   else if (IS_HSW_GT3(devID))
-      intel->gt = 3;
-   else
-      intel->gt = 0;
-
-   if (IS_HASWELL(devID)) {
-      intel->is_haswell = true;
-   } else if (IS_BAYTRAIL(devID)) {
-      intel->is_baytrail = true;
-      intel->gt = 1;
-   } else if (IS_G4X(devID)) {
-      intel->is_g4x = true;
-   } else if (IS_945(devID)) {
-      intel->is_945 = true;
-   }
-
-   if (intel->gen >= 5) {
-      intel->needs_ff_sync = true;
-   }
-
-   intel->has_separate_stencil = intel->intelScreen->hw_has_separate_stencil;
-   intel->must_use_separate_stencil = intel->intelScreen->hw_must_use_separate_stencil;
-   intel->has_hiz = intel->gen >= 6;
-   intel->has_llc = intel->intelScreen->hw_has_llc;
-   intel->has_swizzling = intel->intelScreen->hw_has_swizzling;
-
-   memset(&ctx->TextureFormatSupported,
-         0, sizeof(ctx->TextureFormatSupported));
-
-   driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache,
-                       sPriv->myNum, (intel->gen >= 4) ? "i965" : "i915");
-   if (intel->gen < 4)
-      intel->maxBatchSize = 4096;
-   else
-      intel->maxBatchSize = BATCH_SZ;
-
-   /* Estimate the size of the mappable aperture into the GTT.  There's an
-    * ioctl to get the whole GTT size, but not one to get the mappable subset.
-    * It turns out it's basically always 256MB, though some ancient hardware
-    * was smaller.
-    */
-   uint32_t gtt_size = 256 * 1024 * 1024;
-   if (intel->gen == 2)
-      gtt_size = 128 * 1024 * 1024;
-
-   /* We don't want to map two objects such that a memcpy between them would
-    * just fault one mapping in and then the other over and over forever.  So
-    * we would need to divide the GTT size by 2.  Additionally, some GTT is
-    * taken up by things like the framebuffer and the ringbuffer and such, so
-    * be more conservative.
-    */
-   intel->max_gtt_map_object_size = gtt_size / 4;
-
-   intel->bufmgr = intelScreen->bufmgr;
-
-   bo_reuse_mode = driQueryOptioni(&intel->optionCache, "bo_reuse");
-   switch (bo_reuse_mode) {
-   case DRI_CONF_BO_REUSE_DISABLED:
-      break;
-   case DRI_CONF_BO_REUSE_ALL:
-      intel_bufmgr_gem_enable_reuse(intel->bufmgr);
-      break;
-   }
-
-   ctx->Const.MinLineWidth = 1.0;
-   ctx->Const.MinLineWidthAA = 1.0;
-   ctx->Const.MaxLineWidth = 5.0;
-   ctx->Const.MaxLineWidthAA = 5.0;
-   ctx->Const.LineWidthGranularity = 0.5;
-
-   ctx->Const.MinPointSize = 1.0;
-   ctx->Const.MinPointSizeAA = 1.0;
-   ctx->Const.MaxPointSize = 255.0;
-   ctx->Const.MaxPointSizeAA = 3.0;
-   ctx->Const.PointSizeGranularity = 1.0;
-
-   if (intel->gen >= 6)
-      ctx->Const.MaxClipPlanes = 8;
-
-   ctx->Const.StripTextureBorder = GL_TRUE;
-
-   /* reinitialize the context point state.
-    * It depend on constants in __struct gl_contextRec::Const
-    */
-   _mesa_init_point(ctx);
-
-   if (intel->gen >= 4) {
-      ctx->Const.MaxRenderbufferSize = 8192;
-   } else {
-      ctx->Const.MaxRenderbufferSize = 2048;
-   }
-
-   /* Initialize the software rasterizer and helper modules.
-    *
-    * As of GL 3.1 core, the gen4+ driver doesn't need the swrast context for
-    * software fallbacks (which we have to support on legacy GL to do weird
-    * glDrawPixels(), glBitmap(), and other functions).
-    */
-   if (intel->gen <= 3 || api != API_OPENGL_CORE) {
-      _swrast_CreateContext(ctx);
-   }
-
-   _vbo_CreateContext(ctx);
-   if (ctx->swrast_context) {
-      _tnl_CreateContext(ctx);
-      _swsetup_CreateContext(ctx);
-
-      /* Configure swrast to match hardware characteristics: */
-      _swrast_allow_pixel_fog(ctx, false);
-      _swrast_allow_vertex_fog(ctx, true);
-   }
-
-   _mesa_meta_init(ctx);
-
-   intel->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24;
-   intel->hw_stipple = 1;
-
-   intel->RenderIndex = ~0;
-
-   intelInitExtensions(ctx);
-
-   INTEL_DEBUG = driParseDebugString(getenv("INTEL_DEBUG"), debug_control);
-   if (INTEL_DEBUG & DEBUG_BUFMGR)
-      dri_bufmgr_set_debug(intel->bufmgr, true);
-   if ((INTEL_DEBUG & DEBUG_SHADER_TIME) && intel->gen < 7) {
-      fprintf(stderr,
-              "shader_time debugging requires gen7 (Ivybridge) or better.\n");
-      INTEL_DEBUG &= ~DEBUG_SHADER_TIME;
-   }
-   if (INTEL_DEBUG & DEBUG_PERF)
-      intel->perf_debug = true;
-
-   if (INTEL_DEBUG & DEBUG_AUB)
-      drm_intel_bufmgr_gem_set_aub_dump(intel->bufmgr, true);
-
-   intel_batchbuffer_init(intel);
-
-   intel_fbo_init(intel);
-
-   intel->use_early_z = driQueryOptionb(&intel->optionCache, "early_z");
-
-   if (!driQueryOptionb(&intel->optionCache, "hiz")) {
-       intel->has_hiz = false;
-       /* On gen6, you can only do separate stencil with HIZ. */
-       if (intel->gen == 6)
-         intel->has_separate_stencil = false;
-   }
-
-   intel->prim.primitive = ~0;
-
-   /* Force all software fallbacks */
-#ifdef I915
-   if (driQueryOptionb(&intel->optionCache, "no_rast")) {
-      fprintf(stderr, "disabling 3D rasterization\n");
-      intel->no_rast = 1;
-   }
-#endif
-
-   if (driQueryOptionb(&intel->optionCache, "always_flush_batch")) {
-      fprintf(stderr, "flushing batchbuffer before/after each draw call\n");
-      intel->always_flush_batch = 1;
-   }
-
-   if (driQueryOptionb(&intel->optionCache, "always_flush_cache")) {
-      fprintf(stderr, "flushing GPU caches before/after each draw call\n");
-      intel->always_flush_cache = 1;
-   }
-
-   if (driQueryOptionb(&intel->optionCache, "disable_throttling")) {
-      fprintf(stderr, "disabling flush throttling\n");
-      intel->disable_throttling = 1;
-   }
-
-   return true;
-}
-
-void
-intelDestroyContext(__DRIcontext * driContextPriv)
-{
-   struct intel_context *intel =
-      (struct intel_context *) driContextPriv->driverPrivate;
-   struct gl_context *ctx = &intel->ctx;
-
-   assert(intel);               /* should never be null */
-   if (intel) {
-      INTEL_FIREVERTICES(intel);
-
-      /* Dump a final BMP in case the application doesn't call SwapBuffers */
-      if (INTEL_DEBUG & DEBUG_AUB) {
-         intel_batchbuffer_flush(intel);
-        aub_dump_bmp(&intel->ctx);
-      }
-
-      _mesa_meta_free(&intel->ctx);
-
-      intel->vtbl.destroy(intel);
-
-      if (ctx->swrast_context) {
-         _swsetup_DestroyContext(&intel->ctx);
-         _tnl_DestroyContext(&intel->ctx);
-      }
-      _vbo_DestroyContext(&intel->ctx);
-
-      if (ctx->swrast_context)
-         _swrast_DestroyContext(&intel->ctx);
-      intel->Fallback = 0x0;      /* don't call _swrast_Flush later */
-
-      intel_batchbuffer_free(intel);
-
-      free(intel->prim.vb);
-      intel->prim.vb = NULL;
-      drm_intel_bo_unreference(intel->prim.vb_bo);
-      intel->prim.vb_bo = NULL;
-      drm_intel_bo_unreference(intel->first_post_swapbuffers_batch);
-      intel->first_post_swapbuffers_batch = NULL;
-
-      driDestroyOptionCache(&intel->optionCache);
-
-      /* free the Mesa context */
-      _mesa_free_context_data(&intel->ctx);
-
-      _math_matrix_dtr(&intel->ViewportMatrix);
-
-      ralloc_free(intel);
-      driContextPriv->driverPrivate = NULL;
-   }
-}
-
-GLboolean
-intelUnbindContext(__DRIcontext * driContextPriv)
-{
-   /* Unset current context and dispath table */
-   _mesa_make_current(NULL, NULL, NULL);
-
-   return true;
-}
-
-/**
- * Fixes up the context for GLES23 with our default-to-sRGB-capable behavior
- * on window system framebuffers.
- *
- * Desktop GL is fairly reasonable in its handling of sRGB: You can ask if
- * your renderbuffer can do sRGB encode, and you can flip a switch that does
- * sRGB encode if the renderbuffer can handle it.  You can ask specifically
- * for a visual where you're guaranteed to be capable, but it turns out that
- * everyone just makes all their ARGB8888 visuals capable and doesn't offer
- * incapable ones, becuase there's no difference between the two in resources
- * used.  Applications thus get built that accidentally rely on the default
- * visual choice being sRGB, so we make ours sRGB capable.  Everything sounds
- * great...
- *
- * But for GLES2/3, they decided that it was silly to not turn on sRGB encode
- * for sRGB renderbuffers you made with the GL_EXT_texture_sRGB equivalent.
- * So they removed the enable knob and made it "if the renderbuffer is sRGB
- * capable, do sRGB encode".  Then, for your window system renderbuffers, you
- * can ask for sRGB visuals and get sRGB encode, or not ask for sRGB visuals
- * and get no sRGB encode (assuming that both kinds of visual are available).
- * Thus our choice to support sRGB by default on our visuals for desktop would
- * result in broken rendering of GLES apps that aren't expecting sRGB encode.
- *
- * Unfortunately, renderbuffer setup happens before a context is created.  So
- * in intel_screen.c we always set up sRGB, and here, if you're a GLES2/3
- * context (without an sRGB visual, though we don't have sRGB visuals exposed
- * yet), we go turn that back off before anyone finds out.
- */
-static void
-intel_gles3_srgb_workaround(struct intel_context *intel,
-                            struct gl_framebuffer *fb)
-{
-   struct gl_context *ctx = &intel->ctx;
-
-   if (_mesa_is_desktop_gl(ctx) || !fb->Visual.sRGBCapable)
-      return;
-
-   /* Some day when we support the sRGB capable bit on visuals available for
-    * GLES, we'll need to respect that and not disable things here.
-    */
-   fb->Visual.sRGBCapable = false;
-   for (int i = 0; i < BUFFER_COUNT; i++) {
-      if (fb->Attachment[i].Renderbuffer &&
-          fb->Attachment[i].Renderbuffer->Format == MESA_FORMAT_SARGB8) {
-         fb->Attachment[i].Renderbuffer->Format = MESA_FORMAT_ARGB8888;
-      }
-   }
-}
-
-GLboolean
-intelMakeCurrent(__DRIcontext * driContextPriv,
-                 __DRIdrawable * driDrawPriv,
-                 __DRIdrawable * driReadPriv)
-{
-   struct intel_context *intel;
-   GET_CURRENT_CONTEXT(curCtx);
-
-   if (driContextPriv)
-      intel = (struct intel_context *) driContextPriv->driverPrivate;
-   else
-      intel = NULL;
-
-   /* According to the glXMakeCurrent() man page: "Pending commands to
-    * the previous context, if any, are flushed before it is released."
-    * But only flush if we're actually changing contexts.
-    */
-   if (intel_context(curCtx) && intel_context(curCtx) != intel) {
-      _mesa_flush(curCtx);
-   }
-
-   if (driContextPriv) {
-      struct gl_context *ctx = &intel->ctx;
-      struct gl_framebuffer *fb, *readFb;
-      
-      if (driDrawPriv == NULL && driReadPriv == NULL) {
-        fb = _mesa_get_incomplete_framebuffer();
-        readFb = _mesa_get_incomplete_framebuffer();
-      } else {
-        fb = driDrawPriv->driverPrivate;
-        readFb = driReadPriv->driverPrivate;
-        driContextPriv->dri2.draw_stamp = driDrawPriv->dri2.stamp - 1;
-        driContextPriv->dri2.read_stamp = driReadPriv->dri2.stamp - 1;
-      }
-
-      intel_prepare_render(intel);
-      _mesa_make_current(ctx, fb, readFb);
-
-      intel_gles3_srgb_workaround(intel, ctx->WinSysDrawBuffer);
-      intel_gles3_srgb_workaround(intel, ctx->WinSysReadBuffer);
-
-      /* We do this in intel_prepare_render() too, but intel->ctx.DrawBuffer
-       * is NULL at that point.  We can't call _mesa_makecurrent()
-       * first, since we need the buffer size for the initial
-       * viewport.  So just call intel_draw_buffer() again here. */
-      intel_draw_buffer(ctx);
-   }
-   else {
-      _mesa_make_current(NULL, NULL, NULL);
-   }
-
-   return true;
-}
-
-/**
- * \brief Query DRI2 to obtain a DRIdrawable's buffers.
- *
- * To determine which DRI buffers to request, examine the renderbuffers
- * attached to the drawable's framebuffer. Then request the buffers with
- * DRI2GetBuffers() or DRI2GetBuffersWithFormat().
- *
- * This is called from intel_update_renderbuffers().
- *
- * \param drawable      Drawable whose buffers are queried.
- * \param buffers       [out] List of buffers returned by DRI2 query.
- * \param buffer_count  [out] Number of buffers returned.
- *
- * \see intel_update_renderbuffers()
- * \see DRI2GetBuffers()
- * \see DRI2GetBuffersWithFormat()
- */
-static void
-intel_query_dri2_buffers(struct intel_context *intel,
-                        __DRIdrawable *drawable,
-                        __DRIbuffer **buffers,
-                        int *buffer_count)
-{
-   __DRIscreen *screen = intel->intelScreen->driScrnPriv;
-   struct gl_framebuffer *fb = drawable->driverPrivate;
-   int i = 0;
-   unsigned attachments[8];
-
-   struct intel_renderbuffer *front_rb;
-   struct intel_renderbuffer *back_rb;
-
-   front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
-   back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT);
-
-   memset(attachments, 0, sizeof(attachments));
-   if ((intel->is_front_buffer_rendering ||
-       intel->is_front_buffer_reading ||
-       !back_rb) && front_rb) {
-      /* If a fake front buffer is in use, then querying for
-       * __DRI_BUFFER_FRONT_LEFT will cause the server to copy the image from
-       * the real front buffer to the fake front buffer.  So before doing the
-       * query, we need to make sure all the pending drawing has landed in the
-       * real front buffer.
-       */
-      intel_flush(&intel->ctx);
-      intel_flush_front(&intel->ctx);
-
-      attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
-      attachments[i++] = intel_bits_per_pixel(front_rb);
-   } else if (front_rb && intel->front_buffer_dirty) {
-      /* We have pending front buffer rendering, but we aren't querying for a
-       * front buffer.  If the front buffer we have is a fake front buffer,
-       * the X server is going to throw it away when it processes the query.
-       * So before doing the query, make sure all the pending drawing has
-       * landed in the real front buffer.
-       */
-      intel_flush(&intel->ctx);
-      intel_flush_front(&intel->ctx);
-   }
-
-   if (back_rb) {
-      attachments[i++] = __DRI_BUFFER_BACK_LEFT;
-      attachments[i++] = intel_bits_per_pixel(back_rb);
-   }
-
-   assert(i <= ARRAY_SIZE(attachments));
-
-   *buffers = screen->dri2.loader->getBuffersWithFormat(drawable,
-                                                       &drawable->w,
-                                                       &drawable->h,
-                                                       attachments, i / 2,
-                                                       buffer_count,
-                                                       drawable->loaderPrivate);
-}
-
-/**
- * \brief Assign a DRI buffer's DRM region to a renderbuffer.
- *
- * This is called from intel_update_renderbuffers().
- *
- * \par Note:
- *    DRI buffers whose attachment point is DRI2BufferStencil or
- *    DRI2BufferDepthStencil are handled as special cases.
- *
- * \param buffer_name is a human readable name, such as "dri2 front buffer",
- *        that is passed to intel_region_alloc_for_handle().
- *
- * \see intel_update_renderbuffers()
- * \see intel_region_alloc_for_handle()
- */
-static void
-intel_process_dri2_buffer(struct intel_context *intel,
-                         __DRIdrawable *drawable,
-                         __DRIbuffer *buffer,
-                         struct intel_renderbuffer *rb,
-                         const char *buffer_name)
-{
-   struct intel_region *region = NULL;
-
-   if (!rb)
-      return;
-
-   unsigned num_samples = rb->Base.Base.NumSamples;
-
-   /* We try to avoid closing and reopening the same BO name, because the first
-    * use of a mapping of the buffer involves a bunch of page faulting which is
-    * moderately expensive.
-    */
-   if (num_samples == 0) {
-       if (rb->mt &&
-           rb->mt->region &&
-           rb->mt->region->name == buffer->name)
-          return;
-   } else {
-       if (rb->mt &&
-           rb->mt->singlesample_mt &&
-           rb->mt->singlesample_mt->region &&
-           rb->mt->singlesample_mt->region->name == buffer->name)
-          return;
-   }
-
-   if (unlikely(INTEL_DEBUG & DEBUG_DRI)) {
-      fprintf(stderr,
-             "attaching buffer %d, at %d, cpp %d, pitch %d\n",
-             buffer->name, buffer->attachment,
-             buffer->cpp, buffer->pitch);
-   }
-
-   intel_miptree_release(&rb->mt);
-   region = intel_region_alloc_for_handle(intel->intelScreen,
-                                          buffer->cpp,
-                                          drawable->w,
-                                          drawable->h,
-                                          buffer->pitch,
-                                          buffer->name,
-                                          buffer_name);
-   if (!region)
-      return;
-
-   rb->mt = intel_miptree_create_for_dri2_buffer(intel,
-                                                 buffer->attachment,
-                                                 intel_rb_format(rb),
-                                                 num_samples,
-                                                 region);
-   intel_region_release(&region);
-}
diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c
deleted file mode 100644 (file)
index 5cb2fa3..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-#include "main/version.h"
-
-#include "intel_chipset.h"
-#include "intel_context.h"
-#include "intel_extensions.h"
-#include "intel_reg.h"
-#include "utils.h"
-
-/**
- * Initializes potential list of extensions if ctx == NULL, or actually enables
- * extensions for a context.
- */
-void
-intelInitExtensions(struct gl_context *ctx)
-{
-   struct intel_context *intel = intel_context(ctx);
-
-   ctx->Extensions.ARB_draw_elements_base_vertex = true;
-   ctx->Extensions.ARB_explicit_attrib_location = true;
-   ctx->Extensions.ARB_framebuffer_object = true;
-   ctx->Extensions.ARB_half_float_pixel = true;
-   ctx->Extensions.ARB_internalformat_query = true;
-   ctx->Extensions.ARB_map_buffer_range = true;
-   ctx->Extensions.ARB_point_sprite = true;
-   ctx->Extensions.ARB_shader_objects = true;
-   ctx->Extensions.ARB_shading_language_100 = true;
-   ctx->Extensions.ARB_sync = true;
-   ctx->Extensions.ARB_texture_border_clamp = true;
-   ctx->Extensions.ARB_texture_cube_map = true;
-   ctx->Extensions.ARB_texture_env_combine = true;
-   ctx->Extensions.ARB_texture_env_crossbar = true;
-   ctx->Extensions.ARB_texture_env_dot3 = true;
-   ctx->Extensions.ARB_texture_storage = true;
-   ctx->Extensions.ARB_vertex_program = true;
-   ctx->Extensions.ARB_vertex_shader = true;
-   ctx->Extensions.EXT_blend_color = true;
-   ctx->Extensions.EXT_blend_equation_separate = true;
-   ctx->Extensions.EXT_blend_func_separate = true;
-   ctx->Extensions.EXT_blend_minmax = true;
-   ctx->Extensions.EXT_framebuffer_blit = true;
-   ctx->Extensions.EXT_framebuffer_object = true;
-   ctx->Extensions.EXT_fog_coord = true;
-   ctx->Extensions.EXT_gpu_program_parameters = true;
-   ctx->Extensions.EXT_packed_depth_stencil = true;
-   ctx->Extensions.EXT_pixel_buffer_object = true;
-   ctx->Extensions.EXT_point_parameters = true;
-   ctx->Extensions.EXT_provoking_vertex = true;
-   ctx->Extensions.EXT_secondary_color = true;
-   ctx->Extensions.EXT_separate_shader_objects = true;
-   ctx->Extensions.EXT_texture_env_dot3 = true;
-   ctx->Extensions.EXT_texture_filter_anisotropic = true;
-   ctx->Extensions.APPLE_object_purgeable = true;
-   ctx->Extensions.MESA_pack_invert = true;
-   ctx->Extensions.MESA_ycbcr_texture = true;
-   ctx->Extensions.NV_blend_square = true;
-   ctx->Extensions.NV_texture_rectangle = true;
-   ctx->Extensions.TDFX_texture_compression_FXT1 = true;
-   ctx->Extensions.OES_EGL_image = true;
-   ctx->Extensions.OES_draw_texture = true;
-
-   if (intel->gen >= 6)
-      ctx->Const.GLSLVersion = 140;
-   else
-      ctx->Const.GLSLVersion = 120;
-   _mesa_override_glsl_version(ctx);
-
-   if (intel->gen >= 6) {
-      ctx->Extensions.EXT_framebuffer_multisample = true;
-      ctx->Extensions.EXT_transform_feedback = true;
-      ctx->Extensions.ARB_blend_func_extended = !driQueryOptionb(&intel->optionCache, "disable_blend_func_extended");
-      ctx->Extensions.ARB_draw_buffers_blend = true;
-      ctx->Extensions.ARB_ES3_compatibility = true;
-      ctx->Extensions.ARB_uniform_buffer_object = true;
-      ctx->Extensions.ARB_texture_buffer_object = true;
-      ctx->Extensions.ARB_texture_buffer_object_rgb32 = true;
-      ctx->Extensions.ARB_texture_cube_map_array = true;
-      ctx->Extensions.OES_depth_texture_cube_map = true;
-      ctx->Extensions.ARB_shading_language_packing = true;
-      ctx->Extensions.ARB_texture_multisample = true;
-      ctx->Extensions.ARB_texture_storage_multisample = true;
-   }
-
-   if (intel->gen >= 5) {
-      ctx->Extensions.ARB_texture_query_lod = true;
-      ctx->Extensions.EXT_timer_query = true;
-   }
-
-   if (intel->gen >= 6) {
-      uint64_t dummy;
-      /* Test if the kernel has the ioctl. */
-      if (drm_intel_reg_read(intel->bufmgr, TIMESTAMP, &dummy) == 0)
-         ctx->Extensions.ARB_timer_query = true;
-   }
-
-   if (intel->gen >= 4) {
-      if (ctx->API == API_OPENGL_CORE)
-         ctx->Extensions.ARB_base_instance = true;
-      if (ctx->API != API_OPENGL_CORE)
-         ctx->Extensions.ARB_color_buffer_float = true;
-      ctx->Extensions.ARB_depth_buffer_float = true;
-      ctx->Extensions.ARB_depth_clamp = true;
-      ctx->Extensions.ARB_draw_instanced = true;
-      ctx->Extensions.ARB_instanced_arrays = true;
-      ctx->Extensions.ARB_fragment_coord_conventions = true;
-      ctx->Extensions.ARB_fragment_program_shadow = true;
-      ctx->Extensions.ARB_fragment_shader = true;
-      ctx->Extensions.ARB_half_float_vertex = true;
-      ctx->Extensions.ARB_occlusion_query = true;
-      ctx->Extensions.ARB_occlusion_query2 = true;
-      ctx->Extensions.ARB_point_sprite = true;
-      ctx->Extensions.ARB_seamless_cube_map = true;
-      ctx->Extensions.ARB_shader_bit_encoding = true;
-      ctx->Extensions.ARB_shader_texture_lod = true;
-      ctx->Extensions.ARB_texture_float = true;
-      ctx->Extensions.EXT_texture_shared_exponent = true;
-      ctx->Extensions.EXT_packed_float = true;
-      ctx->Extensions.ARB_texture_compression_rgtc = true;
-      ctx->Extensions.ARB_texture_rg = true;
-      ctx->Extensions.ARB_texture_rgb10_a2ui = true;
-      ctx->Extensions.ARB_vertex_type_2_10_10_10_rev = true;
-      ctx->Extensions.EXT_draw_buffers2 = true;
-      ctx->Extensions.EXT_framebuffer_sRGB = true;
-      ctx->Extensions.EXT_texture_array = true;
-      ctx->Extensions.EXT_texture_integer = true;
-      ctx->Extensions.EXT_texture_snorm = true;
-      ctx->Extensions.EXT_texture_swizzle = true;
-      ctx->Extensions.EXT_vertex_array_bgra = true;
-      ctx->Extensions.ATI_envmap_bumpmap = true;
-      ctx->Extensions.MESA_texture_array = true;
-      ctx->Extensions.NV_conditional_render = true;
-      ctx->Extensions.OES_compressed_ETC1_RGB8_texture = true;
-      ctx->Extensions.OES_standard_derivatives = true;
-   }
-
-   if (intel->gen >= 3) {
-      ctx->Extensions.ARB_ES2_compatibility = true;
-      ctx->Extensions.ARB_depth_texture = true;
-      ctx->Extensions.ARB_fragment_program = true;
-      ctx->Extensions.ARB_shadow = true;
-      ctx->Extensions.ARB_texture_non_power_of_two = true;
-      ctx->Extensions.EXT_texture_sRGB = true;
-      ctx->Extensions.EXT_texture_sRGB_decode = true;
-      ctx->Extensions.EXT_shadow_funcs = true;
-      ctx->Extensions.EXT_stencil_two_side = true;
-      ctx->Extensions.ATI_separate_stencil = true;
-      ctx->Extensions.ATI_texture_env_combine3 = true;
-      ctx->Extensions.NV_texture_env_combine4 = true;
-      ctx->Extensions.ARB_fragment_shader = true;
-      ctx->Extensions.ARB_occlusion_query = true;
-   }
-
-   if (intel->ctx.Mesa_DXTn
-       || driQueryOptionb(&intel->optionCache, "force_s3tc_enable"))
-      ctx->Extensions.EXT_texture_compression_s3tc = true;
-
-   ctx->Extensions.ANGLE_texture_compression_dxt = true;
-
-   if (intel->gen >= 4) {
-      ctx->Extensions.NV_primitive_restart = true;
-   }
-}
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
deleted file mode 100644 (file)
index d16523b..0000000
+++ /dev/null
@@ -1,949 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-
-#include "main/enums.h"
-#include "main/imports.h"
-#include "main/macros.h"
-#include "main/mtypes.h"
-#include "main/fbobject.h"
-#include "main/framebuffer.h"
-#include "main/renderbuffer.h"
-#include "main/context.h"
-#include "main/teximage.h"
-#include "main/image.h"
-
-#include "swrast/swrast.h"
-#include "drivers/common/meta.h"
-
-#include "intel_context.h"
-#include "intel_batchbuffer.h"
-#include "intel_buffers.h"
-#include "intel_blit.h"
-#include "intel_fbo.h"
-#include "intel_mipmap_tree.h"
-#include "intel_regions.h"
-#include "intel_tex.h"
-#ifndef I915
-#include "brw_context.h"
-#endif
-
-#define FILE_DEBUG_FLAG DEBUG_FBO
-
-static struct gl_renderbuffer *
-intel_new_renderbuffer(struct gl_context * ctx, GLuint name);
-
-struct intel_region*
-intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex)
-{
-   struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, attIndex);
-   if (irb && irb->mt) {
-      if (attIndex == BUFFER_STENCIL && irb->mt->stencil_mt)
-        return irb->mt->stencil_mt->region;
-      else
-        return irb->mt->region;
-   } else
-      return NULL;
-}
-
-/**
- * Create a new framebuffer object.
- */
-static struct gl_framebuffer *
-intel_new_framebuffer(struct gl_context * ctx, GLuint name)
-{
-   /* Only drawable state in intel_framebuffer at this time, just use Mesa's
-    * class
-    */
-   return _mesa_new_framebuffer(ctx, name);
-}
-
-
-/** Called by gl_renderbuffer::Delete() */
-static void
-intel_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
-{
-   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
-
-   ASSERT(irb);
-
-   intel_miptree_release(&irb->mt);
-
-   _mesa_delete_renderbuffer(ctx, rb);
-}
-
-/**
- * \see dd_function_table::MapRenderbuffer
- */
-static void
-intel_map_renderbuffer(struct gl_context *ctx,
-                      struct gl_renderbuffer *rb,
-                      GLuint x, GLuint y, GLuint w, GLuint h,
-                      GLbitfield mode,
-                      GLubyte **out_map,
-                      GLint *out_stride)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct swrast_renderbuffer *srb = (struct swrast_renderbuffer *)rb;
-   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
-   void *map;
-   int stride;
-
-   if (srb->Buffer) {
-      /* this is a malloc'd renderbuffer (accum buffer), not an irb */
-      GLint bpp = _mesa_get_format_bytes(rb->Format);
-      GLint rowStride = srb->RowStride;
-      *out_map = (GLubyte *) srb->Buffer + y * rowStride + x * bpp;
-      *out_stride = rowStride;
-      return;
-   }
-
-   intel_prepare_render(intel);
-
-   /* For a window-system renderbuffer, we need to flip the mapping we receive
-    * upside-down.  So we need to ask for a rectangle on flipped vertically, and
-    * we then return a pointer to the bottom of it with a negative stride.
-    */
-   if (rb->Name == 0) {
-      y = rb->Height - y - h;
-   }
-
-   intel_miptree_map(intel, irb->mt, irb->mt_level, irb->mt_layer,
-                    x, y, w, h, mode, &map, &stride);
-
-   if (rb->Name == 0) {
-      map += (h - 1) * stride;
-      stride = -stride;
-   }
-
-   DBG("%s: rb %d (%s) mt mapped: (%d, %d) (%dx%d) -> %p/%d\n",
-       __FUNCTION__, rb->Name, _mesa_get_format_name(rb->Format),
-       x, y, w, h, map, stride);
-
-   *out_map = map;
-   *out_stride = stride;
-}
-
-/**
- * \see dd_function_table::UnmapRenderbuffer
- */
-static void
-intel_unmap_renderbuffer(struct gl_context *ctx,
-                        struct gl_renderbuffer *rb)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct swrast_renderbuffer *srb = (struct swrast_renderbuffer *)rb;
-   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
-
-   DBG("%s: rb %d (%s)\n", __FUNCTION__,
-       rb->Name, _mesa_get_format_name(rb->Format));
-
-   if (srb->Buffer) {
-      /* this is a malloc'd renderbuffer (accum buffer) */
-      /* nothing to do */
-      return;
-   }
-
-   intel_miptree_unmap(intel, irb->mt, irb->mt_level, irb->mt_layer);
-}
-
-
-/**
- * Round up the requested multisample count to the next supported sample size.
- */
-unsigned
-intel_quantize_num_samples(struct intel_screen *intel, unsigned num_samples)
-{
-   switch (intel->gen) {
-   case 6:
-      /* Gen6 supports only 4x multisampling. */
-      if (num_samples > 0)
-         return 4;
-      else
-         return 0;
-   case 7:
-      /* Gen7 supports 4x and 8x multisampling. */
-      if (num_samples > 4)
-         return 8;
-      else if (num_samples > 0)
-         return 4;
-      else
-         return 0;
-      return 0;
-   default:
-      /* MSAA unsupported. */
-      return 0;
-   }
-}
-
-
-/**
- * Called via glRenderbufferStorageEXT() to set the format and allocate
- * storage for a user-created renderbuffer.
- */
-static GLboolean
-intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
-                                 GLenum internalFormat,
-                                 GLuint width, GLuint height)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_screen *screen = intel->intelScreen;
-   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
-   rb->NumSamples = intel_quantize_num_samples(screen, rb->NumSamples);
-
-   switch (internalFormat) {
-   default:
-      /* Use the same format-choice logic as for textures.
-       * Renderbuffers aren't any different from textures for us,
-       * except they're less useful because you can't texture with
-       * them.
-       */
-      rb->Format = intel->ctx.Driver.ChooseTextureFormat(ctx, GL_TEXTURE_2D,
-                                                        internalFormat,
-                                                        GL_NONE, GL_NONE);
-      break;
-   case GL_STENCIL_INDEX:
-   case GL_STENCIL_INDEX1_EXT:
-   case GL_STENCIL_INDEX4_EXT:
-   case GL_STENCIL_INDEX8_EXT:
-   case GL_STENCIL_INDEX16_EXT:
-      /* These aren't actual texture formats, so force them here. */
-      if (intel->has_separate_stencil) {
-        rb->Format = MESA_FORMAT_S8;
-      } else {
-        assert(!intel->must_use_separate_stencil);
-        rb->Format = MESA_FORMAT_S8_Z24;
-      }
-      break;
-   }
-
-   rb->Width = width;
-   rb->Height = height;
-   rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat);
-
-   intel_miptree_release(&irb->mt);
-
-   DBG("%s: %s: %s (%dx%d)\n", __FUNCTION__,
-       _mesa_lookup_enum_by_nr(internalFormat),
-       _mesa_get_format_name(rb->Format), width, height);
-
-   if (width == 0 || height == 0)
-      return true;
-
-   irb->mt = intel_miptree_create_for_renderbuffer(intel, rb->Format,
-                                                  width, height,
-                                                   rb->NumSamples);
-   if (!irb->mt)
-      return false;
-
-   return true;
-}
-
-
-static void
-intel_image_target_renderbuffer_storage(struct gl_context *ctx,
-                                       struct gl_renderbuffer *rb,
-                                       void *image_handle)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_renderbuffer *irb;
-   __DRIscreen *screen;
-   __DRIimage *image;
-
-   screen = intel->intelScreen->driScrnPriv;
-   image = screen->dri2.image->lookupEGLImage(screen, image_handle,
-                                             screen->loaderPrivate);
-   if (image == NULL)
-      return;
-
-   /* __DRIimage is opaque to the core so it has to be checked here */
-   switch (image->format) {
-   case MESA_FORMAT_RGBA8888_REV:
-      _mesa_error(&intel->ctx, GL_INVALID_OPERATION,
-            "glEGLImageTargetRenderbufferStorage(unsupported image format");
-      return;
-      break;
-   default:
-      break;
-   }
-
-   irb = intel_renderbuffer(rb);
-   intel_miptree_release(&irb->mt);
-   irb->mt = intel_miptree_create_for_bo(intel,
-                                         image->region->bo,
-                                         image->format,
-                                         image->offset,
-                                         image->region->width,
-                                         image->region->height,
-                                         image->region->pitch,
-                                         image->region->tiling);
-   if (!irb->mt)
-      return;
-
-   rb->InternalFormat = image->internal_format;
-   rb->Width = image->region->width;
-   rb->Height = image->region->height;
-   rb->Format = image->format;
-   rb->_BaseFormat = _mesa_base_fbo_format(&intel->ctx,
-                                          image->internal_format);
-   rb->NeedsFinishRenderTexture = true;
-}
-
-/**
- * Called by _mesa_resize_framebuffer() for each hardware renderbuffer when a
- * window system framebuffer is resized.
- *
- * Any actual buffer reallocations for hardware renderbuffers (which would
- * have triggered _mesa_resize_framebuffer()) were done by
- * intel_process_dri2_buffer().
- */
-static GLboolean
-intel_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
-                           GLenum internalFormat, GLuint width, GLuint height)
-{
-   ASSERT(rb->Name == 0);
-   rb->Width = width;
-   rb->Height = height;
-   rb->InternalFormat = internalFormat;
-
-   return true;
-}
-
-/** Dummy function for gl_renderbuffer::AllocStorage() */
-static GLboolean
-intel_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb,
-                        GLenum internalFormat, GLuint width, GLuint height)
-{
-   _mesa_problem(ctx, "intel_op_alloc_storage should never be called.");
-   return false;
-}
-
-/**
- * Create a new intel_renderbuffer which corresponds to an on-screen window,
- * not a user-created renderbuffer.
- *
- * \param num_samples must be quantized.
- */
-struct intel_renderbuffer *
-intel_create_renderbuffer(gl_format format, unsigned num_samples)
-{
-   struct intel_renderbuffer *irb;
-   struct gl_renderbuffer *rb;
-
-   GET_CURRENT_CONTEXT(ctx);
-
-   irb = CALLOC_STRUCT(intel_renderbuffer);
-   if (!irb) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
-      return NULL;
-   }
-
-   rb = &irb->Base.Base;
-
-   _mesa_init_renderbuffer(rb, 0);
-   rb->ClassID = INTEL_RB_CLASS;
-   rb->_BaseFormat = _mesa_get_format_base_format(format);
-   rb->Format = format;
-   rb->InternalFormat = rb->_BaseFormat;
-   rb->NumSamples = num_samples;
-
-   /* intel-specific methods */
-   rb->Delete = intel_delete_renderbuffer;
-   rb->AllocStorage = intel_alloc_window_storage;
-
-   return irb;
-}
-
-/**
- * Private window-system buffers (as opposed to ones shared with the display
- * server created with intel_create_renderbuffer()) are most similar in their
- * handling to user-created renderbuffers, but they have a resize handler that
- * may be called at intel_update_renderbuffers() time.
- *
- * \param num_samples must be quantized.
- */
-struct intel_renderbuffer *
-intel_create_private_renderbuffer(gl_format format, unsigned num_samples)
-{
-   struct intel_renderbuffer *irb;
-
-   irb = intel_create_renderbuffer(format, num_samples);
-   irb->Base.Base.AllocStorage = intel_alloc_renderbuffer_storage;
-
-   return irb;
-}
-
-/**
- * Create a new renderbuffer object.
- * Typically called via glBindRenderbufferEXT().
- */
-static struct gl_renderbuffer *
-intel_new_renderbuffer(struct gl_context * ctx, GLuint name)
-{
-   /*struct intel_context *intel = intel_context(ctx); */
-   struct intel_renderbuffer *irb;
-   struct gl_renderbuffer *rb;
-
-   irb = CALLOC_STRUCT(intel_renderbuffer);
-   if (!irb) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer");
-      return NULL;
-   }
-
-   rb = &irb->Base.Base;
-
-   _mesa_init_renderbuffer(rb, name);
-   rb->ClassID = INTEL_RB_CLASS;
-
-   /* intel-specific methods */
-   rb->Delete = intel_delete_renderbuffer;
-   rb->AllocStorage = intel_alloc_renderbuffer_storage;
-   /* span routines set in alloc_storage function */
-
-   return rb;
-}
-
-
-/**
- * Called via glBindFramebufferEXT().
- */
-static void
-intel_bind_framebuffer(struct gl_context * ctx, GLenum target,
-                       struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
-{
-   if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
-      intel_draw_buffer(ctx);
-   }
-   else {
-      /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
-   }
-}
-
-
-/**
- * Called via glFramebufferRenderbufferEXT().
- */
-static void
-intel_framebuffer_renderbuffer(struct gl_context * ctx,
-                               struct gl_framebuffer *fb,
-                               GLenum attachment, struct gl_renderbuffer *rb)
-{
-   DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0);
-
-   _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb);
-   intel_draw_buffer(ctx);
-}
-
-static bool
-intel_renderbuffer_update_wrapper(struct intel_context *intel,
-                                  struct intel_renderbuffer *irb,
-                                 struct gl_texture_image *image,
-                                  uint32_t layer)
-{
-   struct gl_renderbuffer *rb = &irb->Base.Base;
-   struct intel_texture_image *intel_image = intel_texture_image(image);
-   struct intel_mipmap_tree *mt = intel_image->mt;
-   int level = image->Level;
-
-   rb->Depth = image->Depth;
-
-   rb->AllocStorage = intel_nop_alloc_storage;
-
-   intel_miptree_check_level_layer(mt, level, layer);
-   irb->mt_level = level;
-
-   switch (mt->msaa_layout) {
-      case INTEL_MSAA_LAYOUT_UMS:
-      case INTEL_MSAA_LAYOUT_CMS:
-         irb->mt_layer = layer * mt->num_samples;
-         break;
-
-      default:
-         irb->mt_layer = layer;
-   }
-
-   intel_miptree_reference(&irb->mt, mt);
-
-   intel_renderbuffer_set_draw_offset(irb);
-
-   if (mt->hiz_mt == NULL &&
-       intel->vtbl.is_hiz_depth_format(intel, rb->Format)) {
-      intel_miptree_alloc_hiz(intel, mt);
-      if (!mt->hiz_mt)
-        return false;
-   }
-
-   return true;
-}
-
-void
-intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb)
-{
-   unsigned int dst_x, dst_y;
-
-   /* compute offset of the particular 2D image within the texture region */
-   intel_miptree_get_image_offset(irb->mt,
-                                 irb->mt_level,
-                                 irb->mt_layer,
-                                 &dst_x, &dst_y);
-
-   irb->draw_x = dst_x;
-   irb->draw_y = dst_y;
-}
-
-/**
- * Called by glFramebufferTexture[123]DEXT() (and other places) to
- * prepare for rendering into texture memory.  This might be called
- * many times to choose different texture levels, cube faces, etc
- * before intel_finish_render_texture() is ever called.
- */
-static void
-intel_render_texture(struct gl_context * ctx,
-                     struct gl_framebuffer *fb,
-                     struct gl_renderbuffer_attachment *att)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct gl_renderbuffer *rb = att->Renderbuffer;
-   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
-   struct gl_texture_image *image = rb->TexImage;
-   struct intel_texture_image *intel_image = intel_texture_image(image);
-   struct intel_mipmap_tree *mt = intel_image->mt;
-   int layer;
-
-   (void) fb;
-
-   if (att->CubeMapFace > 0) {
-      assert(att->Zoffset == 0);
-      layer = att->CubeMapFace;
-   } else {
-      layer = att->Zoffset;
-   }
-
-   if (!intel_image->mt) {
-      /* Fallback on drawing to a texture that doesn't have a miptree
-       * (has a border, width/height 0, etc.)
-       */
-      _swrast_render_texture(ctx, fb, att);
-      return;
-   }
-
-   intel_miptree_check_level_layer(mt, att->TextureLevel, layer);
-
-   if (!intel_renderbuffer_update_wrapper(intel, irb, image, layer)) {
-       _swrast_render_texture(ctx, fb, att);
-       return;
-   }
-
-   DBG("Begin render %s texture tex=%u w=%d h=%d d=%d refcount=%d\n",
-       _mesa_get_format_name(image->TexFormat),
-       att->Texture->Name, image->Width, image->Height, image->Depth,
-       rb->RefCount);
-
-   /* update drawing region, etc */
-   intel_draw_buffer(ctx);
-}
-
-
-/**
- * Called by Mesa when rendering to a texture is done.
- */
-static void
-intel_finish_render_texture(struct gl_context * ctx, struct gl_renderbuffer *rb)
-{
-   struct intel_context *intel = intel_context(ctx);
-
-   DBG("Finish render %s texture\n", _mesa_get_format_name(rb->Format));
-
-   /* Since we've (probably) rendered to the texture and will (likely) use
-    * it in the texture domain later on in this batchbuffer, flush the
-    * batch.  Once again, we wish for a domain tracker in libdrm to cover
-    * usage inside of a batchbuffer like GEM does in the kernel.
-    */
-   intel_batchbuffer_emit_mi_flush(intel);
-}
-
-#define fbo_incomplete(fb, ...) do {                                          \
-      static GLuint msg_id = 0;                                               \
-      if (unlikely(ctx->Const.ContextFlags & GL_CONTEXT_FLAG_DEBUG_BIT)) {    \
-         _mesa_gl_debug(ctx, &msg_id,                                         \
-                        MESA_DEBUG_TYPE_OTHER,                                \
-                        MESA_DEBUG_SEVERITY_MEDIUM,                           \
-                        __VA_ARGS__);                                         \
-      }                                                                       \
-      DBG(__VA_ARGS__);                                                       \
-      fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED;                               \
-   } while (0)
-
-/**
- * Do additional "completeness" testing of a framebuffer object.
- */
-static void
-intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_renderbuffer *depthRb =
-      intel_get_renderbuffer(fb, BUFFER_DEPTH);
-   struct intel_renderbuffer *stencilRb =
-      intel_get_renderbuffer(fb, BUFFER_STENCIL);
-   struct intel_mipmap_tree *depth_mt = NULL, *stencil_mt = NULL;
-   int i;
-
-   DBG("%s() on fb %p (%s)\n", __FUNCTION__,
-       fb, (fb == ctx->DrawBuffer ? "drawbuffer" :
-           (fb == ctx->ReadBuffer ? "readbuffer" : "other buffer")));
-
-   if (depthRb)
-      depth_mt = depthRb->mt;
-   if (stencilRb) {
-      stencil_mt = stencilRb->mt;
-      if (stencil_mt->stencil_mt)
-        stencil_mt = stencil_mt->stencil_mt;
-   }
-
-   if (depth_mt && stencil_mt) {
-      if (depth_mt == stencil_mt) {
-        /* For true packed depth/stencil (not faked on prefers-separate-stencil
-         * hardware) we need to be sure they're the same level/layer, since
-         * we'll be emitting a single packet describing the packed setup.
-         */
-        if (depthRb->mt_level != stencilRb->mt_level ||
-            depthRb->mt_layer != stencilRb->mt_layer) {
-           fbo_incomplete(fb,
-                           "FBO incomplete: depth image level/layer %d/%d != "
-                           "stencil image %d/%d\n",
-                           depthRb->mt_level,
-                           depthRb->mt_layer,
-                           stencilRb->mt_level,
-                           stencilRb->mt_layer);
-        }
-      } else {
-        if (!intel->has_separate_stencil) {
-           fbo_incomplete(fb, "FBO incomplete: separate stencil "
-                           "unsupported\n");
-        }
-        if (stencil_mt->format != MESA_FORMAT_S8) {
-           fbo_incomplete(fb, "FBO incomplete: separate stencil is %s "
-                           "instead of S8\n",
-                           _mesa_get_format_name(stencil_mt->format));
-        }
-        if (intel->gen < 7 && !intel_renderbuffer_has_hiz(depthRb)) {
-           /* Before Gen7, separate depth and stencil buffers can be used
-            * only if HiZ is enabled. From the Sandybridge PRM, Volume 2,
-            * Part 1, Bit 3DSTATE_DEPTH_BUFFER.SeparateStencilBufferEnable:
-            *     [DevSNB]: This field must be set to the same value (enabled
-            *     or disabled) as Hierarchical Depth Buffer Enable.
-            */
-           fbo_incomplete(fb, "FBO incomplete: separate stencil "
-                           "without HiZ\n");
-        }
-      }
-   }
-
-   for (i = 0; i < Elements(fb->Attachment); i++) {
-      struct gl_renderbuffer *rb;
-      struct intel_renderbuffer *irb;
-
-      if (fb->Attachment[i].Type == GL_NONE)
-        continue;
-
-      /* A supported attachment will have a Renderbuffer set either
-       * from being a Renderbuffer or being a texture that got the
-       * intel_wrap_texture() treatment.
-       */
-      rb = fb->Attachment[i].Renderbuffer;
-      if (rb == NULL) {
-        fbo_incomplete(fb, "FBO incomplete: attachment without "
-                        "renderbuffer\n");
-        continue;
-      }
-
-      if (fb->Attachment[i].Type == GL_TEXTURE) {
-        if (rb->TexImage->Border) {
-           fbo_incomplete(fb, "FBO incomplete: texture with border\n");
-           continue;
-        }
-      }
-
-      irb = intel_renderbuffer(rb);
-      if (irb == NULL) {
-        fbo_incomplete(fb, "FBO incomplete: software rendering "
-                        "renderbuffer\n");
-        continue;
-      }
-
-      if (!intel->vtbl.render_target_supported(intel, rb)) {
-        fbo_incomplete(fb, "FBO incomplete: Unsupported HW "
-                        "texture/renderbuffer format attached: %s\n",
-                        _mesa_get_format_name(intel_rb_format(irb)));
-      }
-   }
-}
-
-/**
- * Try to do a glBlitFramebuffer using glCopyTexSubImage2D
- * We can do this when the dst renderbuffer is actually a texture and
- * there is no scaling, mirroring or scissoring.
- *
- * \return new buffer mask indicating the buffers left to blit using the
- *         normal path.
- */
-static GLbitfield
-intel_blit_framebuffer_with_blitter(struct gl_context *ctx,
-                                    GLint srcX0, GLint srcY0,
-                                    GLint srcX1, GLint srcY1,
-                                    GLint dstX0, GLint dstY0,
-                                    GLint dstX1, GLint dstY1,
-                                    GLbitfield mask, GLenum filter)
-{
-   struct intel_context *intel = intel_context(ctx);
-
-   if (mask & GL_COLOR_BUFFER_BIT) {
-      GLint i;
-      const struct gl_framebuffer *drawFb = ctx->DrawBuffer;
-      const struct gl_framebuffer *readFb = ctx->ReadBuffer;
-      struct gl_renderbuffer *src_rb = readFb->_ColorReadBuffer;
-      struct intel_renderbuffer *src_irb = intel_renderbuffer(src_rb);
-
-      if (!src_irb) {
-         perf_debug("glBlitFramebuffer(): missing src renderbuffer.  "
-                    "Falling back to software rendering.\n");
-         return mask;
-      }
-
-      /* If the source and destination are the same size with no mirroring,
-       * the rectangles are within the size of the texture and there is no
-       * scissor, then we can probably use the blit engine.
-       */
-      if (!(srcX0 - srcX1 == dstX0 - dstX1 &&
-            srcY0 - srcY1 == dstY0 - dstY1 &&
-            srcX1 >= srcX0 &&
-            srcY1 >= srcY0 &&
-            srcX0 >= 0 && srcX1 <= readFb->Width &&
-            srcY0 >= 0 && srcY1 <= readFb->Height &&
-            dstX0 >= 0 && dstX1 <= drawFb->Width &&
-            dstY0 >= 0 && dstY1 <= drawFb->Height &&
-            !ctx->Scissor.Enabled)) {
-         perf_debug("glBlitFramebuffer(): non-1:1 blit.  "
-                    "Falling back to software rendering.\n");
-         return mask;
-      }
-
-      /* Blit to all active draw buffers.  We don't do any pre-checking,
-       * because we assume that copying to MRTs is rare, and failure midway
-       * through copying is even more rare.  Even if it was to occur, it's
-       * safe to let meta start the copy over from scratch, because
-       * glBlitFramebuffer completely overwrites the destination pixels, and
-       * results are undefined if any destination pixels have a dependency on
-       * source pixels.
-       */
-      for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
-         struct gl_renderbuffer *dst_rb = ctx->DrawBuffer->_ColorDrawBuffers[i];
-         struct intel_renderbuffer *dst_irb = intel_renderbuffer(dst_rb);
-
-         if (!dst_irb) {
-            perf_debug("glBlitFramebuffer(): missing dst renderbuffer.  "
-                       "Falling back to software rendering.\n");
-            return mask;
-         }
-
-         gl_format src_format = _mesa_get_srgb_format_linear(src_rb->Format);
-         gl_format dst_format = _mesa_get_srgb_format_linear(dst_rb->Format);
-         if (src_format != dst_format) {
-            perf_debug("glBlitFramebuffer(): unsupported blit from %s to %s.  "
-                       "Falling back to software rendering.\n",
-                       _mesa_get_format_name(src_format),
-                       _mesa_get_format_name(dst_format));
-            return mask;
-         }
-
-         if (!intel_miptree_blit(intel,
-                                 src_irb->mt,
-                                 src_irb->mt_level, src_irb->mt_layer,
-                                 srcX0, srcY0, src_rb->Name == 0,
-                                 dst_irb->mt,
-                                 dst_irb->mt_level, dst_irb->mt_layer,
-                                 dstX0, dstY0, dst_rb->Name == 0,
-                                 dstX1 - dstX0, dstY1 - dstY0, GL_COPY)) {
-            perf_debug("glBlitFramebuffer(): unknown blit failure.  "
-                       "Falling back to software rendering.\n");
-            return mask;
-         }
-      }
-
-      mask &= ~GL_COLOR_BUFFER_BIT;
-   }
-
-   return mask;
-}
-
-static void
-intel_blit_framebuffer(struct gl_context *ctx,
-                       GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
-                       GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
-                       GLbitfield mask, GLenum filter)
-{
-#ifndef I915
-   mask = brw_blorp_framebuffer(intel_context(ctx),
-                                srcX0, srcY0, srcX1, srcY1,
-                                dstX0, dstY0, dstX1, dstY1,
-                                mask, filter);
-   if (mask == 0x0)
-      return;
-#endif
-
-   /* Try using the BLT engine. */
-   mask = intel_blit_framebuffer_with_blitter(ctx,
-                                              srcX0, srcY0, srcX1, srcY1,
-                                              dstX0, dstY0, dstX1, dstY1,
-                                              mask, filter);
-   if (mask == 0x0)
-      return;
-
-
-   _mesa_meta_BlitFramebuffer(ctx,
-                              srcX0, srcY0, srcX1, srcY1,
-                              dstX0, dstY0, dstX1, dstY1,
-                              mask, filter);
-}
-
-/**
- * This is a no-op except on multisample buffers shared with DRI2.
- */
-void
-intel_renderbuffer_set_needs_downsample(struct intel_renderbuffer *irb)
-{
-   if (irb->mt && irb->mt->singlesample_mt)
-      irb->mt->need_downsample = true;
-}
-
-/**
- * Does the renderbuffer have hiz enabled?
- */
-bool
-intel_renderbuffer_has_hiz(struct intel_renderbuffer *irb)
-{
-   return intel_miptree_slice_has_hiz(irb->mt, irb->mt_level, irb->mt_layer);
-}
-
-void
-intel_renderbuffer_set_needs_hiz_resolve(struct intel_renderbuffer *irb)
-{
-   if (irb->mt) {
-      intel_miptree_slice_set_needs_hiz_resolve(irb->mt,
-                                                irb->mt_level,
-                                                irb->mt_layer);
-   }
-}
-
-void
-intel_renderbuffer_set_needs_depth_resolve(struct intel_renderbuffer *irb)
-{
-   if (irb->mt) {
-      intel_miptree_slice_set_needs_depth_resolve(irb->mt,
-                                                  irb->mt_level,
-                                                  irb->mt_layer);
-   }
-}
-
-bool
-intel_renderbuffer_resolve_hiz(struct intel_context *intel,
-                              struct intel_renderbuffer *irb)
-{
-   if (irb->mt)
-      return intel_miptree_slice_resolve_hiz(intel,
-                                             irb->mt,
-                                             irb->mt_level,
-                                             irb->mt_layer);
-
-   return false;
-}
-
-bool
-intel_renderbuffer_resolve_depth(struct intel_context *intel,
-                                struct intel_renderbuffer *irb)
-{
-   if (irb->mt)
-      return intel_miptree_slice_resolve_depth(intel,
-                                               irb->mt,
-                                               irb->mt_level,
-                                               irb->mt_layer);
-
-   return false;
-}
-
-void
-intel_renderbuffer_move_to_temp(struct intel_context *intel,
-                                struct intel_renderbuffer *irb,
-                                bool invalidate)
-{
-   struct gl_renderbuffer *rb =&irb->Base.Base;
-   struct intel_texture_image *intel_image = intel_texture_image(rb->TexImage);
-   struct intel_mipmap_tree *new_mt;
-   int width, height, depth;
-
-   intel_miptree_get_dimensions_for_image(rb->TexImage, &width, &height, &depth);
-
-   new_mt = intel_miptree_create(intel, rb->TexImage->TexObject->Target,
-                                 intel_image->base.Base.TexFormat,
-                                 intel_image->base.Base.Level,
-                                 intel_image->base.Base.Level,
-                                 width, height, depth,
-                                 true,
-                                 irb->mt->num_samples,
-                                 INTEL_MIPTREE_TILING_ANY);
-
-   if (intel->vtbl.is_hiz_depth_format(intel, new_mt->format)) {
-      intel_miptree_alloc_hiz(intel, new_mt);
-   }
-
-   intel_miptree_copy_teximage(intel, intel_image, new_mt, invalidate);
-
-   intel_miptree_reference(&irb->mt, intel_image->mt);
-   intel_renderbuffer_set_draw_offset(irb);
-   intel_miptree_release(&new_mt);
-}
-
-/**
- * Do one-time context initializations related to GL_EXT_framebuffer_object.
- * Hook in device driver functions.
- */
-void
-intel_fbo_init(struct intel_context *intel)
-{
-   intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer;
-   intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer;
-   intel->ctx.Driver.MapRenderbuffer = intel_map_renderbuffer;
-   intel->ctx.Driver.UnmapRenderbuffer = intel_unmap_renderbuffer;
-   intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer;
-   intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer;
-   intel->ctx.Driver.RenderTexture = intel_render_texture;
-   intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture;
-   intel->ctx.Driver.ValidateFramebuffer = intel_validate_framebuffer;
-   intel->ctx.Driver.BlitFramebuffer = intel_blit_framebuffer;
-   intel->ctx.Driver.EGLImageTargetRenderbufferStorage =
-      intel_image_target_renderbuffer_storage;
-}
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
deleted file mode 100644 (file)
index 1776a4b..0000000
+++ /dev/null
@@ -1,2349 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-#include <GL/gl.h>
-#include <GL/internal/dri_interface.h>
-
-#include "intel_batchbuffer.h"
-#include "intel_chipset.h"
-#include "intel_context.h"
-#include "intel_mipmap_tree.h"
-#include "intel_regions.h"
-#include "intel_resolve_map.h"
-#include "intel_tex_layout.h"
-#include "intel_tex.h"
-#include "intel_blit.h"
-
-#ifndef I915
-#include "brw_blorp.h"
-#endif
-
-#include "main/enums.h"
-#include "main/formats.h"
-#include "main/glformats.h"
-#include "main/texcompress_etc.h"
-#include "main/teximage.h"
-
-#define FILE_DEBUG_FLAG DEBUG_MIPTREE
-
-static GLenum
-target_to_target(GLenum target)
-{
-   switch (target) {
-   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
-   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
-   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
-   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
-   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
-   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
-      return GL_TEXTURE_CUBE_MAP_ARB;
-   default:
-      return target;
-   }
-}
-
-
-/**
- * Determine which MSAA layout should be used by the MSAA surface being
- * created, based on the chip generation and the surface type.
- */
-static enum intel_msaa_layout
-compute_msaa_layout(struct intel_context *intel, gl_format format, GLenum target)
-{
-   /* Prior to Gen7, all MSAA surfaces used IMS layout. */
-   if (intel->gen < 7)
-      return INTEL_MSAA_LAYOUT_IMS;
-
-   /* In Gen7, IMS layout is only used for depth and stencil buffers. */
-   switch (_mesa_get_format_base_format(format)) {
-   case GL_DEPTH_COMPONENT:
-   case GL_STENCIL_INDEX:
-   case GL_DEPTH_STENCIL:
-      return INTEL_MSAA_LAYOUT_IMS;
-   default:
-      /* From the Ivy Bridge PRM, Vol4 Part1 p77 ("MCS Enable"):
-       *
-       *   This field must be set to 0 for all SINT MSRTs when all RT channels
-       *   are not written
-       *
-       * In practice this means that we have to disable MCS for all signed
-       * integer MSAA buffers.  The alternative, to disable MCS only when one
-       * of the render target channels is disabled, is impractical because it
-       * would require converting between CMS and UMS MSAA layouts on the fly,
-       * which is expensive.
-       */
-      if (_mesa_get_format_datatype(format) == GL_INT) {
-         /* TODO: is this workaround needed for future chipsets? */
-         assert(intel->gen == 7);
-         return INTEL_MSAA_LAYOUT_UMS;
-      } else {
-         /* For now, if we're going to be texturing from this surface,
-          * force UMS, so that the shader doesn't have to do different things
-          * based on whether there's a multisample control surface needing sampled first.
-          * We can't just blindly read the MCS surface in all cases because:
-          *
-          * From the Ivy Bridge PRM, Vol4 Part1 p77 ("MCS Enable"):
-          *
-          *    If this field is disabled and the sampling engine <ld_mcs> message
-          *    is issued on this surface, the MCS surface may be accessed. Software
-          *    must ensure that the surface is defined to avoid GTT errors.
-          */
-         if (target == GL_TEXTURE_2D_MULTISAMPLE ||
-             target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
-            return INTEL_MSAA_LAYOUT_UMS;
-         } else {
-            return INTEL_MSAA_LAYOUT_CMS;
-         }
-      }
-   }
-}
-
-
-/**
- * For single-sampled render targets ("non-MSRT"), the MCS buffer is a
- * scaled-down bitfield representation of the color buffer which is capable of
- * recording when blocks of the color buffer are equal to the clear value.
- * This function returns the block size that will be used by the MCS buffer
- * corresponding to a certain color miptree.
- *
- * From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render Target(s)",
- * beneath the "Fast Color Clear" bullet (p327):
- *
- *     The following table describes the RT alignment
- *
- *                       Pixels  Lines
- *         TiledY RT CL
- *             bpp
- *              32          8      4
- *              64          4      4
- *             128          2      4
- *         TiledX RT CL
- *             bpp
- *              32         16      2
- *              64          8      2
- *             128          4      2
- *
- * This alignment has the following uses:
- *
- * - For figuring out the size of the MCS buffer.  Each 4k tile in the MCS
- *   buffer contains 128 blocks horizontally and 256 blocks vertically.
- *
- * - For figuring out alignment restrictions for a fast clear operation.  Fast
- *   clear operations must always clear aligned multiples of 16 blocks
- *   horizontally and 32 blocks vertically.
- *
- * - For scaling down the coordinates sent through the render pipeline during
- *   a fast clear.  X coordinates must be scaled down by 8 times the block
- *   width, and Y coordinates by 16 times the block height.
- *
- * - For scaling down the coordinates sent through the render pipeline during
- *   a "Render Target Resolve" operation.  X coordinates must be scaled down
- *   by half the block width, and Y coordinates by half the block height.
- */
-void
-intel_get_non_msrt_mcs_alignment(struct intel_context *intel,
-                                 struct intel_mipmap_tree *mt,
-                                 unsigned *width_px, unsigned *height)
-{
-   switch (mt->region->tiling) {
-   default:
-      assert(!"Non-MSRT MCS requires X or Y tiling");
-      /* In release builds, fall through */
-   case I915_TILING_Y:
-      *width_px = 32 / mt->cpp;
-      *height = 4;
-      break;
-   case I915_TILING_X:
-      *width_px = 64 / mt->cpp;
-      *height = 2;
-   }
-}
-
-
-/**
- * For a single-sampled render target ("non-MSRT"), determine if an MCS buffer
- * can be used.
- *
- * From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render Target(s)",
- * beneath the "Fast Color Clear" bullet (p326):
- *
- *     - Support is limited to tiled render targets.
- *     - Support is for non-mip-mapped and non-array surface types only.
- *
- * And then later, on p327:
- *
- *     - MCS buffer for non-MSRT is supported only for RT formats 32bpp,
- *       64bpp, and 128bpp.
- */
-bool
-intel_is_non_msrt_mcs_buffer_supported(struct intel_context *intel,
-                                       struct intel_mipmap_tree *mt)
-{
-#ifdef I915
-   /* MCS is not supported on the i915 (pre-Gen4) driver */
-   return false;
-#else
-   struct brw_context *brw = brw_context(&intel->ctx);
-
-   /* MCS support does not exist prior to Gen7 */
-   if (intel->gen < 7)
-      return false;
-
-   /* MCS is only supported for color buffers */
-   switch (_mesa_get_format_base_format(mt->format)) {
-   case GL_DEPTH_COMPONENT:
-   case GL_DEPTH_STENCIL:
-   case GL_STENCIL_INDEX:
-      return false;
-   }
-
-   if (mt->region->tiling != I915_TILING_X &&
-       mt->region->tiling != I915_TILING_Y)
-      return false;
-   if (mt->cpp != 4 && mt->cpp != 8 && mt->cpp != 16)
-      return false;
-   if (mt->first_level != 0 || mt->last_level != 0)
-      return false;
-   if (mt->physical_depth0 != 1)
-      return false;
-
-   /* There's no point in using an MCS buffer if the surface isn't in a
-    * renderable format.
-    */
-   if (!brw->format_supported_as_render_target[mt->format])
-      return false;
-
-   return true;
-#endif
-}
-
-
-/**
- * @param for_bo Indicates that the caller is
- *        intel_miptree_create_for_bo(). If true, then do not create
- *        \c stencil_mt.
- */
-struct intel_mipmap_tree *
-intel_miptree_create_layout(struct intel_context *intel,
-                            GLenum target,
-                            gl_format format,
-                            GLuint first_level,
-                            GLuint last_level,
-                            GLuint width0,
-                            GLuint height0,
-                            GLuint depth0,
-                            bool for_bo,
-                            GLuint num_samples)
-{
-   struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
-
-   DBG("%s target %s format %s level %d..%d <-- %p\n", __FUNCTION__,
-       _mesa_lookup_enum_by_nr(target),
-       _mesa_get_format_name(format),
-       first_level, last_level, mt);
-
-   mt->target = target_to_target(target);
-   mt->format = format;
-   mt->first_level = first_level;
-   mt->last_level = last_level;
-   mt->logical_width0 = width0;
-   mt->logical_height0 = height0;
-   mt->logical_depth0 = depth0;
-#ifndef I915
-   mt->mcs_state = INTEL_MCS_STATE_NONE;
-#endif
-
-   /* The cpp is bytes per (1, blockheight)-sized block for compressed
-    * textures.  This is why you'll see divides by blockheight all over
-    */
-   unsigned bw, bh;
-   _mesa_get_format_block_size(format, &bw, &bh);
-   assert(_mesa_get_format_bytes(mt->format) % bw == 0);
-   mt->cpp = _mesa_get_format_bytes(mt->format) / bw;
-
-   mt->num_samples = num_samples;
-   mt->compressed = _mesa_is_format_compressed(format);
-   mt->msaa_layout = INTEL_MSAA_LAYOUT_NONE;
-   mt->refcount = 1; 
-
-   if (num_samples > 1) {
-      /* Adjust width/height/depth for MSAA */
-      mt->msaa_layout = compute_msaa_layout(intel, format, mt->target);
-      if (mt->msaa_layout == INTEL_MSAA_LAYOUT_IMS) {
-         /* In the Sandy Bridge PRM, volume 4, part 1, page 31, it says:
-          *
-          *     "Any of the other messages (sample*, LOD, load4) used with a
-          *      (4x) multisampled surface will in-effect sample a surface with
-          *      double the height and width as that indicated in the surface
-          *      state. Each pixel position on the original-sized surface is
-          *      replaced with a 2x2 of samples with the following arrangement:
-          *
-          *         sample 0 sample 2
-          *         sample 1 sample 3"
-          *
-          * Thus, when sampling from a multisampled texture, it behaves as
-          * though the layout in memory for (x,y,sample) is:
-          *
-          *      (0,0,0) (0,0,2)   (1,0,0) (1,0,2)
-          *      (0,0,1) (0,0,3)   (1,0,1) (1,0,3)
-          *
-          *      (0,1,0) (0,1,2)   (1,1,0) (1,1,2)
-          *      (0,1,1) (0,1,3)   (1,1,1) (1,1,3)
-          *
-          * However, the actual layout of multisampled data in memory is:
-          *
-          *      (0,0,0) (1,0,0)   (0,0,1) (1,0,1)
-          *      (0,1,0) (1,1,0)   (0,1,1) (1,1,1)
-          *
-          *      (0,0,2) (1,0,2)   (0,0,3) (1,0,3)
-          *      (0,1,2) (1,1,2)   (0,1,3) (1,1,3)
-          *
-          * This pattern repeats for each 2x2 pixel block.
-          *
-          * As a result, when calculating the size of our 4-sample buffer for
-          * an odd width or height, we have to align before scaling up because
-          * sample 3 is in that bottom right 2x2 block.
-          */
-         switch (num_samples) {
-         case 4:
-            width0 = ALIGN(width0, 2) * 2;
-            height0 = ALIGN(height0, 2) * 2;
-            break;
-         case 8:
-            width0 = ALIGN(width0, 2) * 4;
-            height0 = ALIGN(height0, 2) * 2;
-            break;
-         default:
-            /* num_samples should already have been quantized to 0, 1, 4, or
-             * 8.
-             */
-            assert(false);
-         }
-      } else {
-         /* Non-interleaved */
-         depth0 *= num_samples;
-      }
-   }
-
-   /* array_spacing_lod0 is only used for non-IMS MSAA surfaces.  TODO: can we
-    * use it elsewhere?
-    */
-   switch (mt->msaa_layout) {
-   case INTEL_MSAA_LAYOUT_NONE:
-   case INTEL_MSAA_LAYOUT_IMS:
-      mt->array_spacing_lod0 = false;
-      break;
-   case INTEL_MSAA_LAYOUT_UMS:
-   case INTEL_MSAA_LAYOUT_CMS:
-      mt->array_spacing_lod0 = true;
-      break;
-   }
-
-   if (target == GL_TEXTURE_CUBE_MAP) {
-      assert(depth0 == 1);
-      depth0 = 6;
-   }
-
-   mt->physical_width0 = width0;
-   mt->physical_height0 = height0;
-   mt->physical_depth0 = depth0;
-
-   if (!for_bo &&
-       _mesa_get_format_base_format(format) == GL_DEPTH_STENCIL &&
-       (intel->must_use_separate_stencil ||
-       (intel->has_separate_stencil &&
-        intel->vtbl.is_hiz_depth_format(intel, format)))) {
-      mt->stencil_mt = intel_miptree_create(intel,
-                                            mt->target,
-                                            MESA_FORMAT_S8,
-                                            mt->first_level,
-                                            mt->last_level,
-                                            mt->logical_width0,
-                                            mt->logical_height0,
-                                            mt->logical_depth0,
-                                            true,
-                                            num_samples,
-                                            INTEL_MIPTREE_TILING_ANY);
-      if (!mt->stencil_mt) {
-        intel_miptree_release(&mt);
-        return NULL;
-      }
-
-      /* Fix up the Z miptree format for how we're splitting out separate
-       * stencil.  Gen7 expects there to be no stencil bits in its depth buffer.
-       */
-      if (mt->format == MESA_FORMAT_S8_Z24) {
-        mt->format = MESA_FORMAT_X8_Z24;
-      } else if (mt->format == MESA_FORMAT_Z32_FLOAT_X24S8) {
-        mt->format = MESA_FORMAT_Z32_FLOAT;
-        mt->cpp = 4;
-      } else {
-        _mesa_problem(NULL, "Unknown format %s in separate stencil mt\n",
-                      _mesa_get_format_name(mt->format));
-      }
-   }
-
-   intel_get_texture_alignment_unit(intel, mt->format,
-                                   &mt->align_w, &mt->align_h);
-
-#ifdef I915
-   (void) intel;
-   if (intel->is_945)
-      i945_miptree_layout(mt);
-   else
-      i915_miptree_layout(mt);
-#else
-   brw_miptree_layout(intel, mt);
-#endif
-
-   return mt;
-}
-
-/**
- * \brief Helper function for intel_miptree_create().
- */
-static uint32_t
-intel_miptree_choose_tiling(struct intel_context *intel,
-                            gl_format format,
-                            uint32_t width0,
-                            uint32_t num_samples,
-                            enum intel_miptree_tiling_mode requested,
-                            struct intel_mipmap_tree *mt)
-{
-
-   if (format == MESA_FORMAT_S8) {
-      /* The stencil buffer is W tiled. However, we request from the kernel a
-       * non-tiled buffer because the GTT is incapable of W fencing.
-       */
-      return I915_TILING_NONE;
-   }
-
-   /* Some usages may want only one type of tiling, like depth miptrees (Y
-    * tiled), or temporary BOs for uploading data once (linear).
-    */
-   switch (requested) {
-   case INTEL_MIPTREE_TILING_ANY:
-      break;
-   case INTEL_MIPTREE_TILING_Y:
-      return I915_TILING_Y;
-   case INTEL_MIPTREE_TILING_NONE:
-      return I915_TILING_NONE;
-   }
-
-   if (num_samples > 1) {
-      /* From p82 of the Sandy Bridge PRM, dw3[1] of SURFACE_STATE ("Tiled
-       * Surface"):
-       *
-       *   [DevSNB+]: For multi-sample render targets, this field must be
-       *   1. MSRTs can only be tiled.
-       *
-       * Our usual reason for preferring X tiling (fast blits using the
-       * blitting engine) doesn't apply to MSAA, since we'll generally be
-       * downsampling or upsampling when blitting between the MSAA buffer
-       * and another buffer, and the blitting engine doesn't support that.
-       * So use Y tiling, since it makes better use of the cache.
-       */
-      return I915_TILING_Y;
-   }
-
-   GLenum base_format = _mesa_get_format_base_format(format);
-   if (intel->gen >= 4 &&
-       (base_format == GL_DEPTH_COMPONENT ||
-        base_format == GL_DEPTH_STENCIL_EXT))
-      return I915_TILING_Y;
-
-   int minimum_pitch = mt->total_width * mt->cpp;
-
-   /* If the width is much smaller than a tile, don't bother tiling. */
-   if (minimum_pitch < 64)
-      return I915_TILING_NONE;
-
-   if (ALIGN(minimum_pitch, 512) >= 32768) {
-      perf_debug("%dx%d miptree too large to blit, falling back to untiled",
-                 mt->total_width, mt->total_height);
-      return I915_TILING_NONE;
-   }
-
-   /* Pre-gen6 doesn't have BLORP to handle Y-tiling, so use X-tiling. */
-   if (intel->gen < 6)
-      return I915_TILING_X;
-
-   return I915_TILING_Y | I915_TILING_X;
-}
-
-struct intel_mipmap_tree *
-intel_miptree_create(struct intel_context *intel,
-                    GLenum target,
-                    gl_format format,
-                    GLuint first_level,
-                    GLuint last_level,
-                    GLuint width0,
-                    GLuint height0,
-                    GLuint depth0,
-                    bool expect_accelerated_upload,
-                     GLuint num_samples,
-                     enum intel_miptree_tiling_mode requested_tiling)
-{
-   struct intel_mipmap_tree *mt;
-   gl_format tex_format = format;
-   gl_format etc_format = MESA_FORMAT_NONE;
-   GLuint total_width, total_height;
-
-   if (!intel->is_baytrail) {
-      switch (format) {
-      case MESA_FORMAT_ETC1_RGB8:
-         format = MESA_FORMAT_RGBX8888_REV;
-         break;
-      case MESA_FORMAT_ETC2_RGB8:
-         format = MESA_FORMAT_RGBX8888_REV;
-         break;
-      case MESA_FORMAT_ETC2_SRGB8:
-      case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
-      case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
-         format = MESA_FORMAT_SARGB8;
-         break;
-      case MESA_FORMAT_ETC2_RGBA8_EAC:
-      case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
-         format = MESA_FORMAT_RGBA8888_REV;
-         break;
-      case MESA_FORMAT_ETC2_R11_EAC:
-         format = MESA_FORMAT_R16;
-         break;
-      case MESA_FORMAT_ETC2_SIGNED_R11_EAC:
-         format = MESA_FORMAT_SIGNED_R16;
-         break;
-      case MESA_FORMAT_ETC2_RG11_EAC:
-         format = MESA_FORMAT_GR1616;
-         break;
-      case MESA_FORMAT_ETC2_SIGNED_RG11_EAC:
-         format = MESA_FORMAT_SIGNED_GR1616;
-         break;
-      default:
-         /* Non ETC1 / ETC2 format */
-         break;
-      }
-   }
-
-   etc_format = (format != tex_format) ? tex_format : MESA_FORMAT_NONE;
-
-   mt = intel_miptree_create_layout(intel, target, format,
-                                     first_level, last_level, width0,
-                                     height0, depth0,
-                                     false, num_samples);
-   /*
-    * pitch == 0 || height == 0  indicates the null texture
-    */
-   if (!mt || !mt->total_width || !mt->total_height) {
-      intel_miptree_release(&mt);
-      return NULL;
-   }
-
-   total_width = mt->total_width;
-   total_height = mt->total_height;
-
-   if (format == MESA_FORMAT_S8) {
-      /* Align to size of W tile, 64x64. */
-      total_width = ALIGN(total_width, 64);
-      total_height = ALIGN(total_height, 64);
-   }
-
-   uint32_t tiling = intel_miptree_choose_tiling(intel, format, width0,
-                                                 num_samples, requested_tiling,
-                                                 mt);
-   bool y_or_x = tiling == (I915_TILING_Y | I915_TILING_X);
-
-   mt->etc_format = etc_format;
-   mt->region = intel_region_alloc(intel->intelScreen,
-                                  y_or_x ? I915_TILING_Y : tiling,
-                                  mt->cpp,
-                                  total_width,
-                                  total_height,
-                                  expect_accelerated_upload);
-
-   /* If the region is too large to fit in the aperture, we need to use the
-    * BLT engine to support it.  The BLT paths can't currently handle Y-tiling,
-    * so we need to fall back to X.
-    */
-   if (y_or_x && mt->region->bo->size >= intel->max_gtt_map_object_size) {
-      perf_debug("%dx%d miptree larger than aperture; falling back to X-tiled\n",
-                 mt->total_width, mt->total_height);
-      intel_region_release(&mt->region);
-
-      mt->region = intel_region_alloc(intel->intelScreen,
-                                      I915_TILING_X,
-                                      mt->cpp,
-                                      total_width,
-                                      total_height,
-                                      expect_accelerated_upload);
-   }
-
-   mt->offset = 0;
-
-   if (!mt->region) {
-       intel_miptree_release(&mt);
-       return NULL;
-   }
-
-#ifndef I915
-   /* If this miptree is capable of supporting fast color clears, set
-    * mcs_state appropriately to ensure that fast clears will occur.
-    * Allocation of the MCS miptree will be deferred until the first fast
-    * clear actually occurs.
-    */
-   if (intel_is_non_msrt_mcs_buffer_supported(intel, mt))
-      mt->mcs_state = INTEL_MCS_STATE_RESOLVED;
-#endif
-
-   return mt;
-}
-
-struct intel_mipmap_tree *
-intel_miptree_create_for_bo(struct intel_context *intel,
-                            drm_intel_bo *bo,
-                            gl_format format,
-                            uint32_t offset,
-                            uint32_t width,
-                            uint32_t height,
-                            int pitch,
-                            uint32_t tiling)
-{
-   struct intel_mipmap_tree *mt;
-
-   struct intel_region *region = calloc(1, sizeof(*region));
-   if (!region)
-      return NULL;
-
-   /* Nothing will be able to use this miptree with the BO if the offset isn't
-    * aligned.
-    */
-   if (tiling != I915_TILING_NONE)
-      assert(offset % 4096 == 0);
-
-   /* miptrees can't handle negative pitch.  If you need flipping of images,
-    * that's outside of the scope of the mt.
-    */
-   assert(pitch >= 0);
-
-   mt = intel_miptree_create_layout(intel, GL_TEXTURE_2D, format,
-                                    0, 0,
-                                    width, height, 1,
-                                    true, 0 /* num_samples */);
-   if (!mt)
-      return mt;
-
-   region->cpp = mt->cpp;
-   region->width = width;
-   region->height = height;
-   region->pitch = pitch;
-   region->refcount = 1;
-   drm_intel_bo_reference(bo);
-   region->bo = bo;
-   region->tiling = tiling;
-
-   mt->region = region;
-   mt->offset = offset;
-
-   return mt;
-}
-
-
-/**
- * For a singlesample DRI2 buffer, this simply wraps the given region with a miptree.
- *
- * For a multisample DRI2 buffer, this wraps the given region with
- * a singlesample miptree, then creates a multisample miptree into which the
- * singlesample miptree is embedded as a child.
- */
-struct intel_mipmap_tree*
-intel_miptree_create_for_dri2_buffer(struct intel_context *intel,
-                                     unsigned dri_attachment,
-                                     gl_format format,
-                                     uint32_t num_samples,
-                                     struct intel_region *region)
-{
-   struct intel_mipmap_tree *singlesample_mt = NULL;
-   struct intel_mipmap_tree *multisample_mt = NULL;
-
-   /* Only the front and back buffers, which are color buffers, are shared
-    * through DRI2.
-    */
-   assert(dri_attachment == __DRI_BUFFER_BACK_LEFT ||
-          dri_attachment == __DRI_BUFFER_FRONT_LEFT ||
-          dri_attachment == __DRI_BUFFER_FAKE_FRONT_LEFT);
-   assert(_mesa_get_format_base_format(format) == GL_RGB ||
-          _mesa_get_format_base_format(format) == GL_RGBA);
-
-   singlesample_mt = intel_miptree_create_for_bo(intel,
-                                                 region->bo,
-                                                 format,
-                                                 0,
-                                                 region->width,
-                                                 region->height,
-                                                 region->pitch,
-                                                 region->tiling);
-   if (!singlesample_mt)
-      return NULL;
-   singlesample_mt->region->name = region->name;
-
-#ifndef I915
-   /* If this miptree is capable of supporting fast color clears, set
-    * mcs_state appropriately to ensure that fast clears will occur.
-    * Allocation of the MCS miptree will be deferred until the first fast
-    * clear actually occurs.
-    */
-   if (intel_is_non_msrt_mcs_buffer_supported(intel, singlesample_mt))
-      singlesample_mt->mcs_state = INTEL_MCS_STATE_RESOLVED;
-#endif
-
-   if (num_samples == 0)
-      return singlesample_mt;
-
-   multisample_mt = intel_miptree_create_for_renderbuffer(intel,
-                                                          format,
-                                                          region->width,
-                                                          region->height,
-                                                          num_samples);
-   if (!multisample_mt) {
-      intel_miptree_release(&singlesample_mt);
-      return NULL;
-   }
-
-   multisample_mt->singlesample_mt = singlesample_mt;
-   multisample_mt->need_downsample = false;
-
-   if (intel->is_front_buffer_rendering &&
-       (dri_attachment == __DRI_BUFFER_FRONT_LEFT ||
-        dri_attachment == __DRI_BUFFER_FAKE_FRONT_LEFT)) {
-      intel_miptree_upsample(intel, multisample_mt);
-   }
-
-   return multisample_mt;
-}
-
-struct intel_mipmap_tree*
-intel_miptree_create_for_renderbuffer(struct intel_context *intel,
-                                      gl_format format,
-                                      uint32_t width,
-                                      uint32_t height,
-                                      uint32_t num_samples)
-{
-   struct intel_mipmap_tree *mt;
-   uint32_t depth = 1;
-   bool ok;
-
-   mt = intel_miptree_create(intel, GL_TEXTURE_2D, format, 0, 0,
-                            width, height, depth, true, num_samples,
-                             INTEL_MIPTREE_TILING_ANY);
-   if (!mt)
-      goto fail;
-
-   if (intel->vtbl.is_hiz_depth_format(intel, format)) {
-      ok = intel_miptree_alloc_hiz(intel, mt);
-      if (!ok)
-         goto fail;
-   }
-
-   if (mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) {
-      ok = intel_miptree_alloc_mcs(intel, mt, num_samples);
-      if (!ok)
-         goto fail;
-   }
-
-   return mt;
-
-fail:
-   intel_miptree_release(&mt);
-   return NULL;
-}
-
-void
-intel_miptree_reference(struct intel_mipmap_tree **dst,
-                        struct intel_mipmap_tree *src)
-{
-   if (*dst == src)
-      return;
-
-   intel_miptree_release(dst);
-
-   if (src) {
-      src->refcount++;
-      DBG("%s %p refcount now %d\n", __FUNCTION__, src, src->refcount);
-   }
-
-   *dst = src;
-}
-
-
-void
-intel_miptree_release(struct intel_mipmap_tree **mt)
-{
-   if (!*mt)
-      return;
-
-   DBG("%s %p refcount will be %d\n", __FUNCTION__, *mt, (*mt)->refcount - 1);
-   if (--(*mt)->refcount <= 0) {
-      GLuint i;
-
-      DBG("%s deleting %p\n", __FUNCTION__, *mt);
-
-      intel_region_release(&((*mt)->region));
-      intel_miptree_release(&(*mt)->stencil_mt);
-      intel_miptree_release(&(*mt)->hiz_mt);
-#ifndef I915
-      intel_miptree_release(&(*mt)->mcs_mt);
-#endif
-      intel_miptree_release(&(*mt)->singlesample_mt);
-      intel_resolve_map_clear(&(*mt)->hiz_map);
-
-      for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
-        free((*mt)->level[i].slice);
-      }
-
-      free(*mt);
-   }
-   *mt = NULL;
-}
-
-void
-intel_miptree_get_dimensions_for_image(struct gl_texture_image *image,
-                                       int *width, int *height, int *depth)
-{
-   switch (image->TexObject->Target) {
-   case GL_TEXTURE_1D_ARRAY:
-      *width = image->Width;
-      *height = 1;
-      *depth = image->Height;
-      break;
-   default:
-      *width = image->Width;
-      *height = image->Height;
-      *depth = image->Depth;
-      break;
-   }
-}
-
-/**
- * Can the image be pulled into a unified mipmap tree?  This mirrors
- * the completeness test in a lot of ways.
- *
- * Not sure whether I want to pass gl_texture_image here.
- */
-bool
-intel_miptree_match_image(struct intel_mipmap_tree *mt,
-                          struct gl_texture_image *image)
-{
-   struct intel_texture_image *intelImage = intel_texture_image(image);
-   GLuint level = intelImage->base.Base.Level;
-   int width, height, depth;
-
-   /* glTexImage* choose the texture object based on the target passed in, and
-    * objects can't change targets over their lifetimes, so this should be
-    * true.
-    */
-   assert(target_to_target(image->TexObject->Target) == mt->target);
-
-   gl_format mt_format = mt->format;
-   if (mt->format == MESA_FORMAT_X8_Z24 && mt->stencil_mt)
-      mt_format = MESA_FORMAT_S8_Z24;
-   if (mt->format == MESA_FORMAT_Z32_FLOAT && mt->stencil_mt)
-      mt_format = MESA_FORMAT_Z32_FLOAT_X24S8;
-   if (mt->etc_format != MESA_FORMAT_NONE)
-      mt_format = mt->etc_format;
-
-   if (image->TexFormat != mt_format)
-      return false;
-
-   intel_miptree_get_dimensions_for_image(image, &width, &height, &depth);
-
-   if (mt->target == GL_TEXTURE_CUBE_MAP)
-      depth = 6;
-
-   /* Test image dimensions against the base level image adjusted for
-    * minification.  This will also catch images not present in the
-    * tree, changed targets, etc.
-    */
-   if (mt->target == GL_TEXTURE_2D_MULTISAMPLE ||
-         mt->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
-      /* nonzero level here is always bogus */
-      assert(level == 0);
-
-      if (width != mt->logical_width0 ||
-            height != mt->logical_height0 ||
-            depth != mt->logical_depth0) {
-         return false;
-      }
-   }
-   else {
-      /* all normal textures, renderbuffers, etc */
-      if (width != mt->level[level].width ||
-          height != mt->level[level].height ||
-          depth != mt->level[level].depth) {
-         return false;
-      }
-   }
-
-   if (image->NumSamples != mt->num_samples)
-      return false;
-
-   return true;
-}
-
-
-void
-intel_miptree_set_level_info(struct intel_mipmap_tree *mt,
-                            GLuint level,
-                            GLuint x, GLuint y,
-                            GLuint w, GLuint h, GLuint d)
-{
-   mt->level[level].width = w;
-   mt->level[level].height = h;
-   mt->level[level].depth = d;
-   mt->level[level].level_x = x;
-   mt->level[level].level_y = y;
-
-   DBG("%s level %d size: %d,%d,%d offset %d,%d\n", __FUNCTION__,
-       level, w, h, d, x, y);
-
-   assert(mt->level[level].slice == NULL);
-
-   mt->level[level].slice = calloc(d, sizeof(*mt->level[0].slice));
-   mt->level[level].slice[0].x_offset = mt->level[level].level_x;
-   mt->level[level].slice[0].y_offset = mt->level[level].level_y;
-}
-
-
-void
-intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
-                              GLuint level, GLuint img,
-                              GLuint x, GLuint y)
-{
-   if (img == 0 && level == 0)
-      assert(x == 0 && y == 0);
-
-   assert(img < mt->level[level].depth);
-
-   mt->level[level].slice[img].x_offset = mt->level[level].level_x + x;
-   mt->level[level].slice[img].y_offset = mt->level[level].level_y + y;
-
-   DBG("%s level %d img %d pos %d,%d\n",
-       __FUNCTION__, level, img,
-       mt->level[level].slice[img].x_offset,
-       mt->level[level].slice[img].y_offset);
-}
-
-void
-intel_miptree_get_image_offset(struct intel_mipmap_tree *mt,
-                              GLuint level, GLuint slice,
-                              GLuint *x, GLuint *y)
-{
-   assert(slice < mt->level[level].depth);
-
-   *x = mt->level[level].slice[slice].x_offset;
-   *y = mt->level[level].slice[slice].y_offset;
-}
-
-/**
- * Rendering with tiled buffers requires that the base address of the buffer
- * be aligned to a page boundary.  For renderbuffers, and sometimes with
- * textures, we may want the surface to point at a texture image level that
- * isn't at a page boundary.
- *
- * This function returns an appropriately-aligned base offset
- * according to the tiling restrictions, plus any required x/y offset
- * from there.
- */
-uint32_t
-intel_miptree_get_tile_offsets(struct intel_mipmap_tree *mt,
-                               GLuint level, GLuint slice,
-                               uint32_t *tile_x,
-                               uint32_t *tile_y)
-{
-   struct intel_region *region = mt->region;
-   uint32_t x, y;
-   uint32_t mask_x, mask_y;
-
-   intel_region_get_tile_masks(region, &mask_x, &mask_y, false);
-   intel_miptree_get_image_offset(mt, level, slice, &x, &y);
-
-   *tile_x = x & mask_x;
-   *tile_y = y & mask_y;
-
-   return intel_region_get_aligned_offset(region, x & ~mask_x, y & ~mask_y,
-                                          false);
-}
-
-static void
-intel_miptree_copy_slice_sw(struct intel_context *intel,
-                            struct intel_mipmap_tree *dst_mt,
-                            struct intel_mipmap_tree *src_mt,
-                            int level,
-                            int slice,
-                            int width,
-                            int height)
-{
-   void *src, *dst;
-   int src_stride, dst_stride;
-   int cpp = dst_mt->cpp;
-
-   intel_miptree_map(intel, src_mt,
-                     level, slice,
-                     0, 0,
-                     width, height,
-                     GL_MAP_READ_BIT | BRW_MAP_DIRECT_BIT,
-                     &src, &src_stride);
-
-   intel_miptree_map(intel, dst_mt,
-                     level, slice,
-                     0, 0,
-                     width, height,
-                     GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT |
-                     BRW_MAP_DIRECT_BIT,
-                     &dst, &dst_stride);
-
-   DBG("sw blit %s mt %p %p/%d -> %s mt %p %p/%d (%dx%d)\n",
-       _mesa_get_format_name(src_mt->format),
-       src_mt, src, src_stride,
-       _mesa_get_format_name(dst_mt->format),
-       dst_mt, dst, dst_stride,
-       width, height);
-
-   int row_size = cpp * width;
-   if (src_stride == row_size &&
-       dst_stride == row_size) {
-      memcpy(dst, src, row_size * height);
-   } else {
-      for (int i = 0; i < height; i++) {
-         memcpy(dst, src, row_size);
-         dst += dst_stride;
-         src += src_stride;
-      }
-   }
-
-   intel_miptree_unmap(intel, dst_mt, level, slice);
-   intel_miptree_unmap(intel, src_mt, level, slice);
-
-   /* Don't forget to copy the stencil data over, too.  We could have skipped
-    * passing BRW_MAP_DIRECT_BIT, but that would have meant intel_miptree_map
-    * shuffling the two data sources in/out of temporary storage instead of
-    * the direct mapping we get this way.
-    */
-   if (dst_mt->stencil_mt) {
-      assert(src_mt->stencil_mt);
-      intel_miptree_copy_slice_sw(intel, dst_mt->stencil_mt, src_mt->stencil_mt,
-                                  level, slice, width, height);
-   }
-}
-
-static void
-intel_miptree_copy_slice(struct intel_context *intel,
-                        struct intel_mipmap_tree *dst_mt,
-                        struct intel_mipmap_tree *src_mt,
-                        int level,
-                        int face,
-                        int depth)
-
-{
-   gl_format format = src_mt->format;
-   uint32_t width = src_mt->level[level].width;
-   uint32_t height = src_mt->level[level].height;
-   int slice;
-
-   if (face > 0)
-      slice = face;
-   else
-      slice = depth;
-
-   assert(depth < src_mt->level[level].depth);
-   assert(src_mt->format == dst_mt->format);
-
-   if (dst_mt->compressed) {
-      height = ALIGN(height, dst_mt->align_h) / dst_mt->align_h;
-      width = ALIGN(width, dst_mt->align_w);
-   }
-
-   /* If it's a packed depth/stencil buffer with separate stencil, the blit
-    * below won't apply since we can't do the depth's Y tiling or the
-    * stencil's W tiling in the blitter.
-    */
-   if (src_mt->stencil_mt) {
-      intel_miptree_copy_slice_sw(intel,
-                                  dst_mt, src_mt,
-                                  level, slice,
-                                  width, height);
-      return;
-   }
-
-   uint32_t dst_x, dst_y, src_x, src_y;
-   intel_miptree_get_image_offset(dst_mt, level, slice, &dst_x, &dst_y);
-   intel_miptree_get_image_offset(src_mt, level, slice, &src_x, &src_y);
-
-   DBG("validate blit mt %s %p %d,%d/%d -> mt %s %p %d,%d/%d (%dx%d)\n",
-       _mesa_get_format_name(src_mt->format),
-       src_mt, src_x, src_y, src_mt->region->pitch,
-       _mesa_get_format_name(dst_mt->format),
-       dst_mt, dst_x, dst_y, dst_mt->region->pitch,
-       width, height);
-
-   if (!intel_miptree_blit(intel,
-                           src_mt, level, slice, 0, 0, false,
-                           dst_mt, level, slice, 0, 0, false,
-                           width, height, GL_COPY)) {
-      perf_debug("miptree validate blit for %s failed\n",
-                 _mesa_get_format_name(format));
-
-      intel_miptree_copy_slice_sw(intel, dst_mt, src_mt, level, slice,
-                                  width, height);
-   }
-}
-
-/**
- * Copies the image's current data to the given miptree, and associates that
- * miptree with the image.
- *
- * If \c invalidate is true, then the actual image data does not need to be
- * copied, but the image still needs to be associated to the new miptree (this
- * is set to true if we're about to clear the image).
- */
-void
-intel_miptree_copy_teximage(struct intel_context *intel,
-                           struct intel_texture_image *intelImage,
-                           struct intel_mipmap_tree *dst_mt,
-                            bool invalidate)
-{
-   struct intel_mipmap_tree *src_mt = intelImage->mt;
-   struct intel_texture_object *intel_obj =
-      intel_texture_object(intelImage->base.Base.TexObject);
-   int level = intelImage->base.Base.Level;
-   int face = intelImage->base.Base.Face;
-   GLuint depth = intelImage->base.Base.Depth;
-
-   if (!invalidate) {
-      for (int slice = 0; slice < depth; slice++) {
-         intel_miptree_copy_slice(intel, dst_mt, src_mt, level, face, slice);
-      }
-   }
-
-   intel_miptree_reference(&intelImage->mt, dst_mt);
-   intel_obj->needs_validate = true;
-}
-
-bool
-intel_miptree_alloc_mcs(struct intel_context *intel,
-                        struct intel_mipmap_tree *mt,
-                        GLuint num_samples)
-{
-   assert(intel->gen >= 7); /* MCS only used on Gen7+ */
-#ifdef I915
-   return false;
-#else
-   assert(mt->mcs_mt == NULL);
-
-   /* Choose the correct format for the MCS buffer.  All that really matters
-    * is that we allocate the right buffer size, since we'll always be
-    * accessing this miptree using MCS-specific hardware mechanisms, which
-    * infer the correct format based on num_samples.
-    */
-   gl_format format;
-   switch (num_samples) {
-   case 4:
-      /* 8 bits/pixel are required for MCS data when using 4x MSAA (2 bits for
-       * each sample).
-       */
-      format = MESA_FORMAT_R8;
-      break;
-   case 8:
-      /* 32 bits/pixel are required for MCS data when using 8x MSAA (3 bits
-       * for each sample, plus 8 padding bits).
-       */
-      format = MESA_FORMAT_R_UINT32;
-      break;
-   default:
-      assert(!"Unrecognized sample count in intel_miptree_alloc_mcs");
-      return false;
-   };
-
-   /* From the Ivy Bridge PRM, Vol4 Part1 p76, "MCS Base Address":
-    *
-    *     "The MCS surface must be stored as Tile Y."
-    */
-   mt->mcs_state = INTEL_MCS_STATE_MSAA;
-   mt->mcs_mt = intel_miptree_create(intel,
-                                     mt->target,
-                                     format,
-                                     mt->first_level,
-                                     mt->last_level,
-                                     mt->logical_width0,
-                                     mt->logical_height0,
-                                     mt->logical_depth0,
-                                     true,
-                                     0 /* num_samples */,
-                                     INTEL_MIPTREE_TILING_Y);
-
-   /* From the Ivy Bridge PRM, Vol 2 Part 1 p326:
-    *
-    *     When MCS buffer is enabled and bound to MSRT, it is required that it
-    *     is cleared prior to any rendering.
-    *
-    * Since we don't use the MCS buffer for any purpose other than rendering,
-    * it makes sense to just clear it immediately upon allocation.
-    *
-    * Note: the clear value for MCS buffers is all 1's, so we memset to 0xff.
-    */
-   void *data = intel_miptree_map_raw(intel, mt->mcs_mt);
-   memset(data, 0xff, mt->mcs_mt->region->bo->size);
-   intel_miptree_unmap_raw(intel, mt->mcs_mt);
-
-   return mt->mcs_mt;
-#endif
-}
-
-
-bool
-intel_miptree_alloc_non_msrt_mcs(struct intel_context *intel,
-                                 struct intel_mipmap_tree *mt)
-{
-#ifdef I915
-   assert(!"MCS not supported on i915");
-   return false;
-#else
-   assert(mt->mcs_mt == NULL);
-
-   /* The format of the MCS buffer is opaque to the driver; all that matters
-    * is that we get its size and pitch right.  We'll pretend that the format
-    * is R32.  Since an MCS tile covers 128 blocks horizontally, and a Y-tiled
-    * R32 buffer is 32 pixels across, we'll need to scale the width down by
-    * the block width and then a further factor of 4.  Since an MCS tile
-    * covers 256 blocks vertically, and a Y-tiled R32 buffer is 32 rows high,
-    * we'll need to scale the height down by the block height and then a
-    * further factor of 8.
-    */
-   const gl_format format = MESA_FORMAT_R_UINT32;
-   unsigned block_width_px;
-   unsigned block_height;
-   intel_get_non_msrt_mcs_alignment(intel, mt, &block_width_px, &block_height);
-   unsigned width_divisor = block_width_px * 4;
-   unsigned height_divisor = block_height * 8;
-   unsigned mcs_width =
-      ALIGN(mt->logical_width0, width_divisor) / width_divisor;
-   unsigned mcs_height =
-      ALIGN(mt->logical_height0, height_divisor) / height_divisor;
-   assert(mt->logical_depth0 == 1);
-   mt->mcs_mt = intel_miptree_create(intel,
-                                     mt->target,
-                                     format,
-                                     mt->first_level,
-                                     mt->last_level,
-                                     mcs_width,
-                                     mcs_height,
-                                     mt->logical_depth0,
-                                     true,
-                                     0 /* num_samples */,
-                                     INTEL_MIPTREE_TILING_Y);
-
-   return mt->mcs_mt;
-#endif
-}
-
-
-/**
- * Helper for intel_miptree_alloc_hiz() that sets
- * \c mt->level[level].slice[layer].has_hiz. Return true if and only if
- * \c has_hiz was set.
- */
-static bool
-intel_miptree_slice_enable_hiz(struct intel_context *intel,
-                               struct intel_mipmap_tree *mt,
-                               uint32_t level,
-                               uint32_t layer)
-{
-   assert(mt->hiz_mt);
-
-   if (intel->is_haswell) {
-      /* Disable HiZ for some slices to work around a hardware bug.
-       *
-       * Haswell hardware fails to respect
-       * 3DSTATE_DEPTH_BUFFER.Depth_Coordinate_Offset_X/Y when during HiZ
-       * ambiguate operations.  The failure is inconsistent and affected by
-       * other GPU contexts. Running a heavy GPU workload in a separate
-       * process causes the failure rate to drop to nearly 0.
-       *
-       * To workaround the bug, we enable HiZ only when we can guarantee that
-       * the Depth Coordinate Offset fields will be set to 0. The function
-       * brw_get_depthstencil_tile_masks() is used to calculate the fields,
-       * and the function is sometimes called in such a way that the presence
-       * of an attached stencil buffer changes the fuction's return value.
-       *
-       * The largest tile size considered by brw_get_depthstencil_tile_masks()
-       * is that of the stencil buffer. Therefore, if this hiz slice's
-       * corresponding depth slice has an offset that is aligned to the
-       * stencil buffer tile size, 64x64 pixels, then
-       * 3DSTATE_DEPTH_BUFFER.Depth_Coordinate_Offset_X/Y is set to 0.
-       */
-      uint32_t depth_x_offset = mt->level[level].slice[layer].x_offset;
-      uint32_t depth_y_offset = mt->level[level].slice[layer].y_offset;
-      if ((depth_x_offset & 63) || (depth_y_offset & 63)) {
-         return false;
-      }
-   }
-
-   mt->level[level].slice[layer].has_hiz = true;
-   return true;
-}
-
-
-
-bool
-intel_miptree_alloc_hiz(struct intel_context *intel,
-                       struct intel_mipmap_tree *mt)
-{
-   assert(mt->hiz_mt == NULL);
-   mt->hiz_mt = intel_miptree_create(intel,
-                                     mt->target,
-                                     mt->format,
-                                     mt->first_level,
-                                     mt->last_level,
-                                     mt->logical_width0,
-                                     mt->logical_height0,
-                                     mt->logical_depth0,
-                                     true,
-                                     mt->num_samples,
-                                     INTEL_MIPTREE_TILING_ANY);
-
-   if (!mt->hiz_mt)
-      return false;
-
-   /* Mark that all slices need a HiZ resolve. */
-   struct intel_resolve_map *head = &mt->hiz_map;
-   for (int level = mt->first_level; level <= mt->last_level; ++level) {
-      for (int layer = 0; layer < mt->level[level].depth; ++layer) {
-         if (!intel_miptree_slice_enable_hiz(intel, mt, level, layer))
-            continue;
-
-        head->next = malloc(sizeof(*head->next));
-        head->next->prev = head;
-        head->next->next = NULL;
-        head = head->next;
-
-        head->level = level;
-        head->layer = layer;
-        head->need = GEN6_HIZ_OP_HIZ_RESOLVE;
-      }
-   }
-
-   return true;
-}
-
-/**
- * Does the miptree slice have hiz enabled?
- */
-bool
-intel_miptree_slice_has_hiz(struct intel_mipmap_tree *mt,
-                            uint32_t level,
-                            uint32_t layer)
-{
-   intel_miptree_check_level_layer(mt, level, layer);
-   return mt->level[level].slice[layer].has_hiz;
-}
-
-void
-intel_miptree_slice_set_needs_hiz_resolve(struct intel_mipmap_tree *mt,
-                                         uint32_t level,
-                                         uint32_t layer)
-{
-   if (!intel_miptree_slice_has_hiz(mt, level, layer))
-      return;
-
-   intel_resolve_map_set(&mt->hiz_map,
-                        level, layer, GEN6_HIZ_OP_HIZ_RESOLVE);
-}
-
-
-void
-intel_miptree_slice_set_needs_depth_resolve(struct intel_mipmap_tree *mt,
-                                            uint32_t level,
-                                            uint32_t layer)
-{
-   if (!intel_miptree_slice_has_hiz(mt, level, layer))
-      return;
-
-   intel_resolve_map_set(&mt->hiz_map,
-                        level, layer, GEN6_HIZ_OP_DEPTH_RESOLVE);
-}
-
-static bool
-intel_miptree_slice_resolve(struct intel_context *intel,
-                           struct intel_mipmap_tree *mt,
-                           uint32_t level,
-                           uint32_t layer,
-                           enum gen6_hiz_op need)
-{
-   intel_miptree_check_level_layer(mt, level, layer);
-
-   struct intel_resolve_map *item =
-        intel_resolve_map_get(&mt->hiz_map, level, layer);
-
-   if (!item || item->need != need)
-      return false;
-
-   intel_hiz_exec(intel, mt, level, layer, need);
-   intel_resolve_map_remove(item);
-   return true;
-}
-
-bool
-intel_miptree_slice_resolve_hiz(struct intel_context *intel,
-                               struct intel_mipmap_tree *mt,
-                               uint32_t level,
-                               uint32_t layer)
-{
-   return intel_miptree_slice_resolve(intel, mt, level, layer,
-                                     GEN6_HIZ_OP_HIZ_RESOLVE);
-}
-
-bool
-intel_miptree_slice_resolve_depth(struct intel_context *intel,
-                                 struct intel_mipmap_tree *mt,
-                                 uint32_t level,
-                                 uint32_t layer)
-{
-   return intel_miptree_slice_resolve(intel, mt, level, layer,
-                                     GEN6_HIZ_OP_DEPTH_RESOLVE);
-}
-
-static bool
-intel_miptree_all_slices_resolve(struct intel_context *intel,
-                                struct intel_mipmap_tree *mt,
-                                enum gen6_hiz_op need)
-{
-   bool did_resolve = false;
-   struct intel_resolve_map *i, *next;
-
-   for (i = mt->hiz_map.next; i; i = next) {
-      next = i->next;
-      if (i->need != need)
-        continue;
-
-      intel_hiz_exec(intel, mt, i->level, i->layer, need);
-      intel_resolve_map_remove(i);
-      did_resolve = true;
-   }
-
-   return did_resolve;
-}
-
-bool
-intel_miptree_all_slices_resolve_hiz(struct intel_context *intel,
-                                    struct intel_mipmap_tree *mt)
-{
-   return intel_miptree_all_slices_resolve(intel, mt,
-                                          GEN6_HIZ_OP_HIZ_RESOLVE);
-}
-
-bool
-intel_miptree_all_slices_resolve_depth(struct intel_context *intel,
-                                      struct intel_mipmap_tree *mt)
-{
-   return intel_miptree_all_slices_resolve(intel, mt,
-                                          GEN6_HIZ_OP_DEPTH_RESOLVE);
-}
-
-
-void
-intel_miptree_resolve_color(struct intel_context *intel,
-                            struct intel_mipmap_tree *mt)
-{
-#ifdef I915
-   /* Fast color clear is not supported on the i915 (pre-Gen4) driver */
-#else
-   switch (mt->mcs_state) {
-   case INTEL_MCS_STATE_NONE:
-   case INTEL_MCS_STATE_MSAA:
-   case INTEL_MCS_STATE_RESOLVED:
-      /* No resolve needed */
-      break;
-   case INTEL_MCS_STATE_UNRESOLVED:
-   case INTEL_MCS_STATE_CLEAR:
-      brw_blorp_resolve_color(intel, mt);
-      break;
-   }
-#endif
-}
-
-
-/**
- * Make it possible to share the region backing the given miptree with another
- * process or another miptree.
- *
- * Fast color clears are unsafe with shared buffers, so we need to resolve and
- * then discard the MCS buffer, if present.  We also set the mcs_state to
- * INTEL_MCS_STATE_NONE to ensure that no MCS buffer gets allocated in the
- * future.
- */
-void
-intel_miptree_make_shareable(struct intel_context *intel,
-                             struct intel_mipmap_tree *mt)
-{
-#ifdef I915
-   /* Nothing needs to be done for I915 */
-   (void) intel;
-   (void) mt;
-#else
-   /* MCS buffers are also used for multisample buffers, but we can't resolve
-    * away a multisample MCS buffer because it's an integral part of how the
-    * pixel data is stored.  Fortunately this code path should never be
-    * reached for multisample buffers.
-    */
-   assert(mt->msaa_layout == INTEL_MSAA_LAYOUT_NONE);
-
-   if (mt->mcs_mt) {
-      intel_miptree_resolve_color(intel, mt);
-      intel_miptree_release(&mt->mcs_mt);
-      mt->mcs_state = INTEL_MCS_STATE_NONE;
-   }
-#endif
-}
-
-
-/**
- * \brief Get pointer offset into stencil buffer.
- *
- * The stencil buffer is W tiled. Since the GTT is incapable of W fencing, we
- * must decode the tile's layout in software.
- *
- * See
- *   - PRM, 2011 Sandy Bridge, Volume 1, Part 2, Section 4.5.2.1 W-Major Tile
- *     Format.
- *   - PRM, 2011 Sandy Bridge, Volume 1, Part 2, Section 4.5.3 Tiling Algorithm
- *
- * Even though the returned offset is always positive, the return type is
- * signed due to
- *    commit e8b1c6d6f55f5be3bef25084fdd8b6127517e137
- *    mesa: Fix return type of  _mesa_get_format_bytes() (#37351)
- */
-static intptr_t
-intel_offset_S8(uint32_t stride, uint32_t x, uint32_t y, bool swizzled)
-{
-   uint32_t tile_size = 4096;
-   uint32_t tile_width = 64;
-   uint32_t tile_height = 64;
-   uint32_t row_size = 64 * stride;
-
-   uint32_t tile_x = x / tile_width;
-   uint32_t tile_y = y / tile_height;
-
-   /* The byte's address relative to the tile's base addres. */
-   uint32_t byte_x = x % tile_width;
-   uint32_t byte_y = y % tile_height;
-
-   uintptr_t u = tile_y * row_size
-               + tile_x * tile_size
-               + 512 * (byte_x / 8)
-               +  64 * (byte_y / 8)
-               +  32 * ((byte_y / 4) % 2)
-               +  16 * ((byte_x / 4) % 2)
-               +   8 * ((byte_y / 2) % 2)
-               +   4 * ((byte_x / 2) % 2)
-               +   2 * (byte_y % 2)
-               +   1 * (byte_x % 2);
-
-   if (swizzled) {
-      /* adjust for bit6 swizzling */
-      if (((byte_x / 8) % 2) == 1) {
-        if (((byte_y / 8) % 2) == 0) {
-           u += 64;
-        } else {
-           u -= 64;
-        }
-      }
-   }
-
-   return u;
-}
-
-static void
-intel_miptree_updownsample(struct intel_context *intel,
-                           struct intel_mipmap_tree *src,
-                           struct intel_mipmap_tree *dst,
-                           unsigned width,
-                           unsigned height)
-{
-#ifndef I915
-   int src_x0 = 0;
-   int src_y0 = 0;
-   int dst_x0 = 0;
-   int dst_y0 = 0;
-
-   brw_blorp_blit_miptrees(intel,
-                           src, 0 /* level */, 0 /* layer */,
-                           dst, 0 /* level */, 0 /* layer */,
-                           src_x0, src_y0,
-                           width, height,
-                           dst_x0, dst_y0,
-                           width, height,
-                           false, false /*mirror x, y*/);
-
-   if (src->stencil_mt) {
-      brw_blorp_blit_miptrees(intel,
-                              src->stencil_mt, 0 /* level */, 0 /* layer */,
-                              dst->stencil_mt, 0 /* level */, 0 /* layer */,
-                              src_x0, src_y0,
-                              width, height,
-                              dst_x0, dst_y0,
-                              width, height,
-                              false, false /*mirror x, y*/);
-   }
-#endif /* I915 */
-}
-
-static void
-assert_is_flat(struct intel_mipmap_tree *mt)
-{
-   assert(mt->target == GL_TEXTURE_2D);
-   assert(mt->first_level == 0);
-   assert(mt->last_level == 0);
-}
-
-/**
- * \brief Downsample from mt to mt->singlesample_mt.
- *
- * If the miptree needs no downsample, then skip.
- */
-void
-intel_miptree_downsample(struct intel_context *intel,
-                         struct intel_mipmap_tree *mt)
-{
-   /* Only flat, renderbuffer-like miptrees are supported. */
-   assert_is_flat(mt);
-
-   if (!mt->need_downsample)
-      return;
-   intel_miptree_updownsample(intel,
-                              mt, mt->singlesample_mt,
-                              mt->logical_width0,
-                              mt->logical_height0);
-   mt->need_downsample = false;
-}
-
-/**
- * \brief Upsample from mt->singlesample_mt to mt.
- *
- * The upsample is done unconditionally.
- */
-void
-intel_miptree_upsample(struct intel_context *intel,
-                       struct intel_mipmap_tree *mt)
-{
-   /* Only flat, renderbuffer-like miptrees are supported. */
-   assert_is_flat(mt);
-   assert(!mt->need_downsample);
-
-   intel_miptree_updownsample(intel,
-                              mt->singlesample_mt, mt,
-                              mt->logical_width0,
-                              mt->logical_height0);
-}
-
-void *
-intel_miptree_map_raw(struct intel_context *intel, struct intel_mipmap_tree *mt)
-{
-   /* CPU accesses to color buffers don't understand fast color clears, so
-    * resolve any pending fast color clears before we map.
-    */
-   intel_miptree_resolve_color(intel, mt);
-
-   drm_intel_bo *bo = mt->region->bo;
-
-   if (unlikely(INTEL_DEBUG & DEBUG_PERF)) {
-      if (drm_intel_bo_busy(bo)) {
-         perf_debug("Mapping a busy BO, causing a stall on the GPU.\n");
-      }
-   }
-
-   intel_flush(&intel->ctx);
-
-   if (mt->region->tiling != I915_TILING_NONE)
-      drm_intel_gem_bo_map_gtt(bo);
-   else
-      drm_intel_bo_map(bo, true);
-
-   return bo->virtual;
-}
-
-void
-intel_miptree_unmap_raw(struct intel_context *intel,
-                        struct intel_mipmap_tree *mt)
-{
-   drm_intel_bo_unmap(mt->region->bo);
-}
-
-static void
-intel_miptree_map_gtt(struct intel_context *intel,
-                     struct intel_mipmap_tree *mt,
-                     struct intel_miptree_map *map,
-                     unsigned int level, unsigned int slice)
-{
-   unsigned int bw, bh;
-   void *base;
-   unsigned int image_x, image_y;
-   int x = map->x;
-   int y = map->y;
-
-   /* For compressed formats, the stride is the number of bytes per
-    * row of blocks.  intel_miptree_get_image_offset() already does
-    * the divide.
-    */
-   _mesa_get_format_block_size(mt->format, &bw, &bh);
-   assert(y % bh == 0);
-   y /= bh;
-
-   base = intel_miptree_map_raw(intel, mt) + mt->offset;
-
-   if (base == NULL)
-      map->ptr = NULL;
-   else {
-      /* Note that in the case of cube maps, the caller must have passed the
-       * slice number referencing the face.
-      */
-      intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y);
-      x += image_x;
-      y += image_y;
-
-      map->stride = mt->region->pitch;
-      map->ptr = base + y * map->stride + x * mt->cpp;
-   }
-
-   DBG("%s: %d,%d %dx%d from mt %p (%s) %d,%d = %p/%d\n", __FUNCTION__,
-       map->x, map->y, map->w, map->h,
-       mt, _mesa_get_format_name(mt->format),
-       x, y, map->ptr, map->stride);
-}
-
-static void
-intel_miptree_unmap_gtt(struct intel_context *intel,
-                       struct intel_mipmap_tree *mt,
-                       struct intel_miptree_map *map,
-                       unsigned int level,
-                       unsigned int slice)
-{
-   intel_miptree_unmap_raw(intel, mt);
-}
-
-static void
-intel_miptree_map_blit(struct intel_context *intel,
-                      struct intel_mipmap_tree *mt,
-                      struct intel_miptree_map *map,
-                      unsigned int level, unsigned int slice)
-{
-   map->mt = intel_miptree_create(intel, GL_TEXTURE_2D, mt->format,
-                                  0, 0,
-                                  map->w, map->h, 1,
-                                  false, 0,
-                                  INTEL_MIPTREE_TILING_NONE);
-   if (!map->mt) {
-      fprintf(stderr, "Failed to allocate blit temporary\n");
-      goto fail;
-   }
-   map->stride = map->mt->region->pitch;
-
-   if (!intel_miptree_blit(intel,
-                           mt, level, slice,
-                           map->x, map->y, false,
-                           map->mt, 0, 0,
-                           0, 0, false,
-                           map->w, map->h, GL_COPY)) {
-      fprintf(stderr, "Failed to blit\n");
-      goto fail;
-   }
-
-   intel_batchbuffer_flush(intel);
-   map->ptr = intel_miptree_map_raw(intel, map->mt);
-
-   DBG("%s: %d,%d %dx%d from mt %p (%s) %d,%d = %p/%d\n", __FUNCTION__,
-       map->x, map->y, map->w, map->h,
-       mt, _mesa_get_format_name(mt->format),
-       level, slice, map->ptr, map->stride);
-
-   return;
-
-fail:
-   intel_miptree_release(&map->mt);
-   map->ptr = NULL;
-   map->stride = 0;
-}
-
-static void
-intel_miptree_unmap_blit(struct intel_context *intel,
-                        struct intel_mipmap_tree *mt,
-                        struct intel_miptree_map *map,
-                        unsigned int level,
-                        unsigned int slice)
-{
-   struct gl_context *ctx = &intel->ctx;
-
-   intel_miptree_unmap_raw(intel, map->mt);
-
-   if (map->mode & GL_MAP_WRITE_BIT) {
-      bool ok = intel_miptree_blit(intel,
-                                   map->mt, 0, 0,
-                                   0, 0, false,
-                                   mt, level, slice,
-                                   map->x, map->y, false,
-                                   map->w, map->h, GL_COPY);
-      WARN_ONCE(!ok, "Failed to blit from linear temporary mapping");
-   }
-
-   intel_miptree_release(&map->mt);
-}
-
-static void
-intel_miptree_map_s8(struct intel_context *intel,
-                    struct intel_mipmap_tree *mt,
-                    struct intel_miptree_map *map,
-                    unsigned int level, unsigned int slice)
-{
-   map->stride = map->w;
-   map->buffer = map->ptr = malloc(map->stride * map->h);
-   if (!map->buffer)
-      return;
-
-   /* One of either READ_BIT or WRITE_BIT or both is set.  READ_BIT implies no
-    * INVALIDATE_RANGE_BIT.  WRITE_BIT needs the original values read in unless
-    * invalidate is set, since we'll be writing the whole rectangle from our
-    * temporary buffer back out.
-    */
-   if (!(map->mode & GL_MAP_INVALIDATE_RANGE_BIT)) {
-      uint8_t *untiled_s8_map = map->ptr;
-      uint8_t *tiled_s8_map = intel_miptree_map_raw(intel, mt);
-      unsigned int image_x, image_y;
-
-      intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y);
-
-      for (uint32_t y = 0; y < map->h; y++) {
-        for (uint32_t x = 0; x < map->w; x++) {
-           ptrdiff_t offset = intel_offset_S8(mt->region->pitch,
-                                              x + image_x + map->x,
-                                              y + image_y + map->y,
-                                              intel->has_swizzling);
-           untiled_s8_map[y * map->w + x] = tiled_s8_map[offset];
-        }
-      }
-
-      intel_miptree_unmap_raw(intel, mt);
-
-      DBG("%s: %d,%d %dx%d from mt %p %d,%d = %p/%d\n", __FUNCTION__,
-         map->x, map->y, map->w, map->h,
-         mt, map->x + image_x, map->y + image_y, map->ptr, map->stride);
-   } else {
-      DBG("%s: %d,%d %dx%d from mt %p = %p/%d\n", __FUNCTION__,
-         map->x, map->y, map->w, map->h,
-         mt, map->ptr, map->stride);
-   }
-}
-
-static void
-intel_miptree_unmap_s8(struct intel_context *intel,
-                      struct intel_mipmap_tree *mt,
-                      struct intel_miptree_map *map,
-                      unsigned int level,
-                      unsigned int slice)
-{
-   if (map->mode & GL_MAP_WRITE_BIT) {
-      unsigned int image_x, image_y;
-      uint8_t *untiled_s8_map = map->ptr;
-      uint8_t *tiled_s8_map = intel_miptree_map_raw(intel, mt);
-
-      intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y);
-
-      for (uint32_t y = 0; y < map->h; y++) {
-        for (uint32_t x = 0; x < map->w; x++) {
-           ptrdiff_t offset = intel_offset_S8(mt->region->pitch,
-                                              x + map->x,
-                                              y + map->y,
-                                              intel->has_swizzling);
-           tiled_s8_map[offset] = untiled_s8_map[y * map->w + x];
-        }
-      }
-
-      intel_miptree_unmap_raw(intel, mt);
-   }
-
-   free(map->buffer);
-}
-
-static void
-intel_miptree_map_etc(struct intel_context *intel,
-                      struct intel_mipmap_tree *mt,
-                      struct intel_miptree_map *map,
-                      unsigned int level,
-                      unsigned int slice)
-{
-   assert(mt->etc_format != MESA_FORMAT_NONE);
-   if (mt->etc_format == MESA_FORMAT_ETC1_RGB8) {
-      assert(mt->format == MESA_FORMAT_RGBX8888_REV);
-   }
-
-   assert(map->mode & GL_MAP_WRITE_BIT);
-   assert(map->mode & GL_MAP_INVALIDATE_RANGE_BIT);
-
-   map->stride = _mesa_format_row_stride(mt->etc_format, map->w);
-   map->buffer = malloc(_mesa_format_image_size(mt->etc_format,
-                                                map->w, map->h, 1));
-   map->ptr = map->buffer;
-}
-
-static void
-intel_miptree_unmap_etc(struct intel_context *intel,
-                        struct intel_mipmap_tree *mt,
-                        struct intel_miptree_map *map,
-                        unsigned int level,
-                        unsigned int slice)
-{
-   uint32_t image_x;
-   uint32_t image_y;
-   intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y);
-
-   image_x += map->x;
-   image_y += map->y;
-
-   uint8_t *dst = intel_miptree_map_raw(intel, mt)
-                + image_y * mt->region->pitch
-                + image_x * mt->region->cpp;
-
-   if (mt->etc_format == MESA_FORMAT_ETC1_RGB8)
-      _mesa_etc1_unpack_rgba8888(dst, mt->region->pitch,
-                                 map->ptr, map->stride,
-                                 map->w, map->h);
-   else
-      _mesa_unpack_etc2_format(dst, mt->region->pitch,
-                               map->ptr, map->stride,
-                               map->w, map->h, mt->etc_format);
-
-   intel_miptree_unmap_raw(intel, mt);
-   free(map->buffer);
-}
-
-/**
- * Mapping function for packed depth/stencil miptrees backed by real separate
- * miptrees for depth and stencil.
- *
- * On gen7, and to support HiZ pre-gen7, we have to have the stencil buffer
- * separate from the depth buffer.  Yet at the GL API level, we have to expose
- * packed depth/stencil textures and FBO attachments, and Mesa core expects to
- * be able to map that memory for texture storage and glReadPixels-type
- * operations.  We give Mesa core that access by mallocing a temporary and
- * copying the data between the actual backing store and the temporary.
- */
-static void
-intel_miptree_map_depthstencil(struct intel_context *intel,
-                              struct intel_mipmap_tree *mt,
-                              struct intel_miptree_map *map,
-                              unsigned int level, unsigned int slice)
-{
-   struct intel_mipmap_tree *z_mt = mt;
-   struct intel_mipmap_tree *s_mt = mt->stencil_mt;
-   bool map_z32f_x24s8 = mt->format == MESA_FORMAT_Z32_FLOAT;
-   int packed_bpp = map_z32f_x24s8 ? 8 : 4;
-
-   map->stride = map->w * packed_bpp;
-   map->buffer = map->ptr = malloc(map->stride * map->h);
-   if (!map->buffer)
-      return;
-
-   /* One of either READ_BIT or WRITE_BIT or both is set.  READ_BIT implies no
-    * INVALIDATE_RANGE_BIT.  WRITE_BIT needs the original values read in unless
-    * invalidate is set, since we'll be writing the whole rectangle from our
-    * temporary buffer back out.
-    */
-   if (!(map->mode & GL_MAP_INVALIDATE_RANGE_BIT)) {
-      uint32_t *packed_map = map->ptr;
-      uint8_t *s_map = intel_miptree_map_raw(intel, s_mt);
-      uint32_t *z_map = intel_miptree_map_raw(intel, z_mt);
-      unsigned int s_image_x, s_image_y;
-      unsigned int z_image_x, z_image_y;
-
-      intel_miptree_get_image_offset(s_mt, level, slice,
-                                    &s_image_x, &s_image_y);
-      intel_miptree_get_image_offset(z_mt, level, slice,
-                                    &z_image_x, &z_image_y);
-
-      for (uint32_t y = 0; y < map->h; y++) {
-        for (uint32_t x = 0; x < map->w; x++) {
-           int map_x = map->x + x, map_y = map->y + y;
-           ptrdiff_t s_offset = intel_offset_S8(s_mt->region->pitch,
-                                                map_x + s_image_x,
-                                                map_y + s_image_y,
-                                                intel->has_swizzling);
-           ptrdiff_t z_offset = ((map_y + z_image_y) *
-                                  (z_mt->region->pitch / 4) +
-                                 (map_x + z_image_x));
-           uint8_t s = s_map[s_offset];
-           uint32_t z = z_map[z_offset];
-
-           if (map_z32f_x24s8) {
-              packed_map[(y * map->w + x) * 2 + 0] = z;
-              packed_map[(y * map->w + x) * 2 + 1] = s;
-           } else {
-              packed_map[y * map->w + x] = (s << 24) | (z & 0x00ffffff);
-           }
-        }
-      }
-
-      intel_miptree_unmap_raw(intel, s_mt);
-      intel_miptree_unmap_raw(intel, z_mt);
-
-      DBG("%s: %d,%d %dx%d from z mt %p %d,%d, s mt %p %d,%d = %p/%d\n",
-         __FUNCTION__,
-         map->x, map->y, map->w, map->h,
-         z_mt, map->x + z_image_x, map->y + z_image_y,
-         s_mt, map->x + s_image_x, map->y + s_image_y,
-         map->ptr, map->stride);
-   } else {
-      DBG("%s: %d,%d %dx%d from mt %p = %p/%d\n", __FUNCTION__,
-         map->x, map->y, map->w, map->h,
-         mt, map->ptr, map->stride);
-   }
-}
-
-static void
-intel_miptree_unmap_depthstencil(struct intel_context *intel,
-                                struct intel_mipmap_tree *mt,
-                                struct intel_miptree_map *map,
-                                unsigned int level,
-                                unsigned int slice)
-{
-   struct intel_mipmap_tree *z_mt = mt;
-   struct intel_mipmap_tree *s_mt = mt->stencil_mt;
-   bool map_z32f_x24s8 = mt->format == MESA_FORMAT_Z32_FLOAT;
-
-   if (map->mode & GL_MAP_WRITE_BIT) {
-      uint32_t *packed_map = map->ptr;
-      uint8_t *s_map = intel_miptree_map_raw(intel, s_mt);
-      uint32_t *z_map = intel_miptree_map_raw(intel, z_mt);
-      unsigned int s_image_x, s_image_y;
-      unsigned int z_image_x, z_image_y;
-
-      intel_miptree_get_image_offset(s_mt, level, slice,
-                                    &s_image_x, &s_image_y);
-      intel_miptree_get_image_offset(z_mt, level, slice,
-                                    &z_image_x, &z_image_y);
-
-      for (uint32_t y = 0; y < map->h; y++) {
-        for (uint32_t x = 0; x < map->w; x++) {
-           ptrdiff_t s_offset = intel_offset_S8(s_mt->region->pitch,
-                                                x + s_image_x + map->x,
-                                                y + s_image_y + map->y,
-                                                intel->has_swizzling);
-           ptrdiff_t z_offset = ((y + z_image_y) *
-                                  (z_mt->region->pitch / 4) +
-                                 (x + z_image_x));
-
-           if (map_z32f_x24s8) {
-              z_map[z_offset] = packed_map[(y * map->w + x) * 2 + 0];
-              s_map[s_offset] = packed_map[(y * map->w + x) * 2 + 1];
-           } else {
-              uint32_t packed = packed_map[y * map->w + x];
-              s_map[s_offset] = packed >> 24;
-              z_map[z_offset] = packed;
-           }
-        }
-      }
-
-      intel_miptree_unmap_raw(intel, s_mt);
-      intel_miptree_unmap_raw(intel, z_mt);
-
-      DBG("%s: %d,%d %dx%d from z mt %p (%s) %d,%d, s mt %p %d,%d = %p/%d\n",
-         __FUNCTION__,
-         map->x, map->y, map->w, map->h,
-         z_mt, _mesa_get_format_name(z_mt->format),
-         map->x + z_image_x, map->y + z_image_y,
-         s_mt, map->x + s_image_x, map->y + s_image_y,
-         map->ptr, map->stride);
-   }
-
-   free(map->buffer);
-}
-
-/**
- * Create and attach a map to the miptree at (level, slice). Return the
- * attached map.
- */
-static struct intel_miptree_map*
-intel_miptree_attach_map(struct intel_mipmap_tree *mt,
-                         unsigned int level,
-                         unsigned int slice,
-                         unsigned int x,
-                         unsigned int y,
-                         unsigned int w,
-                         unsigned int h,
-                         GLbitfield mode)
-{
-   struct intel_miptree_map *map = calloc(1, sizeof(*map));
-
-   if (!map)
-      return NULL;
-
-   assert(mt->level[level].slice[slice].map == NULL);
-   mt->level[level].slice[slice].map = map;
-
-   map->mode = mode;
-   map->x = x;
-   map->y = y;
-   map->w = w;
-   map->h = h;
-
-   return map;
-}
-
-/**
- * Release the map at (level, slice).
- */
-static void
-intel_miptree_release_map(struct intel_mipmap_tree *mt,
-                         unsigned int level,
-                         unsigned int slice)
-{
-   struct intel_miptree_map **map;
-
-   map = &mt->level[level].slice[slice].map;
-   free(*map);
-   *map = NULL;
-}
-
-static void
-intel_miptree_map_singlesample(struct intel_context *intel,
-                               struct intel_mipmap_tree *mt,
-                               unsigned int level,
-                               unsigned int slice,
-                               unsigned int x,
-                               unsigned int y,
-                               unsigned int w,
-                               unsigned int h,
-                               GLbitfield mode,
-                               void **out_ptr,
-                               int *out_stride)
-{
-   struct intel_miptree_map *map;
-
-   assert(mt->num_samples <= 1);
-
-   map = intel_miptree_attach_map(mt, level, slice, x, y, w, h, mode);
-   if (!map){
-      *out_ptr = NULL;
-      *out_stride = 0;
-      return;
-   }
-
-   intel_miptree_slice_resolve_depth(intel, mt, level, slice);
-   if (map->mode & GL_MAP_WRITE_BIT) {
-      intel_miptree_slice_set_needs_hiz_resolve(mt, level, slice);
-   }
-
-   if (mt->format == MESA_FORMAT_S8) {
-      intel_miptree_map_s8(intel, mt, map, level, slice);
-   } else if (mt->etc_format != MESA_FORMAT_NONE &&
-              !(mode & BRW_MAP_DIRECT_BIT)) {
-      intel_miptree_map_etc(intel, mt, map, level, slice);
-   } else if (mt->stencil_mt && !(mode & BRW_MAP_DIRECT_BIT)) {
-      intel_miptree_map_depthstencil(intel, mt, map, level, slice);
-   }
-   /* See intel_miptree_blit() for details on the 32k pitch limit. */
-   else if (intel->has_llc &&
-            !(mode & GL_MAP_WRITE_BIT) &&
-            !mt->compressed &&
-            (mt->region->tiling == I915_TILING_X ||
-             (intel->gen >= 6 && mt->region->tiling == I915_TILING_Y)) &&
-            mt->region->pitch < 32768) {
-      intel_miptree_map_blit(intel, mt, map, level, slice);
-   } else if (mt->region->tiling != I915_TILING_NONE &&
-              mt->region->bo->size >= intel->max_gtt_map_object_size) {
-      assert(mt->region->pitch < 32768);
-      intel_miptree_map_blit(intel, mt, map, level, slice);
-   } else {
-      intel_miptree_map_gtt(intel, mt, map, level, slice);
-   }
-
-   *out_ptr = map->ptr;
-   *out_stride = map->stride;
-
-   if (map->ptr == NULL)
-      intel_miptree_release_map(mt, level, slice);
-}
-
-static void
-intel_miptree_unmap_singlesample(struct intel_context *intel,
-                                 struct intel_mipmap_tree *mt,
-                                 unsigned int level,
-                                 unsigned int slice)
-{
-   struct intel_miptree_map *map = mt->level[level].slice[slice].map;
-
-   assert(mt->num_samples <= 1);
-
-   if (!map)
-      return;
-
-   DBG("%s: mt %p (%s) level %d slice %d\n", __FUNCTION__,
-       mt, _mesa_get_format_name(mt->format), level, slice);
-
-   if (mt->format == MESA_FORMAT_S8) {
-      intel_miptree_unmap_s8(intel, mt, map, level, slice);
-   } else if (mt->etc_format != MESA_FORMAT_NONE &&
-              !(map->mode & BRW_MAP_DIRECT_BIT)) {
-      intel_miptree_unmap_etc(intel, mt, map, level, slice);
-   } else if (mt->stencil_mt && !(map->mode & BRW_MAP_DIRECT_BIT)) {
-      intel_miptree_unmap_depthstencil(intel, mt, map, level, slice);
-   } else if (map->mt) {
-      intel_miptree_unmap_blit(intel, mt, map, level, slice);
-   } else {
-      intel_miptree_unmap_gtt(intel, mt, map, level, slice);
-   }
-
-   intel_miptree_release_map(mt, level, slice);
-}
-
-static void
-intel_miptree_map_multisample(struct intel_context *intel,
-                              struct intel_mipmap_tree *mt,
-                              unsigned int level,
-                              unsigned int slice,
-                              unsigned int x,
-                              unsigned int y,
-                              unsigned int w,
-                              unsigned int h,
-                              GLbitfield mode,
-                              void **out_ptr,
-                              int *out_stride)
-{
-   struct intel_miptree_map *map;
-
-   assert(mt->num_samples > 1);
-
-   /* Only flat, renderbuffer-like miptrees are supported. */
-   if (mt->target != GL_TEXTURE_2D ||
-       mt->first_level != 0 ||
-       mt->last_level != 0) {
-      _mesa_problem(&intel->ctx, "attempt to map a multisample miptree for "
-                    "which (target, first_level, last_level != "
-                    "(GL_TEXTURE_2D, 0, 0)");
-      goto fail;
-   }
-
-   map = intel_miptree_attach_map(mt, level, slice, x, y, w, h, mode);
-   if (!map)
-      goto fail;
-
-   if (!mt->singlesample_mt) {
-      mt->singlesample_mt =
-         intel_miptree_create_for_renderbuffer(intel,
-                                               mt->format,
-                                               mt->logical_width0,
-                                               mt->logical_height0,
-                                               0 /*num_samples*/);
-      if (!mt->singlesample_mt)
-         goto fail;
-
-      map->singlesample_mt_is_tmp = true;
-      mt->need_downsample = true;
-   }
-
-   intel_miptree_downsample(intel, mt);
-   intel_miptree_map_singlesample(intel, mt->singlesample_mt,
-                                  level, slice,
-                                  x, y, w, h,
-                                  mode,
-                                  out_ptr, out_stride);
-   return;
-
-fail:
-   intel_miptree_release_map(mt, level, slice);
-   *out_ptr = NULL;
-   *out_stride = 0;
-}
-
-static void
-intel_miptree_unmap_multisample(struct intel_context *intel,
-                                struct intel_mipmap_tree *mt,
-                                unsigned int level,
-                                unsigned int slice)
-{
-   struct intel_miptree_map *map = mt->level[level].slice[slice].map;
-
-   assert(mt->num_samples > 1);
-
-   if (!map)
-      return;
-
-   intel_miptree_unmap_singlesample(intel, mt->singlesample_mt, level, slice);
-
-   mt->need_downsample = false;
-   if (map->mode & GL_MAP_WRITE_BIT)
-      intel_miptree_upsample(intel, mt);
-
-   if (map->singlesample_mt_is_tmp)
-      intel_miptree_release(&mt->singlesample_mt);
-
-   intel_miptree_release_map(mt, level, slice);
-}
-
-void
-intel_miptree_map(struct intel_context *intel,
-                 struct intel_mipmap_tree *mt,
-                 unsigned int level,
-                 unsigned int slice,
-                 unsigned int x,
-                 unsigned int y,
-                 unsigned int w,
-                 unsigned int h,
-                 GLbitfield mode,
-                 void **out_ptr,
-                 int *out_stride)
-{
-   if (mt->num_samples <= 1)
-      intel_miptree_map_singlesample(intel, mt,
-                                     level, slice,
-                                     x, y, w, h,
-                                     mode,
-                                     out_ptr, out_stride);
-   else
-      intel_miptree_map_multisample(intel, mt,
-                                    level, slice,
-                                    x, y, w, h,
-                                    mode,
-                                    out_ptr, out_stride);
-}
-
-void
-intel_miptree_unmap(struct intel_context *intel,
-                   struct intel_mipmap_tree *mt,
-                   unsigned int level,
-                   unsigned int slice)
-{
-   if (mt->num_samples <= 1)
-      intel_miptree_unmap_singlesample(intel, mt, level, slice);
-   else
-      intel_miptree_unmap_multisample(intel, mt, level, slice);
-}
diff --git a/src/mesa/drivers/dri/intel/intel_pixel.c b/src/mesa/drivers/dri/intel/intel_pixel.c
deleted file mode 100644 (file)
index f58cb85..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portionsalloc
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-#include "main/accum.h"
-#include "main/enums.h"
-#include "main/state.h"
-#include "main/bufferobj.h"
-#include "main/context.h"
-#include "swrast/swrast.h"
-
-#include "intel_context.h"
-#include "intel_pixel.h"
-#include "intel_regions.h"
-
-#define FILE_DEBUG_FLAG DEBUG_PIXEL
-
-static GLenum
-effective_func(GLenum func, bool src_alpha_is_one)
-{
-   if (src_alpha_is_one) {
-      if (func == GL_SRC_ALPHA)
-        return GL_ONE;
-      if (func == GL_ONE_MINUS_SRC_ALPHA)
-        return GL_ZERO;
-   }
-
-   return func;
-}
-
-/**
- * Check if any fragment operations are in effect which might effect
- * glDraw/CopyPixels.
- */
-bool
-intel_check_blit_fragment_ops(struct gl_context * ctx, bool src_alpha_is_one)
-{
-   if (ctx->NewState)
-      _mesa_update_state(ctx);
-
-   if (ctx->FragmentProgram._Enabled) {
-      DBG("fallback due to fragment program\n");
-      return false;
-   }
-
-   if (ctx->Color.BlendEnabled &&
-       (effective_func(ctx->Color.Blend[0].SrcRGB, src_alpha_is_one) != GL_ONE ||
-       effective_func(ctx->Color.Blend[0].DstRGB, src_alpha_is_one) != GL_ZERO ||
-       ctx->Color.Blend[0].EquationRGB != GL_FUNC_ADD ||
-       effective_func(ctx->Color.Blend[0].SrcA, src_alpha_is_one) != GL_ONE ||
-       effective_func(ctx->Color.Blend[0].DstA, src_alpha_is_one) != GL_ZERO ||
-       ctx->Color.Blend[0].EquationA != GL_FUNC_ADD)) {
-      DBG("fallback due to blend\n");
-      return false;
-   }
-
-   if (ctx->Texture._EnabledUnits) {
-      DBG("fallback due to texturing\n");
-      return false;
-   }
-
-   if (!(ctx->Color.ColorMask[0][0] &&
-        ctx->Color.ColorMask[0][1] &&
-        ctx->Color.ColorMask[0][2] &&
-        ctx->Color.ColorMask[0][3])) {
-      DBG("fallback due to color masking\n");
-      return false;
-   }
-
-   if (ctx->Color.AlphaEnabled) {
-      DBG("fallback due to alpha\n");
-      return false;
-   }
-
-   if (ctx->Depth.Test) {
-      DBG("fallback due to depth test\n");
-      return false;
-   }
-
-   if (ctx->Fog.Enabled) {
-      DBG("fallback due to fog\n");
-      return false;
-   }
-
-   if (ctx->_ImageTransferState) {
-      DBG("fallback due to image transfer\n");
-      return false;
-   }
-
-   if (ctx->Stencil._Enabled) {
-      DBG("fallback due to image stencil\n");
-      return false;
-   }
-
-   if (ctx->RenderMode != GL_RENDER) {
-      DBG("fallback due to render mode\n");
-      return false;
-   }
-
-   return true;
-}
-
-void
-intelInitPixelFuncs(struct dd_function_table *functions)
-{
-   functions->Accum = _mesa_accum;
-   functions->Bitmap = intelBitmap;
-   functions->CopyPixels = intelCopyPixels;
-   functions->DrawPixels = intelDrawPixels;
-   functions->ReadPixels = intelReadPixels;
-}
-
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
deleted file mode 100644 (file)
index 8c0edf2..0000000
+++ /dev/null
@@ -1,363 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portionsalloc
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-#include "main/glheader.h"
-#include "main/enums.h"
-#include "main/image.h"
-#include "main/colormac.h"
-#include "main/condrender.h"
-#include "main/mtypes.h"
-#include "main/macros.h"
-#include "main/pbo.h"
-#include "main/bufferobj.h"
-#include "main/state.h"
-#include "main/texobj.h"
-#include "main/context.h"
-#include "main/fbobject.h"
-#include "swrast/swrast.h"
-#include "drivers/common/meta.h"
-
-#include "intel_screen.h"
-#include "intel_context.h"
-#include "intel_batchbuffer.h"
-#include "intel_blit.h"
-#include "intel_fbo.h"
-#include "intel_regions.h"
-#include "intel_buffers.h"
-#include "intel_pixel.h"
-#include "intel_reg.h"
-
-
-#define FILE_DEBUG_FLAG DEBUG_PIXEL
-
-
-/* Unlike the other intel_pixel_* functions, the expectation here is
- * that the incoming data is not in a PBO.  With the XY_TEXT blit
- * method, there's no benefit haveing it in a PBO, but we could
- * implement a path based on XY_MONO_SRC_COPY_BLIT which might benefit
- * PBO bitmaps.  I think they are probably pretty rare though - I
- * wonder if Xgl uses them?
- */
-static const GLubyte *map_pbo( struct gl_context *ctx,
-                              GLsizei width, GLsizei height,
-                              const struct gl_pixelstore_attrib *unpack,
-                              const GLubyte *bitmap )
-{
-   GLubyte *buf;
-
-   if (!_mesa_validate_pbo_access(2, unpack, width, height, 1,
-                                 GL_COLOR_INDEX, GL_BITMAP,
-                                 INT_MAX, (const GLvoid *) bitmap)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,"glBitmap(invalid PBO access)");
-      return NULL;
-   }
-
-   buf = (GLubyte *) ctx->Driver.MapBufferRange(ctx, 0, unpack->BufferObj->Size,
-                                               GL_MAP_READ_BIT,
-                                               unpack->BufferObj);
-   if (!buf) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)");
-      return NULL;
-   }
-
-   return ADD_POINTERS(buf, bitmap);
-}
-
-static bool test_bit( const GLubyte *src, GLuint bit )
-{
-   return (src[bit/8] & (1<<(bit % 8))) ? 1 : 0;
-}
-
-static void set_bit( GLubyte *dest, GLuint bit )
-{
-   dest[bit/8] |= 1 << (bit % 8);
-}
-
-/* Extract a rectangle's worth of data from the bitmap.  Called
- * per chunk of HW-sized bitmap.
- */
-static GLuint get_bitmap_rect(GLsizei width, GLsizei height,
-                             const struct gl_pixelstore_attrib *unpack,
-                             const GLubyte *bitmap,
-                             GLuint x, GLuint y, 
-                             GLuint w, GLuint h,
-                             GLubyte *dest,
-                             GLuint row_align,
-                             bool invert)
-{
-   GLuint src_offset = (x + unpack->SkipPixels) & 0x7;
-   GLuint mask = unpack->LsbFirst ? 0 : 7;
-   GLuint bit = 0;
-   GLint row, col;
-   GLint first, last;
-   GLint incr;
-   GLuint count = 0;
-
-   DBG("%s %d,%d %dx%d bitmap %dx%d skip %d src_offset %d mask %d\n",
-       __FUNCTION__, x,y,w,h,width,height,unpack->SkipPixels, src_offset, mask);
-
-   if (invert) {
-      first = h-1;
-      last = 0;
-      incr = -1;
-   }
-   else {
-      first = 0;
-      last = h-1;
-      incr = 1;
-   }
-
-   /* Require that dest be pre-zero'd.
-    */
-   for (row = first; row != (last+incr); row += incr) {
-      const GLubyte *rowsrc = _mesa_image_address2d(unpack, bitmap, 
-                                                   width, height, 
-                                                   GL_COLOR_INDEX, GL_BITMAP, 
-                                                   y + row, x);
-
-      for (col = 0; col < w; col++, bit++) {
-        if (test_bit(rowsrc, (col + src_offset) ^ mask)) {
-           set_bit(dest, bit ^ 7);
-           count++;
-        }
-      }
-
-      if (row_align)
-        bit = ALIGN(bit, row_align);
-   }
-
-   return count;
-}
-
-/**
- * Returns the low Y value of the vertical range given, flipped according to
- * whether the framebuffer is or not.
- */
-static INLINE int
-y_flip(struct gl_framebuffer *fb, int y, int height)
-{
-   if (_mesa_is_user_fbo(fb))
-      return y;
-   else
-      return fb->Height - y - height;
-}
-
-/*
- * Render a bitmap.
- */
-static bool
-do_blit_bitmap( struct gl_context *ctx, 
-               GLint dstx, GLint dsty,
-               GLsizei width, GLsizei height,
-               const struct gl_pixelstore_attrib *unpack,
-               const GLubyte *bitmap )
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct gl_framebuffer *fb = ctx->DrawBuffer;
-   struct intel_renderbuffer *irb;
-   GLfloat tmpColor[4];
-   GLubyte ubcolor[4];
-   GLuint color;
-   GLsizei bitmap_width = width;
-   GLsizei bitmap_height = height;
-   GLint px, py;
-   GLuint stipple[32];
-   GLint orig_dstx = dstx;
-   GLint orig_dsty = dsty;
-
-   /* Update draw buffer bounds */
-   _mesa_update_state(ctx);
-
-   if (ctx->Depth.Test) {
-      /* The blit path produces incorrect results when depth testing is on.
-       * It seems the blit Z coord is always 1.0 (the far plane) so fragments
-       * will likely be obscured by other, closer geometry.
-       */
-      return false;
-   }
-
-   intel_prepare_render(intel);
-
-   if (fb->_NumColorDrawBuffers != 1) {
-      perf_debug("accelerated glBitmap() only supports rendering to a "
-                 "single color buffer\n");
-      return false;
-   }
-
-   irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
-
-   if (_mesa_is_bufferobj(unpack->BufferObj)) {
-      bitmap = map_pbo(ctx, width, height, unpack, bitmap);
-      if (bitmap == NULL)
-        return true;   /* even though this is an error, we're done */
-   }
-
-   COPY_4V(tmpColor, ctx->Current.RasterColor);
-
-   if (_mesa_need_secondary_color(ctx)) {
-       ADD_3V(tmpColor, tmpColor, ctx->Current.RasterSecondaryColor);
-   }
-
-   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[0], tmpColor[0]);
-   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[1], tmpColor[1]);
-   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[2], tmpColor[2]);
-   UNCLAMPED_FLOAT_TO_UBYTE(ubcolor[3], tmpColor[3]);
-
-   switch (irb->mt->format) {
-   case MESA_FORMAT_ARGB8888:
-   case MESA_FORMAT_XRGB8888:
-      color = PACK_COLOR_8888(ubcolor[3], ubcolor[0], ubcolor[1], ubcolor[2]);
-      break;
-   case MESA_FORMAT_RGB565:
-      color = PACK_COLOR_565(ubcolor[0], ubcolor[1], ubcolor[2]);
-      break;
-   default:
-      perf_debug("Unsupported format %s in accelerated glBitmap()\n",
-                 _mesa_get_format_name(irb->mt->format));
-      return false;
-   }
-
-   if (!intel_check_blit_fragment_ops(ctx, tmpColor[3] == 1.0F))
-      return false;
-
-   /* Clip to buffer bounds and scissor. */
-   if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin,
-                            fb->_Xmax, fb->_Ymax,
-                            &dstx, &dsty, &width, &height))
-      goto out;
-
-   dsty = y_flip(fb, dsty, height);
-
-#define DY 32
-#define DX 32
-
-   /* The blitter has no idea about fast color clears, so we need to resolve
-    * the miptree before we do anything.
-    */
-   intel_miptree_resolve_color(intel, irb->mt);
-
-   /* Chop it all into chunks that can be digested by hardware: */
-   for (py = 0; py < height; py += DY) {
-      for (px = 0; px < width; px += DX) {
-        int h = MIN2(DY, height - py);
-        int w = MIN2(DX, width - px);
-        GLuint sz = ALIGN(ALIGN(w,8) * h, 64)/8;
-        GLenum logic_op = ctx->Color.ColorLogicOpEnabled ?
-           ctx->Color.LogicOp : GL_COPY;
-
-        assert(sz <= sizeof(stipple));
-        memset(stipple, 0, sz);
-
-        /* May need to adjust this when padding has been introduced in
-         * sz above:
-         *
-         * Have to translate destination coordinates back into source
-         * coordinates.
-         */
-         int count = get_bitmap_rect(bitmap_width, bitmap_height, unpack,
-                                     bitmap,
-                                     -orig_dstx + (dstx + px),
-                                     -orig_dsty + y_flip(fb, dsty + py, h),
-                                     w, h,
-                                     (GLubyte *)stipple,
-                                     8,
-                                     _mesa_is_winsys_fbo(fb));
-         if (count == 0)
-           continue;
-
-        if (!intelEmitImmediateColorExpandBlit(intel,
-                                               irb->mt->cpp,
-                                               (GLubyte *)stipple,
-                                               sz,
-                                               color,
-                                               irb->mt->region->pitch,
-                                               irb->mt->region->bo,
-                                               0,
-                                               irb->mt->region->tiling,
-                                               dstx + px,
-                                               dsty + py,
-                                               w, h,
-                                               logic_op)) {
-           return false;
-        }
-
-         if (ctx->Query.CurrentOcclusionObject)
-            ctx->Query.CurrentOcclusionObject->Result += count;
-      }
-   }
-out:
-
-   if (unlikely(INTEL_DEBUG & DEBUG_SYNC))
-      intel_batchbuffer_flush(intel);
-
-   if (_mesa_is_bufferobj(unpack->BufferObj)) {
-      /* done with PBO so unmap it now */
-      ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj);
-   }
-
-   intel_check_front_buffer_rendering(intel);
-
-   return true;
-}
-
-
-/* There are a large number of possible ways to implement bitmap on
- * this hardware, most of them have some sort of drawback.  Here are a
- * few that spring to mind:
- * 
- * Blit:
- *    - XY_MONO_SRC_BLT_CMD
- *         - use XY_SETUP_CLIP_BLT for cliprect clipping.
- *    - XY_TEXT_BLT
- *    - XY_TEXT_IMMEDIATE_BLT
- *         - blit per cliprect, subject to maximum immediate data size.
- *    - XY_COLOR_BLT 
- *         - per pixel or run of pixels
- *    - XY_PIXEL_BLT
- *         - good for sparse bitmaps
- *
- * 3D engine:
- *    - Point per pixel
- *    - Translate bitmap to an alpha texture and render as a quad
- *    - Chop bitmap up into 32x32 squares and render w/polygon stipple.
- */
-void
-intelBitmap(struct gl_context * ctx,
-           GLint x, GLint y,
-           GLsizei width, GLsizei height,
-           const struct gl_pixelstore_attrib *unpack,
-           const GLubyte * pixels)
-{
-   if (!_mesa_check_conditional_render(ctx))
-      return;
-
-   if (do_blit_bitmap(ctx, x, y, width, height,
-                          unpack, pixels))
-      return;
-
-   _mesa_meta_Bitmap(ctx, x, y, width, height, unpack, pixels);
-}
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_copy.c b/src/mesa/drivers/dri/intel/intel_pixel_copy.c
deleted file mode 100644 (file)
index ba8e06f..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-#include "main/glheader.h"
-#include "main/image.h"
-#include "main/state.h"
-#include "main/mtypes.h"
-#include "main/condrender.h"
-#include "main/fbobject.h"
-#include "drivers/common/meta.h"
-
-#include "intel_context.h"
-#include "intel_buffers.h"
-#include "intel_mipmap_tree.h"
-#include "intel_regions.h"
-#include "intel_pixel.h"
-#include "intel_fbo.h"
-#include "intel_blit.h"
-
-#define FILE_DEBUG_FLAG DEBUG_PIXEL
-
-/**
- * CopyPixels with the blitter.  Don't support zooming, pixel transfer, etc.
- */
-static bool
-do_blit_copypixels(struct gl_context * ctx,
-                   GLint srcx, GLint srcy,
-                   GLsizei width, GLsizei height,
-                   GLint dstx, GLint dsty, GLenum type)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct gl_framebuffer *fb = ctx->DrawBuffer;
-   struct gl_framebuffer *read_fb = ctx->ReadBuffer;
-   GLint orig_dstx;
-   GLint orig_dsty;
-   GLint orig_srcx;
-   GLint orig_srcy;
-   struct intel_renderbuffer *draw_irb = NULL;
-   struct intel_renderbuffer *read_irb = NULL;
-
-   /* Update draw buffer bounds */
-   _mesa_update_state(ctx);
-
-   switch (type) {
-   case GL_COLOR:
-      if (fb->_NumColorDrawBuffers != 1) {
-        perf_debug("glCopyPixels() fallback: MRT\n");
-        return false;
-      }
-
-      draw_irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
-      read_irb = intel_renderbuffer(read_fb->_ColorReadBuffer);
-      break;
-   case GL_DEPTH_STENCIL_EXT:
-      draw_irb = intel_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer);
-      read_irb =
-        intel_renderbuffer(read_fb->Attachment[BUFFER_DEPTH].Renderbuffer);
-      break;
-   case GL_DEPTH:
-      perf_debug("glCopyPixels() fallback: GL_DEPTH\n");
-      return false;
-   case GL_STENCIL:
-      perf_debug("glCopyPixels() fallback: GL_STENCIL\n");
-      return false;
-   default:
-      perf_debug("glCopyPixels(): Unknown type\n");
-      return false;
-   }
-
-   if (!draw_irb) {
-      perf_debug("glCopyPixels() fallback: missing draw buffer\n");
-      return false;
-   }
-
-   if (!read_irb) {
-      perf_debug("glCopyPixels() fallback: missing read buffer\n");
-      return false;
-   }
-
-   if (ctx->_ImageTransferState) {
-      perf_debug("glCopyPixels(): Unsupported image transfer state\n");
-      return false;
-   }
-
-   if (ctx->Depth.Test) {
-      perf_debug("glCopyPixels(): Unsupported depth test state\n");
-      return false;
-   }
-
-   if (ctx->Stencil._Enabled) {
-      perf_debug("glCopyPixels(): Unsupported stencil test state\n");
-      return false;
-   }
-
-   if (ctx->Fog.Enabled ||
-       ctx->Texture._EnabledUnits ||
-       ctx->FragmentProgram._Enabled) {
-      perf_debug("glCopyPixels(): Unsupported fragment shader state\n");
-      return false;
-   }
-
-   if (ctx->Color.AlphaEnabled ||
-       ctx->Color.BlendEnabled) {
-      perf_debug("glCopyPixels(): Unsupported blend state\n");
-      return false;
-   }
-
-   if (!ctx->Color.ColorMask[0][0] ||
-       !ctx->Color.ColorMask[0][1] ||
-       !ctx->Color.ColorMask[0][2] ||
-       !ctx->Color.ColorMask[0][3]) {
-      perf_debug("glCopyPixels(): Unsupported color mask state\n");
-      return false;
-   }
-
-   if (ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F) {
-      perf_debug("glCopyPixles(): Unsupported pixel zoom\n");
-      return false;
-   }
-
-   intel_prepare_render(intel);
-
-   intel_flush(&intel->ctx);
-
-   /* Clip to destination buffer. */
-   orig_dstx = dstx;
-   orig_dsty = dsty;
-   if (!_mesa_clip_to_region(fb->_Xmin, fb->_Ymin,
-                            fb->_Xmax, fb->_Ymax,
-                            &dstx, &dsty, &width, &height))
-      goto out;
-   /* Adjust src coords for our post-clipped destination origin */
-   srcx += dstx - orig_dstx;
-   srcy += dsty - orig_dsty;
-
-   /* Clip to source buffer. */
-   orig_srcx = srcx;
-   orig_srcy = srcy;
-   if (!_mesa_clip_to_region(0, 0,
-                            read_fb->Width, read_fb->Height,
-                            &srcx, &srcy, &width, &height))
-      goto out;
-   /* Adjust dst coords for our post-clipped source origin */
-   dstx += srcx - orig_srcx;
-   dsty += srcy - orig_srcy;
-
-   if (!intel_miptree_blit(intel,
-                           read_irb->mt, read_irb->mt_level, read_irb->mt_layer,
-                           srcx, srcy, _mesa_is_winsys_fbo(read_fb),
-                           draw_irb->mt, draw_irb->mt_level, draw_irb->mt_layer,
-                           dstx, dsty, _mesa_is_winsys_fbo(fb),
-                           width, height,
-                           (ctx->Color.ColorLogicOpEnabled ?
-                            ctx->Color.LogicOp : GL_COPY))) {
-      DBG("%s: blit failure\n", __FUNCTION__);
-      return false;
-   }
-
-   if (ctx->Query.CurrentOcclusionObject)
-      ctx->Query.CurrentOcclusionObject->Result += width * height;
-
-out:
-   intel_check_front_buffer_rendering(intel);
-
-   DBG("%s: success\n", __FUNCTION__);
-   return true;
-}
-
-
-void
-intelCopyPixels(struct gl_context * ctx,
-                GLint srcx, GLint srcy,
-                GLsizei width, GLsizei height,
-                GLint destx, GLint desty, GLenum type)
-{
-   DBG("%s\n", __FUNCTION__);
-
-   if (!_mesa_check_conditional_render(ctx))
-      return;
-
-   if (do_blit_copypixels(ctx, srcx, srcy, width, height, destx, desty, type))
-      return;
-
-   /* this will use swrast if needed */
-   _mesa_meta_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type);
-}
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_draw.c b/src/mesa/drivers/dri/intel/intel_pixel_draw.c
deleted file mode 100644 (file)
index 2ec7ed8..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portionsalloc
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-#include "main/glheader.h"
-#include "main/enums.h"
-#include "main/image.h"
-#include "main/mtypes.h"
-#include "main/teximage.h"
-#include "main/texobj.h"
-#include "main/texstate.h"
-#include "swrast/swrast.h"
-#include "drivers/common/meta.h"
-
-#include "intel_context.h"
-#include "intel_pixel.h"
-
-void
-intelDrawPixels(struct gl_context * ctx,
-                GLint x, GLint y,
-                GLsizei width, GLsizei height,
-                GLenum format,
-                GLenum type,
-                const struct gl_pixelstore_attrib *unpack,
-                const GLvoid * pixels)
-{
-   if (format == GL_STENCIL_INDEX) {
-      _swrast_DrawPixels(ctx, x, y, width, height, format, type,
-                         unpack, pixels);
-      return;
-   }
-
-   _mesa_meta_DrawPixels(ctx, x, y, width, height, format, type,
-                         unpack, pixels);
-}
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_read.c b/src/mesa/drivers/dri/intel/intel_pixel_read.c
deleted file mode 100644 (file)
index 26eb496..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-#include "main/glheader.h"
-#include "main/enums.h"
-#include "main/mtypes.h"
-#include "main/macros.h"
-#include "main/fbobject.h"
-#include "main/image.h"
-#include "main/bufferobj.h"
-#include "main/readpix.h"
-#include "main/state.h"
-
-#include "intel_screen.h"
-#include "intel_context.h"
-#include "intel_blit.h"
-#include "intel_buffers.h"
-#include "intel_fbo.h"
-#include "intel_mipmap_tree.h"
-#include "intel_regions.h"
-#include "intel_pixel.h"
-#include "intel_buffer_objects.h"
-
-#define FILE_DEBUG_FLAG DEBUG_PIXEL
-
-/* For many applications, the new ability to pull the source buffers
- * back out of the GTT and then do the packing/conversion operations
- * in software will be as much of an improvement as trying to get the
- * blitter and/or texture engine to do the work.
- *
- * This step is gated on private backbuffers.
- *
- * Obviously the frontbuffer can't be pulled back, so that is either
- * an argument for blit/texture readpixels, or for blitting to a
- * temporary and then pulling that back.
- *
- * When the destination is a pbo, however, it's not clear if it is
- * ever going to be pulled to main memory (though the access param
- * will be a good hint).  So it sounds like we do want to be able to
- * choose between blit/texture implementation on the gpu and pullback
- * and cpu-based copying.
- *
- * Unless you can magically turn client memory into a PBO for the
- * duration of this call, there will be a cpu-based copying step in
- * any case.
- */
-
-static bool
-do_blit_readpixels(struct gl_context * ctx,
-                   GLint x, GLint y, GLsizei width, GLsizei height,
-                   GLenum format, GLenum type,
-                   const struct gl_pixelstore_attrib *pack, GLvoid * pixels)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj);
-   GLuint dst_offset;
-   drm_intel_bo *dst_buffer;
-   bool all;
-   GLint dst_x, dst_y;
-   GLuint dirty;
-
-   DBG("%s\n", __FUNCTION__);
-
-   assert(_mesa_is_bufferobj(pack->BufferObj));
-
-   struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
-   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
-
-   if (ctx->_ImageTransferState ||
-       !_mesa_format_matches_format_and_type(irb->mt->format, format, type,
-                                             false)) {
-      DBG("%s - bad format for blit\n", __FUNCTION__);
-      return false;
-   }
-
-   if (pack->SwapBytes || pack->LsbFirst) {
-      DBG("%s: bad packing params\n", __FUNCTION__);
-      return false;
-   }
-
-   int dst_stride = _mesa_image_row_stride(pack, width, format, type);
-   bool dst_flip = false;
-   /* Mesa flips the dst_stride for pack->Invert, but we want our mt to have a
-    * normal dst_stride.
-    */
-   if (pack->Invert) {
-      dst_stride = -dst_stride;
-      dst_flip = true;
-   }
-
-   dst_offset = (GLintptr)pixels;
-   dst_offset += _mesa_image_offset(2, pack, width, height,
-                                   format, type, 0, 0, 0);
-
-   if (!_mesa_clip_copytexsubimage(ctx,
-                                  &dst_x, &dst_y,
-                                  &x, &y,
-                                  &width, &height)) {
-      return true;
-   }
-
-   dirty = intel->front_buffer_dirty;
-   intel_prepare_render(intel);
-   intel->front_buffer_dirty = dirty;
-
-   all = (width * height * irb->mt->cpp == dst->Base.Size &&
-         x == 0 && dst_offset == 0);
-
-   dst_buffer = intel_bufferobj_buffer(intel, dst,
-                                      all ? INTEL_WRITE_FULL :
-                                      INTEL_WRITE_PART);
-
-   struct intel_mipmap_tree *pbo_mt =
-      intel_miptree_create_for_bo(intel,
-                                  dst_buffer,
-                                  irb->mt->format,
-                                  dst_offset,
-                                  width, height,
-                                  dst_stride, I915_TILING_NONE);
-
-   if (!intel_miptree_blit(intel,
-                           irb->mt, irb->mt_level, irb->mt_layer,
-                           x, y, _mesa_is_winsys_fbo(ctx->ReadBuffer),
-                           pbo_mt, 0, 0,
-                           0, 0, dst_flip,
-                           width, height, GL_COPY)) {
-      return false;
-   }
-
-   intel_miptree_release(&pbo_mt);
-
-   DBG("%s - DONE\n", __FUNCTION__);
-
-   return true;
-}
-
-void
-intelReadPixels(struct gl_context * ctx,
-                GLint x, GLint y, GLsizei width, GLsizei height,
-                GLenum format, GLenum type,
-                const struct gl_pixelstore_attrib *pack, GLvoid * pixels)
-{
-   struct intel_context *intel = intel_context(ctx);
-   bool dirty;
-
-   intel_flush_rendering_to_batch(ctx);
-
-   DBG("%s\n", __FUNCTION__);
-
-   if (_mesa_is_bufferobj(pack->BufferObj)) {
-      /* Using PBOs, so try the BLT based path. */
-      if (do_blit_readpixels(ctx, x, y, width, height, format, type, pack,
-                             pixels)) {
-         return;
-      }
-
-      perf_debug("%s: fallback to CPU mapping in PBO case\n", __FUNCTION__);
-   }
-
-   /* glReadPixels() wont dirty the front buffer, so reset the dirty
-    * flag after calling intel_prepare_render(). */
-   dirty = intel->front_buffer_dirty;
-   intel_prepare_render(intel);
-   intel->front_buffer_dirty = dirty;
-
-   /* Update Mesa state before calling _mesa_readpixels().
-    * XXX this may not be needed since ReadPixels no longer uses the
-    * span code.
-    */
-
-   if (ctx->NewState)
-      _mesa_update_state(ctx);
-
-   _mesa_readpixels(ctx, x, y, width, height, format, type, pack, pixels);
-
-   /* There's an intel_prepare_render() call in intelSpanRenderStart(). */
-   intel->front_buffer_dirty = dirty;
-}
diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c
deleted file mode 100644 (file)
index 44f7030..0000000
+++ /dev/null
@@ -1,353 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/* Provide additional functionality on top of bufmgr buffers:
- *   - 2d semantics and blit operations
- *   - refcounting of buffers for multiple images in a buffer.
- *   - refcounting of buffer mappings.
- *   - some logic for moving the buffers to the best memory pools for
- *     given operations.
- *
- * Most of this is to make it easier to implement the fixed-layout
- * mipmap tree required by intel hardware in the face of GL's
- * programming interface where each image can be specifed in random
- * order and it isn't clear what layout the tree should have until the
- * last moment.
- */
-
-#include <sys/ioctl.h>
-#include <errno.h>
-
-#include "main/hash.h"
-#include "intel_context.h"
-#include "intel_regions.h"
-#include "intel_blit.h"
-#include "intel_buffer_objects.h"
-#include "intel_bufmgr.h"
-#include "intel_batchbuffer.h"
-
-#define FILE_DEBUG_FLAG DEBUG_REGION
-
-/* This should be set to the maximum backtrace size desired.
- * Set it to 0 to disable backtrace debugging.
- */
-#define DEBUG_BACKTRACE_SIZE 0
-
-#if DEBUG_BACKTRACE_SIZE == 0
-/* Use the standard debug output */
-#define _DBG(...) DBG(__VA_ARGS__)
-#else
-/* Use backtracing debug output */
-#define _DBG(...) {debug_backtrace(); DBG(__VA_ARGS__);}
-
-/* Backtracing debug support */
-#include <execinfo.h>
-
-static void
-debug_backtrace(void)
-{
-   void *trace[DEBUG_BACKTRACE_SIZE];
-   char **strings = NULL;
-   int traceSize;
-   register int i;
-
-   traceSize = backtrace(trace, DEBUG_BACKTRACE_SIZE);
-   strings = backtrace_symbols(trace, traceSize);
-   if (strings == NULL) {
-      DBG("no backtrace:");
-      return;
-   }
-
-   /* Spit out all the strings with a colon separator.  Ignore
-    * the first, since we don't really care about the call
-    * to debug_backtrace() itself.  Skip until the final "/" in
-    * the trace to avoid really long lines.
-    */
-   for (i = 1; i < traceSize; i++) {
-      char *p = strings[i], *slash = strings[i];
-      while (*p) {
-         if (*p++ == '/') {
-            slash = p;
-         }
-      }
-
-      DBG("%s:", slash);
-   }
-
-   /* Free up the memory, and we're done */
-   free(strings);
-}
-
-#endif
-
-static struct intel_region *
-intel_region_alloc_internal(struct intel_screen *screen,
-                           GLuint cpp,
-                           GLuint width, GLuint height, GLuint pitch,
-                           uint32_t tiling, drm_intel_bo *buffer)
-{
-   struct intel_region *region;
-
-   region = calloc(sizeof(*region), 1);
-   if (region == NULL)
-      return region;
-
-   region->cpp = cpp;
-   region->width = width;
-   region->height = height;
-   region->pitch = pitch;
-   region->refcount = 1;
-   region->bo = buffer;
-   region->tiling = tiling;
-
-   _DBG("%s <-- %p\n", __FUNCTION__, region);
-   return region;
-}
-
-struct intel_region *
-intel_region_alloc(struct intel_screen *screen,
-                  uint32_t tiling,
-                   GLuint cpp, GLuint width, GLuint height,
-                  bool expect_accelerated_upload)
-{
-   drm_intel_bo *buffer;
-   unsigned long flags = 0;
-   unsigned long aligned_pitch;
-   struct intel_region *region;
-
-   if (expect_accelerated_upload)
-      flags |= BO_ALLOC_FOR_RENDER;
-
-   buffer = drm_intel_bo_alloc_tiled(screen->bufmgr, "region",
-                                    width, height, cpp,
-                                    &tiling, &aligned_pitch, flags);
-   if (buffer == NULL)
-      return NULL;
-
-   region = intel_region_alloc_internal(screen, cpp, width, height,
-                                        aligned_pitch, tiling, buffer);
-   if (region == NULL) {
-      drm_intel_bo_unreference(buffer);
-      return NULL;
-   }
-
-   return region;
-}
-
-bool
-intel_region_flink(struct intel_region *region, uint32_t *name)
-{
-   if (region->name == 0) {
-      if (drm_intel_bo_flink(region->bo, &region->name))
-        return false;
-   }
-
-   *name = region->name;
-
-   return true;
-}
-
-struct intel_region *
-intel_region_alloc_for_handle(struct intel_screen *screen,
-                             GLuint cpp,
-                             GLuint width, GLuint height, GLuint pitch,
-                             GLuint handle, const char *name)
-{
-   struct intel_region *region;
-   drm_intel_bo *buffer;
-   int ret;
-   uint32_t bit_6_swizzle, tiling;
-
-   buffer = intel_bo_gem_create_from_name(screen->bufmgr, name, handle);
-   if (buffer == NULL)
-      return NULL;
-   ret = drm_intel_bo_get_tiling(buffer, &tiling, &bit_6_swizzle);
-   if (ret != 0) {
-      fprintf(stderr, "Couldn't get tiling of buffer %d (%s): %s\n",
-             handle, name, strerror(-ret));
-      drm_intel_bo_unreference(buffer);
-      return NULL;
-   }
-
-   region = intel_region_alloc_internal(screen, cpp,
-                                       width, height, pitch, tiling, buffer);
-   if (region == NULL) {
-      drm_intel_bo_unreference(buffer);
-      return NULL;
-   }
-
-   region->name = handle;
-
-   return region;
-}
-
-struct intel_region *
-intel_region_alloc_for_fd(struct intel_screen *screen,
-                          GLuint cpp,
-                          GLuint width, GLuint height, GLuint pitch,
-                          int fd, const char *name)
-{
-   struct intel_region *region;
-   drm_intel_bo *buffer;
-   int ret;
-   uint32_t bit_6_swizzle, tiling;
-
-   buffer = drm_intel_bo_gem_create_from_prime(screen->bufmgr,
-                                               fd, height * pitch);
-   if (buffer == NULL)
-      return NULL;
-   ret = drm_intel_bo_get_tiling(buffer, &tiling, &bit_6_swizzle);
-   if (ret != 0) {
-      fprintf(stderr, "Couldn't get tiling of buffer (%s): %s\n",
-             name, strerror(-ret));
-      drm_intel_bo_unreference(buffer);
-      return NULL;
-   }
-
-   region = intel_region_alloc_internal(screen, cpp,
-                                       width, height, pitch, tiling, buffer);
-   if (region == NULL) {
-      drm_intel_bo_unreference(buffer);
-      return NULL;
-   }
-
-   return region;
-}
-
-void
-intel_region_reference(struct intel_region **dst, struct intel_region *src)
-{
-   _DBG("%s: %p(%d) -> %p(%d)\n", __FUNCTION__,
-       *dst, *dst ? (*dst)->refcount : 0, src, src ? src->refcount : 0);
-
-   if (src != *dst) {
-      if (*dst)
-        intel_region_release(dst);
-
-      if (src)
-         src->refcount++;
-      *dst = src;
-   }
-}
-
-void
-intel_region_release(struct intel_region **region_handle)
-{
-   struct intel_region *region = *region_handle;
-
-   if (region == NULL) {
-      _DBG("%s NULL\n", __FUNCTION__);
-      return;
-   }
-
-   _DBG("%s %p %d\n", __FUNCTION__, region, region->refcount - 1);
-
-   ASSERT(region->refcount > 0);
-   region->refcount--;
-
-   if (region->refcount == 0) {
-      drm_intel_bo_unreference(region->bo);
-
-      free(region);
-   }
-   *region_handle = NULL;
-}
-
-/**
- * This function computes masks that may be used to select the bits of the X
- * and Y coordinates that indicate the offset within a tile.  If the region is
- * untiled, the masks are set to 0.
- */
-void
-intel_region_get_tile_masks(struct intel_region *region,
-                            uint32_t *mask_x, uint32_t *mask_y,
-                            bool map_stencil_as_y_tiled)
-{
-   int cpp = region->cpp;
-   uint32_t tiling = region->tiling;
-
-   if (map_stencil_as_y_tiled)
-      tiling = I915_TILING_Y;
-
-   switch (tiling) {
-   default:
-      assert(false);
-   case I915_TILING_NONE:
-      *mask_x = *mask_y = 0;
-      break;
-   case I915_TILING_X:
-      *mask_x = 512 / cpp - 1;
-      *mask_y = 7;
-      break;
-   case I915_TILING_Y:
-      *mask_x = 128 / cpp - 1;
-      *mask_y = 31;
-      break;
-   }
-}
-
-/**
- * Compute the offset (in bytes) from the start of the region to the given x
- * and y coordinate.  For tiled regions, caller must ensure that x and y are
- * multiples of the tile size.
- */
-uint32_t
-intel_region_get_aligned_offset(struct intel_region *region, uint32_t x,
-                                uint32_t y, bool map_stencil_as_y_tiled)
-{
-   int cpp = region->cpp;
-   uint32_t pitch = region->pitch;
-   uint32_t tiling = region->tiling;
-
-   if (map_stencil_as_y_tiled) {
-      tiling = I915_TILING_Y;
-
-      /* When mapping a W-tiled stencil buffer as Y-tiled, each 64-high W-tile
-       * gets transformed into a 32-high Y-tile.  Accordingly, the pitch of
-       * the resulting region is twice the pitch of the original region, since
-       * each row in the Y-tiled view corresponds to two rows in the actual
-       * W-tiled surface.  So we need to correct the pitch before computing
-       * the offsets.
-       */
-      pitch *= 2;
-   }
-
-   switch (tiling) {
-   default:
-      assert(false);
-   case I915_TILING_NONE:
-      return y * pitch + x * cpp;
-   case I915_TILING_X:
-      assert((x % (512 / cpp)) == 0);
-      assert((y % 8) == 0);
-      return y * pitch + x / (512 / cpp) * 4096;
-   case I915_TILING_Y:
-      assert((x % (128 / cpp)) == 0);
-      assert((y % 32) == 0);
-      return y * pitch + x / (128 / cpp) * 4096;
-   }
-}
diff --git a/src/mesa/drivers/dri/intel/intel_resolve_map.c b/src/mesa/drivers/dri/intel/intel_resolve_map.c
deleted file mode 100644 (file)
index 04b5c94..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright Â© 2011 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include "intel_resolve_map.h"
-
-#include <assert.h>
-#include <stdlib.h>
-
-/**
- * \brief Set that the miptree slice at (level, layer) needs a resolve.
- *
- * If a map element already exists with the given key, then the value is
- * changed to the given value of \c need.
- */
-void
-intel_resolve_map_set(struct intel_resolve_map *head,
-                     uint32_t level,
-                     uint32_t layer,
-                     enum gen6_hiz_op need)
-{
-   struct intel_resolve_map **tail = &head->next;
-   struct intel_resolve_map *prev = head;
-
-   while (*tail) {
-      if ((*tail)->level == level && (*tail)->layer == layer) {
-         (*tail)->need = need;
-        return;
-      }
-      prev = *tail;
-      tail = &(*tail)->next;
-   }
-
-   *tail = malloc(sizeof(**tail));
-   (*tail)->prev = prev;
-   (*tail)->next = NULL;
-   (*tail)->level = level;
-   (*tail)->layer = layer;
-   (*tail)->need = need;
-}
-
-/**
- * \brief Get an element from the map.
- * \return null if element is not contained in map.
- */
-struct intel_resolve_map*
-intel_resolve_map_get(struct intel_resolve_map *head,
-                     uint32_t level,
-                     uint32_t layer)
-{
-   struct intel_resolve_map *item = head->next;
-
-   while (item) {
-      if (item->level == level && item->layer == layer)
-        break;
-      else
-        item = item->next;
-   }
-
-   return item;
-}
-
-/**
- * \brief Remove and free an element from the map.
- */
-void
-intel_resolve_map_remove(struct intel_resolve_map *elem)
-{
-   if (elem->prev)
-      elem->prev->next = elem->next;
-   if (elem->next)
-      elem->next->prev = elem->prev;
-   free(elem);
-}
-
-/**
- * \brief Remove and free all elements of the map.
- */
-void
-intel_resolve_map_clear(struct intel_resolve_map *head)
-{
-   struct intel_resolve_map *next = head->next;
-   struct intel_resolve_map *trash;
-
-   while (next) {
-      trash = next;
-      next = next->next;
-      free(trash);
-   }
-
-   head->next = NULL;
-}
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
deleted file mode 100644 (file)
index 60a69a6..0000000
+++ /dev/null
@@ -1,1409 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-#include <errno.h>
-#include <time.h>
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/framebuffer.h"
-#include "main/renderbuffer.h"
-#include "main/texobj.h"
-#include "main/hash.h"
-#include "main/fbobject.h"
-#include "main/version.h"
-#include "swrast/s_renderbuffer.h"
-
-#include "utils.h"
-#include "xmlpool.h"
-
-PUBLIC const char __driConfigOptions[] =
-   DRI_CONF_BEGIN
-   DRI_CONF_SECTION_PERFORMANCE
-      DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_ALWAYS_SYNC)
-      /* Options correspond to DRI_CONF_BO_REUSE_DISABLED,
-       * DRI_CONF_BO_REUSE_ALL
-       */
-      DRI_CONF_OPT_BEGIN_V(bo_reuse, enum, 1, "0:1")
-        DRI_CONF_DESC_BEGIN(en, "Buffer object reuse")
-           DRI_CONF_ENUM(0, "Disable buffer object reuse")
-           DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects")
-        DRI_CONF_DESC_END
-      DRI_CONF_OPT_END
-
-      DRI_CONF_OPT_BEGIN_B(hiz, "true")
-        DRI_CONF_DESC(en, "Enable Hierarchical Z on gen6+")
-      DRI_CONF_OPT_END
-
-      DRI_CONF_OPT_BEGIN_B(early_z, "false")
-        DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).")
-      DRI_CONF_OPT_END
-
-   DRI_CONF_SECTION_END
-   DRI_CONF_SECTION_QUALITY
-      DRI_CONF_FORCE_S3TC_ENABLE("false")
-      DRI_CONF_ALLOW_LARGE_TEXTURES(2)
-   DRI_CONF_SECTION_END
-   DRI_CONF_SECTION_DEBUG
-      DRI_CONF_NO_RAST("false")
-      DRI_CONF_ALWAYS_FLUSH_BATCH("false")
-      DRI_CONF_ALWAYS_FLUSH_CACHE("false")
-      DRI_CONF_DISABLE_THROTTLING("false")
-      DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN("false")
-      DRI_CONF_DISABLE_GLSL_LINE_CONTINUATIONS("false")
-      DRI_CONF_DISABLE_BLEND_FUNC_EXTENDED("false")
-
-      DRI_CONF_OPT_BEGIN_B(shader_precompile, "true")
-        DRI_CONF_DESC(en, "Perform code generation at shader link time.")
-      DRI_CONF_OPT_END
-   DRI_CONF_SECTION_END
-DRI_CONF_END;
-
-const GLuint __driNConfigOptions = 14;
-
-#include "intel_batchbuffer.h"
-#include "intel_buffers.h"
-#include "intel_bufmgr.h"
-#include "intel_chipset.h"
-#include "intel_fbo.h"
-#include "intel_mipmap_tree.h"
-#include "intel_screen.h"
-#include "intel_tex.h"
-#include "intel_regions.h"
-
-#ifndef I915
-#include "brw_context.h"
-#endif
-
-#include "i915_drm.h"
-
-#ifdef USE_NEW_INTERFACE
-static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
-#endif /*USE_NEW_INTERFACE */
-
-/**
- * For debugging purposes, this returns a time in seconds.
- */
-double
-get_time(void)
-{
-   struct timespec tp;
-
-   clock_gettime(CLOCK_MONOTONIC, &tp);
-
-   return tp.tv_sec + tp.tv_nsec / 1000000000.0;
-}
-
-void
-aub_dump_bmp(struct gl_context *ctx)
-{
-   struct gl_framebuffer *fb = ctx->DrawBuffer;
-
-   for (int i = 0; i < fb->_NumColorDrawBuffers; i++) {
-      struct intel_renderbuffer *irb =
-        intel_renderbuffer(fb->_ColorDrawBuffers[i]);
-
-      if (irb && irb->mt) {
-        enum aub_dump_bmp_format format;
-
-        switch (irb->Base.Base.Format) {
-        case MESA_FORMAT_ARGB8888:
-        case MESA_FORMAT_XRGB8888:
-           format = AUB_DUMP_BMP_FORMAT_ARGB_8888;
-           break;
-        default:
-           continue;
-        }
-
-         assert(irb->mt->region->pitch % irb->mt->region->cpp == 0);
-        drm_intel_gem_bo_aub_dump_bmp(irb->mt->region->bo,
-                                      irb->draw_x,
-                                      irb->draw_y,
-                                      irb->Base.Base.Width,
-                                      irb->Base.Base.Height,
-                                      format,
-                                      irb->mt->region->pitch,
-                                      0);
-      }
-   }
-}
-
-static const __DRItexBufferExtension intelTexBufferExtension = {
-   .base = { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
-
-   .setTexBuffer        = intelSetTexBuffer,
-   .setTexBuffer2       = intelSetTexBuffer2,
-   .releaseTexBuffer    = NULL,
-};
-
-static void
-intelDRI2Flush(__DRIdrawable *drawable)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   struct intel_context *intel = intel_context(ctx);
-   if (intel == NULL)
-      return;
-
-   if (intel->gen < 4)
-      INTEL_FIREVERTICES(intel);
-
-   intel_resolve_for_dri2_flush(intel, drawable);
-   intel->need_throttle = true;
-
-   if (intel->batch.used)
-      intel_batchbuffer_flush(intel);
-
-   if (INTEL_DEBUG & DEBUG_AUB) {
-      aub_dump_bmp(ctx);
-   }
-}
-
-static const struct __DRI2flushExtensionRec intelFlushExtension = {
-    .base = { __DRI2_FLUSH, 3 },
-
-    .flush              = intelDRI2Flush,
-    .invalidate         = dri2InvalidateDrawable,
-};
-
-static struct intel_image_format intel_image_formats[] = {
-   { __DRI_IMAGE_FOURCC_ARGB8888, __DRI_IMAGE_COMPONENTS_RGBA, 1,
-     { { 0, 0, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } },
-
-   { __DRI_IMAGE_FOURCC_XRGB8888, __DRI_IMAGE_COMPONENTS_RGB, 1,
-     { { 0, 0, 0, __DRI_IMAGE_FORMAT_XRGB8888, 4 }, } },
-
-   { __DRI_IMAGE_FOURCC_YUV410, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
-     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
-       { 1, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 },
-       { 2, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 } } },
-
-   { __DRI_IMAGE_FOURCC_YUV411, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
-     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
-       { 1, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 },
-       { 2, 2, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
-
-   { __DRI_IMAGE_FOURCC_YUV420, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
-     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
-       { 1, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 },
-       { 2, 1, 1, __DRI_IMAGE_FORMAT_R8, 1 } } },
-
-   { __DRI_IMAGE_FOURCC_YUV422, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
-     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
-       { 1, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 },
-       { 2, 1, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
-
-   { __DRI_IMAGE_FOURCC_YUV444, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
-     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
-       { 1, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
-       { 2, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 } } },
-
-   { __DRI_IMAGE_FOURCC_NV12, __DRI_IMAGE_COMPONENTS_Y_UV, 2,
-     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
-       { 1, 1, 1, __DRI_IMAGE_FORMAT_GR88, 2 } } },
-
-   { __DRI_IMAGE_FOURCC_NV16, __DRI_IMAGE_COMPONENTS_Y_UV, 2,
-     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
-       { 1, 1, 0, __DRI_IMAGE_FORMAT_GR88, 2 } } },
-
-   /* For YUYV buffers, we set up two overlapping DRI images and treat
-    * them as planar buffers in the compositors.  Plane 0 is GR88 and
-    * samples YU or YV pairs and places Y into the R component, while
-    * plane 1 is ARGB and samples YUYV clusters and places pairs and
-    * places U into the G component and V into A.  This lets the
-    * texture sampler interpolate the Y components correctly when
-    * sampling from plane 0, and interpolate U and V correctly when
-    * sampling from plane 1. */
-   { __DRI_IMAGE_FOURCC_YUYV, __DRI_IMAGE_COMPONENTS_Y_XUXV, 2,
-     { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 },
-       { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } }
-};
-
-static __DRIimage *
-intel_allocate_image(int dri_format, void *loaderPrivate)
-{
-    __DRIimage *image;
-
-    image = calloc(1, sizeof *image);
-    if (image == NULL)
-       return NULL;
-
-    image->dri_format = dri_format;
-    image->offset = 0;
-
-    switch (dri_format) {
-    case __DRI_IMAGE_FORMAT_RGB565:
-       image->format = MESA_FORMAT_RGB565;
-       break;
-    case __DRI_IMAGE_FORMAT_XRGB8888:
-       image->format = MESA_FORMAT_XRGB8888;
-       break;
-    case __DRI_IMAGE_FORMAT_ARGB8888:
-       image->format = MESA_FORMAT_ARGB8888;
-       break;
-    case __DRI_IMAGE_FORMAT_ABGR8888:
-       image->format = MESA_FORMAT_RGBA8888_REV;
-       break;
-    case __DRI_IMAGE_FORMAT_XBGR8888:
-       image->format = MESA_FORMAT_RGBX8888_REV;
-       break;
-    case __DRI_IMAGE_FORMAT_R8:
-       image->format = MESA_FORMAT_R8;
-       break;
-    case __DRI_IMAGE_FORMAT_GR88:
-       image->format = MESA_FORMAT_GR88;
-       break;
-    case __DRI_IMAGE_FORMAT_NONE:
-       image->format = MESA_FORMAT_NONE;
-       break;
-    default:
-       free(image);
-       return NULL;
-    }
-
-    image->internal_format = _mesa_get_format_base_format(image->format);
-    image->data = loaderPrivate;
-
-    return image;
-}
-
-/**
- * Sets up a DRIImage structure to point to our shared image in a region
- */
-static void
-intel_setup_image_from_mipmap_tree(struct intel_context *intel, __DRIimage *image,
-                                   struct intel_mipmap_tree *mt, GLuint level,
-                                   GLuint zoffset)
-{
-   unsigned int draw_x, draw_y;
-   uint32_t mask_x, mask_y;
-
-   intel_miptree_make_shareable(intel, mt);
-
-   intel_miptree_check_level_layer(mt, level, zoffset);
-
-   intel_region_get_tile_masks(mt->region, &mask_x, &mask_y, false);
-   intel_miptree_get_image_offset(mt, level, zoffset, &draw_x, &draw_y);
-
-   image->width = mt->level[level].width;
-   image->height = mt->level[level].height;
-   image->tile_x = draw_x & mask_x;
-   image->tile_y = draw_y & mask_y;
-
-   image->offset = intel_region_get_aligned_offset(mt->region,
-                                                   draw_x & ~mask_x,
-                                                   draw_y & ~mask_y,
-                                                   false);
-
-   intel_region_reference(&image->region, mt->region);
-}
-
-static void
-intel_setup_image_from_dimensions(__DRIimage *image)
-{
-   image->width    = image->region->width;
-   image->height   = image->region->height;
-   image->tile_x = 0;
-   image->tile_y = 0;
-   image->has_depthstencil = false;
-}
-
-static inline uint32_t
-intel_dri_format(GLuint format)
-{
-   switch (format) {
-   case MESA_FORMAT_RGB565:
-      return __DRI_IMAGE_FORMAT_RGB565;
-   case MESA_FORMAT_XRGB8888:
-      return __DRI_IMAGE_FORMAT_XRGB8888;
-   case MESA_FORMAT_ARGB8888:
-      return __DRI_IMAGE_FORMAT_ARGB8888;
-   case MESA_FORMAT_RGBA8888_REV:
-      return __DRI_IMAGE_FORMAT_ABGR8888;
-   case MESA_FORMAT_R8:
-      return __DRI_IMAGE_FORMAT_R8;
-   case MESA_FORMAT_RG88:
-      return __DRI_IMAGE_FORMAT_GR88;
-   }
-
-   return MESA_FORMAT_NONE;
-}
-
-static __DRIimage *
-intel_create_image_from_name(__DRIscreen *screen,
-                            int width, int height, int format,
-                            int name, int pitch, void *loaderPrivate)
-{
-    struct intel_screen *intelScreen = screen->driverPrivate;
-    __DRIimage *image;
-    int cpp;
-
-    image = intel_allocate_image(format, loaderPrivate);
-    if (image == NULL)
-       return NULL;
-
-    if (image->format == MESA_FORMAT_NONE)
-       cpp = 1;
-    else
-       cpp = _mesa_get_format_bytes(image->format);
-    image->region = intel_region_alloc_for_handle(intelScreen,
-                                                 cpp, width, height,
-                                                 pitch * cpp, name, "image");
-    if (image->region == NULL) {
-       free(image);
-       return NULL;
-    }
-
-    intel_setup_image_from_dimensions(image);
-
-    return image;      
-}
-
-static __DRIimage *
-intel_create_image_from_renderbuffer(__DRIcontext *context,
-                                    int renderbuffer, void *loaderPrivate)
-{
-   __DRIimage *image;
-   struct intel_context *intel = context->driverPrivate;
-   struct gl_renderbuffer *rb;
-   struct intel_renderbuffer *irb;
-
-   rb = _mesa_lookup_renderbuffer(&intel->ctx, renderbuffer);
-   if (!rb) {
-      _mesa_error(&intel->ctx,
-                 GL_INVALID_OPERATION, "glRenderbufferExternalMESA");
-      return NULL;
-   }
-
-   irb = intel_renderbuffer(rb);
-   intel_miptree_make_shareable(intel, irb->mt);
-   image = calloc(1, sizeof *image);
-   if (image == NULL)
-      return NULL;
-
-   image->internal_format = rb->InternalFormat;
-   image->format = rb->Format;
-   image->offset = 0;
-   image->data = loaderPrivate;
-   intel_region_reference(&image->region, irb->mt->region);
-   intel_setup_image_from_dimensions(image);
-   image->dri_format = intel_dri_format(image->format);
-   image->has_depthstencil = irb->mt->stencil_mt? true : false;
-
-   rb->NeedsFinishRenderTexture = true;
-   return image;
-}
-
-static __DRIimage *
-intel_create_image_from_texture(__DRIcontext *context, int target,
-                                unsigned texture, int zoffset,
-                                int level,
-                                unsigned *error,
-                                void *loaderPrivate)
-{
-   __DRIimage *image;
-   struct intel_context *intel = context->driverPrivate;
-   struct gl_texture_object *obj;
-   struct intel_texture_object *iobj;
-   GLuint face = 0;
-
-   obj = _mesa_lookup_texture(&intel->ctx, texture);
-   if (!obj || obj->Target != target) {
-      *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
-      return NULL;
-   }
-
-   if (target == GL_TEXTURE_CUBE_MAP)
-      face = zoffset;
-
-   _mesa_test_texobj_completeness(&intel->ctx, obj);
-   iobj = intel_texture_object(obj);
-   if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) {
-      *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
-      return NULL;
-   }
-
-   if (level < obj->BaseLevel || level > obj->_MaxLevel) {
-      *error = __DRI_IMAGE_ERROR_BAD_MATCH;
-      return NULL;
-   }
-
-   if (target == GL_TEXTURE_3D && obj->Image[face][level]->Depth < zoffset) {
-      *error = __DRI_IMAGE_ERROR_BAD_MATCH;
-      return NULL;
-   }
-   image = calloc(1, sizeof *image);
-   if (image == NULL) {
-      *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
-      return NULL;
-   }
-
-   image->internal_format = obj->Image[face][level]->InternalFormat;
-   image->format = obj->Image[face][level]->TexFormat;
-   image->data = loaderPrivate;
-   intel_setup_image_from_mipmap_tree(intel, image, iobj->mt, level, zoffset);
-   image->dri_format = intel_dri_format(image->format);
-   image->has_depthstencil = iobj->mt->stencil_mt? true : false;
-   if (image->dri_format == MESA_FORMAT_NONE) {
-      *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
-      free(image);
-      return NULL;
-   }
-
-   *error = __DRI_IMAGE_ERROR_SUCCESS;
-   return image;
-}
-
-static void
-intel_destroy_image(__DRIimage *image)
-{
-    intel_region_release(&image->region);
-    free(image);
-}
-
-static __DRIimage *
-intel_create_image(__DRIscreen *screen,
-                  int width, int height, int format,
-                  unsigned int use,
-                  void *loaderPrivate)
-{
-   __DRIimage *image;
-   struct intel_screen *intelScreen = screen->driverPrivate;
-   uint32_t tiling;
-   int cpp;
-
-   tiling = I915_TILING_X;
-   if (use & __DRI_IMAGE_USE_CURSOR) {
-      if (width != 64 || height != 64)
-        return NULL;
-      tiling = I915_TILING_NONE;
-   }
-
-   image = intel_allocate_image(format, loaderPrivate);
-   if (image == NULL)
-      return NULL;
-
-   cpp = _mesa_get_format_bytes(image->format);
-   image->region =
-      intel_region_alloc(intelScreen, tiling, cpp, width, height, true);
-   if (image->region == NULL) {
-      free(image);
-      return NULL;
-   }
-   
-   intel_setup_image_from_dimensions(image);
-
-   return image;
-}
-
-static GLboolean
-intel_query_image(__DRIimage *image, int attrib, int *value)
-{
-   switch (attrib) {
-   case __DRI_IMAGE_ATTRIB_STRIDE:
-      *value = image->region->pitch;
-      return true;
-   case __DRI_IMAGE_ATTRIB_HANDLE:
-      *value = image->region->bo->handle;
-      return true;
-   case __DRI_IMAGE_ATTRIB_NAME:
-      return intel_region_flink(image->region, (uint32_t *) value);
-   case __DRI_IMAGE_ATTRIB_FORMAT:
-      *value = image->dri_format;
-      return true;
-   case __DRI_IMAGE_ATTRIB_WIDTH:
-      *value = image->region->width;
-      return true;
-   case __DRI_IMAGE_ATTRIB_HEIGHT:
-      *value = image->region->height;
-      return true;
-   case __DRI_IMAGE_ATTRIB_COMPONENTS:
-      if (image->planar_format == NULL)
-         return false;
-      *value = image->planar_format->components;
-      return true;
-   case __DRI_IMAGE_ATTRIB_FD:
-      if (drm_intel_bo_gem_export_to_prime(image->region->bo, value) == 0)
-         return true;
-      return false;
-  default:
-      return false;
-   }
-}
-
-static __DRIimage *
-intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
-{
-   __DRIimage *image;
-
-   image = calloc(1, sizeof *image);
-   if (image == NULL)
-      return NULL;
-
-   intel_region_reference(&image->region, orig_image->region);
-   if (image->region == NULL) {
-      free(image);
-      return NULL;
-   }
-
-   image->internal_format = orig_image->internal_format;
-   image->planar_format   = orig_image->planar_format;
-   image->dri_format      = orig_image->dri_format;
-   image->format          = orig_image->format;
-   image->offset          = orig_image->offset;
-   image->width           = orig_image->width;
-   image->height          = orig_image->height;
-   image->tile_x          = orig_image->tile_x;
-   image->tile_y          = orig_image->tile_y;
-   image->has_depthstencil = orig_image->has_depthstencil;
-   image->data            = loaderPrivate;
-
-   memcpy(image->strides, orig_image->strides, sizeof(image->strides));
-   memcpy(image->offsets, orig_image->offsets, sizeof(image->offsets));
-
-   return image;
-}
-
-static GLboolean
-intel_validate_usage(__DRIimage *image, unsigned int use)
-{
-   if (use & __DRI_IMAGE_USE_CURSOR) {
-      if (image->region->width != 64 || image->region->height != 64)
-        return GL_FALSE;
-   }
-
-   return GL_TRUE;
-}
-
-static __DRIimage *
-intel_create_image_from_names(__DRIscreen *screen,
-                              int width, int height, int fourcc,
-                              int *names, int num_names,
-                              int *strides, int *offsets,
-                              void *loaderPrivate)
-{
-    struct intel_image_format *f = NULL;
-    __DRIimage *image;
-    int i, index;
-
-    if (screen == NULL || names == NULL || num_names != 1)
-        return NULL;
-
-    for (i = 0; i < ARRAY_SIZE(intel_image_formats); i++) {
-        if (intel_image_formats[i].fourcc == fourcc) {
-           f = &intel_image_formats[i];
-        }
-    }
-
-    if (f == NULL)
-        return NULL;
-
-    image = intel_create_image_from_name(screen, width, height,
-                                         __DRI_IMAGE_FORMAT_NONE,
-                                         names[0], strides[0],
-                                         loaderPrivate);
-
-   if (image == NULL)
-      return NULL;
-
-    image->planar_format = f;
-    for (i = 0; i < f->nplanes; i++) {
-        index = f->planes[i].buffer_index;
-        image->offsets[index] = offsets[index];
-        image->strides[index] = strides[index];
-    }
-
-    return image;
-}
-
-static __DRIimage *
-intel_create_image_from_fds(__DRIscreen *screen,
-                            int width, int height, int fourcc,
-                            int *fds, int num_fds, int *strides, int *offsets,
-                            void *loaderPrivate)
-{
-   struct intel_screen *intelScreen = screen->driverPrivate;
-   struct intel_image_format *f = NULL;
-   __DRIimage *image;
-   int i, index;
-
-   if (fds == NULL || num_fds != 1)
-      return NULL;
-
-   for (i = 0; i < ARRAY_SIZE(intel_image_formats); i++) {
-      if (intel_image_formats[i].fourcc == fourcc) {
-         f = &intel_image_formats[i];
-      }
-   }
-
-   if (f == NULL)
-      return NULL;
-
-   image = intel_allocate_image(__DRI_IMAGE_FORMAT_NONE, loaderPrivate);
-   if (image == NULL)
-      return NULL;
-
-   image->region = intel_region_alloc_for_fd(intelScreen,
-                                             1, width, height,
-                                             strides[0], fds[0], "image");
-   if (image->region == NULL) {
-      free(image);
-      return NULL;
-   }
-
-   image->planar_format = f;
-   for (i = 0; i < f->nplanes; i++) {
-      index = f->planes[i].buffer_index;
-      image->offsets[index] = offsets[index];
-      image->strides[index] = strides[index];
-   }
-
-   return image;
-}
-
-
-static __DRIimage *
-intel_from_planar(__DRIimage *parent, int plane, void *loaderPrivate)
-{
-    int width, height, offset, stride, dri_format, index;
-    struct intel_image_format *f;
-    uint32_t mask_x, mask_y;
-    __DRIimage *image;
-
-    if (parent == NULL || parent->planar_format == NULL)
-        return NULL;
-
-    f = parent->planar_format;
-
-    if (plane >= f->nplanes)
-        return NULL;
-
-    width = parent->region->width >> f->planes[plane].width_shift;
-    height = parent->region->height >> f->planes[plane].height_shift;
-    dri_format = f->planes[plane].dri_format;
-    index = f->planes[plane].buffer_index;
-    offset = parent->offsets[index];
-    stride = parent->strides[index];
-
-    image = intel_allocate_image(dri_format, loaderPrivate);
-    if (image == NULL)
-       return NULL;
-
-    if (offset + height * stride > parent->region->bo->size) {
-       _mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds");
-       free(image);
-       return NULL;
-    }
-
-    image->region = calloc(sizeof(*image->region), 1);
-    if (image->region == NULL) {
-       free(image);
-       return NULL;
-    }
-
-    image->region->cpp = _mesa_get_format_bytes(image->format);
-    image->region->width = width;
-    image->region->height = height;
-    image->region->pitch = stride;
-    image->region->refcount = 1;
-    image->region->bo = parent->region->bo;
-    drm_intel_bo_reference(image->region->bo);
-    image->region->tiling = parent->region->tiling;
-    image->offset = offset;
-    intel_setup_image_from_dimensions(image);
-
-    intel_region_get_tile_masks(image->region, &mask_x, &mask_y, false);
-    if (offset & mask_x)
-       _mesa_warning(NULL,
-                     "intel_create_sub_image: offset not on tile boundary");
-
-    return image;
-}
-
-static struct __DRIimageExtensionRec intelImageExtension = {
-    .base = { __DRI_IMAGE, 7 },
-
-    .createImageFromName                = intel_create_image_from_name,
-    .createImageFromRenderbuffer        = intel_create_image_from_renderbuffer,
-    .destroyImage                       = intel_destroy_image,
-    .createImage                        = intel_create_image,
-    .queryImage                         = intel_query_image,
-    .dupImage                           = intel_dup_image,
-    .validateUsage                      = intel_validate_usage,
-    .createImageFromNames               = intel_create_image_from_names,
-    .fromPlanar                         = intel_from_planar,
-    .createImageFromTexture             = intel_create_image_from_texture,
-    .createImageFromFds                 = intel_create_image_from_fds
-};
-
-static const __DRIextension *intelScreenExtensions[] = {
-    &intelTexBufferExtension.base,
-    &intelFlushExtension.base,
-    &intelImageExtension.base,
-    &dri2ConfigQueryExtension.base,
-    NULL
-};
-
-static bool
-intel_get_param(__DRIscreen *psp, int param, int *value)
-{
-   int ret;
-   struct drm_i915_getparam gp;
-
-   memset(&gp, 0, sizeof(gp));
-   gp.param = param;
-   gp.value = value;
-
-   ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
-   if (ret) {
-      if (ret != -EINVAL)
-        _mesa_warning(NULL, "drm_i915_getparam: %d", ret);
-      return false;
-   }
-
-   return true;
-}
-
-static bool
-intel_get_boolean(__DRIscreen *psp, int param)
-{
-   int value = 0;
-   return intel_get_param(psp, param, &value) && value;
-}
-
-static void
-intelDestroyScreen(__DRIscreen * sPriv)
-{
-   struct intel_screen *intelScreen = sPriv->driverPrivate;
-
-   dri_bufmgr_destroy(intelScreen->bufmgr);
-   driDestroyOptionInfo(&intelScreen->optionCache);
-
-   free(intelScreen);
-   sPriv->driverPrivate = NULL;
-}
-
-
-/**
- * This is called when we need to set up GL rendering to a new X window.
- */
-static GLboolean
-intelCreateBuffer(__DRIscreen * driScrnPriv,
-                  __DRIdrawable * driDrawPriv,
-                  const struct gl_config * mesaVis, GLboolean isPixmap)
-{
-   struct intel_renderbuffer *rb;
-   struct intel_screen *screen = (struct intel_screen*) driScrnPriv->driverPrivate;
-   gl_format rgbFormat;
-   unsigned num_samples = intel_quantize_num_samples(screen, mesaVis->samples);
-   struct gl_framebuffer *fb;
-
-   if (isPixmap)
-      return false;
-
-   fb = CALLOC_STRUCT(gl_framebuffer);
-   if (!fb)
-      return false;
-
-   _mesa_initialize_window_framebuffer(fb, mesaVis);
-
-   if (mesaVis->redBits == 5)
-      rgbFormat = MESA_FORMAT_RGB565;
-   else if (mesaVis->sRGBCapable)
-      rgbFormat = MESA_FORMAT_SARGB8;
-   else if (mesaVis->alphaBits == 0)
-      rgbFormat = MESA_FORMAT_XRGB8888;
-   else {
-      if (screen->gen >= 4) {
-         rgbFormat = MESA_FORMAT_SARGB8;
-         fb->Visual.sRGBCapable = true;
-      } else {
-         rgbFormat = MESA_FORMAT_ARGB8888;
-      }
-
-   }
-
-   /* setup the hardware-based renderbuffers */
-   rb = intel_create_renderbuffer(rgbFormat, num_samples);
-   _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &rb->Base.Base);
-
-   if (mesaVis->doubleBufferMode) {
-      rb = intel_create_renderbuffer(rgbFormat, num_samples);
-      _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &rb->Base.Base);
-   }
-
-   /*
-    * Assert here that the gl_config has an expected depth/stencil bit
-    * combination: one of d24/s8, d16/s0, d0/s0. (See intelInitScreen2(),
-    * which constructs the advertised configs.)
-    */
-   if (mesaVis->depthBits == 24) {
-      assert(mesaVis->stencilBits == 8);
-
-      if (screen->hw_has_separate_stencil) {
-         rb = intel_create_private_renderbuffer(MESA_FORMAT_X8_Z24,
-                                                num_samples);
-         _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
-         rb = intel_create_private_renderbuffer(MESA_FORMAT_S8,
-                                                num_samples);
-         _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
-      } else {
-         /*
-          * Use combined depth/stencil. Note that the renderbuffer is
-          * attached to two attachment points.
-          */
-         rb = intel_create_private_renderbuffer(MESA_FORMAT_S8_Z24,
-                                                num_samples);
-         _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
-         _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base);
-      }
-   }
-   else if (mesaVis->depthBits == 16) {
-      assert(mesaVis->stencilBits == 0);
-      rb = intel_create_private_renderbuffer(MESA_FORMAT_Z16,
-                                             num_samples);
-      _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base);
-   }
-   else {
-      assert(mesaVis->depthBits == 0);
-      assert(mesaVis->stencilBits == 0);
-   }
-
-   /* now add any/all software-based renderbuffers we may need */
-   _swrast_add_soft_renderbuffers(fb,
-                                  false, /* never sw color */
-                                  false, /* never sw depth */
-                                  false, /* never sw stencil */
-                                  mesaVis->accumRedBits > 0,
-                                  false, /* never sw alpha */
-                                  false  /* never sw aux */ );
-   driDrawPriv->driverPrivate = fb;
-
-   return true;
-}
-
-static void
-intelDestroyBuffer(__DRIdrawable * driDrawPriv)
-{
-    struct gl_framebuffer *fb = driDrawPriv->driverPrivate;
-  
-    _mesa_reference_framebuffer(&fb, NULL);
-}
-
-/* There are probably better ways to do this, such as an
- * init-designated function to register chipids and createcontext
- * functions.
- */
-extern bool
-i830CreateContext(int api,
-                  const struct gl_config *mesaVis,
-                 __DRIcontext *driContextPriv,
-                 unsigned major_version,
-                 unsigned minor_version,
-                 unsigned *error,
-                 void *sharedContextPrivate);
-
-extern bool
-i915CreateContext(int api,
-                 const struct gl_config *mesaVis,
-                 __DRIcontext *driContextPriv,
-                  unsigned major_version,
-                  unsigned minor_version,
-                  unsigned *error,
-                 void *sharedContextPrivate);
-extern bool
-brwCreateContext(int api,
-                const struct gl_config *mesaVis,
-                __DRIcontext *driContextPriv,
-                 unsigned major_version,
-                 unsigned minor_version,
-                 uint32_t flags,
-                 unsigned *error,
-                void *sharedContextPrivate);
-
-static GLboolean
-intelCreateContext(gl_api api,
-                  const struct gl_config * mesaVis,
-                   __DRIcontext * driContextPriv,
-                  unsigned major_version,
-                  unsigned minor_version,
-                  uint32_t flags,
-                  unsigned *error,
-                   void *sharedContextPrivate)
-{
-   bool success = false;
-
-#ifdef I915
-   __DRIscreen *sPriv = driContextPriv->driScreenPriv;
-   struct intel_screen *intelScreen = sPriv->driverPrivate;
-
-   if (IS_9XX(intelScreen->deviceID)) {
-      success = i915CreateContext(api, mesaVis, driContextPriv,
-                                  major_version, minor_version, error,
-                                  sharedContextPrivate);
-   } else {
-      intelScreen->no_vbo = true;
-      success = i830CreateContext(api, mesaVis, driContextPriv,
-                                  major_version, minor_version, error,
-                                  sharedContextPrivate);
-   }
-#else
-   success = brwCreateContext(api, mesaVis,
-                              driContextPriv,
-                              major_version, minor_version, flags,
-                              error, sharedContextPrivate);
-#endif
-
-   if (success)
-      return true;
-
-   if (driContextPriv->driverPrivate != NULL)
-      intelDestroyContext(driContextPriv);
-
-   return false;
-}
-
-static bool
-intel_init_bufmgr(struct intel_screen *intelScreen)
-{
-   __DRIscreen *spriv = intelScreen->driScrnPriv;
-
-   intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL;
-
-   intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ);
-   if (intelScreen->bufmgr == NULL) {
-      fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n",
-             __func__, __LINE__);
-      return false;
-   }
-
-   drm_intel_bufmgr_gem_enable_fenced_relocs(intelScreen->bufmgr);
-
-   if (!intel_get_boolean(spriv, I915_PARAM_HAS_RELAXED_DELTA)) {
-      fprintf(stderr, "[%s: %u] Kernel 2.6.39 required.\n", __func__, __LINE__);
-      return false;
-   }
-
-   return true;
-}
-
-/**
- * Override intel_screen.hw_has_separate_stencil with environment variable
- * INTEL_SEPARATE_STENCIL.
- *
- * Valid values for INTEL_SEPARATE_STENCIL are "0" and "1". If an invalid
- * valid value is encountered, a warning is emitted and INTEL_SEPARATE_STENCIL
- * is ignored.
- */
-static void
-intel_override_separate_stencil(struct intel_screen *screen)
-{
-   const char *s = getenv("INTEL_SEPARATE_STENCIL");
-   if (!s) {
-      return;
-   } else if (!strncmp("0", s, 2)) {
-      screen->hw_has_separate_stencil = false;
-   } else if (!strncmp("1", s, 2)) {
-      screen->hw_has_separate_stencil = true;
-   } else {
-      fprintf(stderr,
-             "warning: env variable INTEL_SEPARATE_STENCIL=\"%s\" has "
-             "invalid value and is ignored", s);
-   }
-}
-
-static bool
-intel_detect_swizzling(struct intel_screen *screen)
-{
-   drm_intel_bo *buffer;
-   unsigned long flags = 0;
-   unsigned long aligned_pitch;
-   uint32_t tiling = I915_TILING_X;
-   uint32_t swizzle_mode = 0;
-
-   buffer = drm_intel_bo_alloc_tiled(screen->bufmgr, "swizzle test",
-                                    64, 64, 4,
-                                    &tiling, &aligned_pitch, flags);
-   if (buffer == NULL)
-      return false;
-
-   drm_intel_bo_get_tiling(buffer, &tiling, &swizzle_mode);
-   drm_intel_bo_unreference(buffer);
-
-   if (swizzle_mode == I915_BIT_6_SWIZZLE_NONE)
-      return false;
-   else
-      return true;
-}
-
-static __DRIconfig**
-intel_screen_make_configs(__DRIscreen *dri_screen)
-{
-   static const gl_format formats[] = {
-      MESA_FORMAT_RGB565,
-      MESA_FORMAT_ARGB8888
-   };
-
-   /* GLX_SWAP_COPY_OML is not supported due to page flipping. */
-   static const GLenum back_buffer_modes[] = {
-       GLX_SWAP_UNDEFINED_OML, GLX_NONE,
-   };
-
-   static const uint8_t singlesample_samples[1] = {0};
-   static const uint8_t multisample_samples[2]  = {4, 8};
-
-   struct intel_screen *screen = dri_screen->driverPrivate;
-   uint8_t depth_bits[4], stencil_bits[4];
-   __DRIconfig **configs = NULL;
-
-   /* Generate singlesample configs without accumulation buffer. */
-   for (int i = 0; i < ARRAY_SIZE(formats); i++) {
-      __DRIconfig **new_configs;
-      int num_depth_stencil_bits = 2;
-
-      /* Starting with DRI2 protocol version 1.1 we can request a depth/stencil
-       * buffer that has a different number of bits per pixel than the color
-       * buffer, gen >= 6 supports this.
-       */
-      depth_bits[0] = 0;
-      stencil_bits[0] = 0;
-
-      if (formats[i] == MESA_FORMAT_RGB565) {
-         depth_bits[1] = 16;
-         stencil_bits[1] = 0;
-         if (screen->gen >= 6) {
-             depth_bits[2] = 24;
-             stencil_bits[2] = 8;
-             num_depth_stencil_bits = 3;
-         }
-      } else {
-         depth_bits[1] = 24;
-         stencil_bits[1] = 8;
-      }
-
-      new_configs = driCreateConfigs(formats[i],
-                                     depth_bits,
-                                     stencil_bits,
-                                     num_depth_stencil_bits,
-                                     back_buffer_modes, 2,
-                                     singlesample_samples, 1,
-                                     false);
-      configs = driConcatConfigs(configs, new_configs);
-   }
-
-   /* Generate the minimum possible set of configs that include an
-    * accumulation buffer.
-    */
-   for (int i = 0; i < ARRAY_SIZE(formats); i++) {
-      __DRIconfig **new_configs;
-
-      if (formats[i] == MESA_FORMAT_RGB565) {
-         depth_bits[0] = 16;
-         stencil_bits[0] = 0;
-      } else {
-         depth_bits[0] = 24;
-         stencil_bits[0] = 8;
-      }
-
-      new_configs = driCreateConfigs(formats[i],
-                                     depth_bits, stencil_bits, 1,
-                                     back_buffer_modes, 1,
-                                     singlesample_samples, 1,
-                                     true);
-      configs = driConcatConfigs(configs, new_configs);
-   }
-
-   /* Generate multisample configs.
-    *
-    * This loop breaks early, and hence is a no-op, on gen < 6.
-    *
-    * Multisample configs must follow the singlesample configs in order to
-    * work around an X server bug present in 1.12. The X server chooses to
-    * associate the first listed RGBA888-Z24S8 config, regardless of its
-    * sample count, with the 32-bit depth visual used for compositing.
-    *
-    * Only doublebuffer configs with GLX_SWAP_UNDEFINED_OML behavior are
-    * supported.  Singlebuffer configs are not supported because no one wants
-    * them.
-    */
-   for (int i = 0; i < ARRAY_SIZE(formats); i++) {
-      if (screen->gen < 6)
-         break;
-
-      __DRIconfig **new_configs;
-      const int num_depth_stencil_bits = 2;
-      int num_msaa_modes = 0;
-
-      depth_bits[0] = 0;
-      stencil_bits[0] = 0;
-
-      if (formats[i] == MESA_FORMAT_RGB565) {
-         depth_bits[1] = 16;
-         stencil_bits[1] = 0;
-      } else {
-         depth_bits[1] = 24;
-         stencil_bits[1] = 8;
-      }
-
-      if (screen->gen >= 7)
-         num_msaa_modes = 2;
-      else if (screen->gen == 6)
-         num_msaa_modes = 1;
-
-      new_configs = driCreateConfigs(formats[i],
-                                     depth_bits,
-                                     stencil_bits,
-                                     num_depth_stencil_bits,
-                                     back_buffer_modes, 1,
-                                     multisample_samples,
-                                     num_msaa_modes,
-                                     false);
-      configs = driConcatConfigs(configs, new_configs);
-   }
-
-   if (configs == NULL) {
-      fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
-              __LINE__);
-      return NULL;
-   }
-
-   return configs;
-}
-
-static void
-set_max_gl_versions(struct intel_screen *screen)
-{
-   int gl_version_override = _mesa_get_gl_version_override();
-
-   switch (screen->gen) {
-   case 7:
-      screen->max_gl_core_version = 31;
-      screen->max_gl_compat_version = 30;
-      screen->max_gl_es1_version = 11;
-      screen->max_gl_es2_version = 30;
-      break;
-   case 6:
-      screen->max_gl_core_version = 31;
-      screen->max_gl_compat_version = 30;
-      screen->max_gl_es1_version = 11;
-      screen->max_gl_es2_version = 30;
-      break;
-   case 5:
-   case 4:
-      screen->max_gl_core_version = 0;
-      screen->max_gl_compat_version = 21;
-      screen->max_gl_es1_version = 11;
-      screen->max_gl_es2_version = 20;
-      break;
-   case 3: {
-      screen->max_gl_core_version = 0;
-      screen->max_gl_es1_version = 11;
-      screen->max_gl_compat_version = 21;
-      screen->max_gl_es2_version = 20;
-
-      break;
-   }
-   case 2:
-      screen->max_gl_core_version = 0;
-      screen->max_gl_compat_version = 13;
-      screen->max_gl_es1_version = 11;
-      screen->max_gl_es2_version = 0;
-      break;
-   default:
-      assert(!"unrecognized intel_screen::gen");
-      break;
-   }
-
-   if (gl_version_override >= 31) {
-      screen->max_gl_core_version = MAX2(screen->max_gl_core_version,
-                                         gl_version_override);
-   } else {
-      screen->max_gl_compat_version = MAX2(screen->max_gl_compat_version,
-                                           gl_version_override);
-   }
-
-#ifndef FEATURE_ES1
-   screen->max_gl_es1_version = 0;
-#endif
-
-#ifndef FEATURE_ES2
-   screen->max_gl_es2_version = 0;
-#endif
-}
-
-/**
- * This is the driver specific part of the createNewScreen entry point.
- * Called when using DRI2.
- *
- * \return the struct gl_config supported by this driver
- */
-static const
-__DRIconfig **intelInitScreen2(__DRIscreen *psp)
-{
-   struct intel_screen *intelScreen;
-
-   if (psp->dri2.loader->base.version <= 2 ||
-       psp->dri2.loader->getBuffersWithFormat == NULL) {
-      fprintf(stderr,
-             "\nERROR!  DRI2 loader with getBuffersWithFormat() "
-             "support required\n");
-      return false;
-   }
-
-   /* Allocate the private area */
-   intelScreen = calloc(1, sizeof *intelScreen);
-   if (!intelScreen) {
-      fprintf(stderr, "\nERROR!  Allocating private area failed\n");
-      return false;
-   }
-   /* parse information in __driConfigOptions */
-   driParseOptionInfo(&intelScreen->optionCache,
-                      __driConfigOptions, __driNConfigOptions);
-
-   intelScreen->driScrnPriv = psp;
-   psp->driverPrivate = (void *) intelScreen;
-
-   if (!intel_init_bufmgr(intelScreen))
-       return false;
-
-   intelScreen->deviceID = drm_intel_bufmgr_gem_get_devid(intelScreen->bufmgr);
-
-   if (IS_GEN7(intelScreen->deviceID)) {
-      intelScreen->gen = 7;
-   } else if (IS_GEN6(intelScreen->deviceID)) {
-      intelScreen->gen = 6;
-   } else if (IS_GEN5(intelScreen->deviceID)) {
-      intelScreen->gen = 5;
-   } else if (IS_965(intelScreen->deviceID)) {
-      intelScreen->gen = 4;
-   } else if (IS_9XX(intelScreen->deviceID)) {
-      intelScreen->gen = 3;
-   } else {
-      intelScreen->gen = 2;
-   }
-
-   intelScreen->hw_has_separate_stencil = intelScreen->gen >= 6;
-   intelScreen->hw_must_use_separate_stencil = intelScreen->gen >= 7;
-
-   int has_llc = 0;
-   bool success = intel_get_param(intelScreen->driScrnPriv, I915_PARAM_HAS_LLC,
-                                 &has_llc);
-   if (success && has_llc)
-      intelScreen->hw_has_llc = true;
-   else if (!success && intelScreen->gen >= 6)
-      intelScreen->hw_has_llc = true;
-
-   intel_override_separate_stencil(intelScreen);
-
-   intelScreen->hw_has_swizzling = intel_detect_swizzling(intelScreen);
-
-   set_max_gl_versions(intelScreen);
-
-   psp->api_mask = (1 << __DRI_API_OPENGL);
-   if (intelScreen->max_gl_core_version > 0)
-      psp->api_mask |= (1 << __DRI_API_OPENGL_CORE);
-   if (intelScreen->max_gl_es1_version > 0)
-      psp->api_mask |= (1 << __DRI_API_GLES);
-   if (intelScreen->max_gl_es2_version > 0)
-      psp->api_mask |= (1 << __DRI_API_GLES2);
-   if (intelScreen->max_gl_es2_version >= 30)
-      psp->api_mask |= (1 << __DRI_API_GLES3);
-
-   psp->extensions = intelScreenExtensions;
-
-   return (const __DRIconfig**) intel_screen_make_configs(psp);
-}
-
-struct intel_buffer {
-   __DRIbuffer base;
-   struct intel_region *region;
-};
-
-static __DRIbuffer *
-intelAllocateBuffer(__DRIscreen *screen,
-                   unsigned attachment, unsigned format,
-                   int width, int height)
-{
-   struct intel_buffer *intelBuffer;
-   struct intel_screen *intelScreen = screen->driverPrivate;
-
-   assert(attachment == __DRI_BUFFER_FRONT_LEFT ||
-          attachment == __DRI_BUFFER_BACK_LEFT);
-
-   intelBuffer = calloc(1, sizeof *intelBuffer);
-   if (intelBuffer == NULL)
-      return NULL;
-
-   /* The front and back buffers are color buffers, which are X tiled. */
-   intelBuffer->region = intel_region_alloc(intelScreen,
-                                            I915_TILING_X,
-                                            format / 8,
-                                            width,
-                                            height,
-                                            true);
-   
-   if (intelBuffer->region == NULL) {
-          free(intelBuffer);
-          return NULL;
-   }
-   
-   intel_region_flink(intelBuffer->region, &intelBuffer->base.name);
-
-   intelBuffer->base.attachment = attachment;
-   intelBuffer->base.cpp = intelBuffer->region->cpp;
-   intelBuffer->base.pitch = intelBuffer->region->pitch;
-
-   return &intelBuffer->base;
-}
-
-static void
-intelReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer)
-{
-   struct intel_buffer *intelBuffer = (struct intel_buffer *) buffer;
-
-   intel_region_release(&intelBuffer->region);
-   free(intelBuffer);
-}
-
-
-const struct __DriverAPIRec driDriverAPI = {
-   .InitScreen          = intelInitScreen2,
-   .DestroyScreen       = intelDestroyScreen,
-   .CreateContext       = intelCreateContext,
-   .DestroyContext      = intelDestroyContext,
-   .CreateBuffer        = intelCreateBuffer,
-   .DestroyBuffer       = intelDestroyBuffer,
-   .MakeCurrent                 = intelMakeCurrent,
-   .UnbindContext       = intelUnbindContext,
-   .AllocateBuffer       = intelAllocateBuffer,
-   .ReleaseBuffer        = intelReleaseBuffer
-};
-
-/* This is the table of extensions that the loader will dlsym() for. */
-PUBLIC const __DRIextension *__driDriverExtensions[] = {
-    &driCoreExtension.base,
-    &driDRI2Extension.base,
-    NULL
-};
diff --git a/src/mesa/drivers/dri/intel/intel_state.c b/src/mesa/drivers/dri/intel/intel_state.c
deleted file mode 100644 (file)
index 6a817cd..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/macros.h"
-#include "main/enums.h"
-#include "main/colormac.h"
-#include "main/dd.h"
-
-#include "intel_screen.h"
-#include "intel_context.h"
-
-int
-intel_translate_shadow_compare_func(GLenum func)
-{
-   switch (func) {
-   case GL_NEVER: 
-       return COMPAREFUNC_ALWAYS;
-   case GL_LESS: 
-       return COMPAREFUNC_LEQUAL;
-   case GL_LEQUAL: 
-       return COMPAREFUNC_LESS;
-   case GL_GREATER: 
-       return COMPAREFUNC_GEQUAL;
-   case GL_GEQUAL: 
-      return COMPAREFUNC_GREATER;
-   case GL_NOTEQUAL: 
-      return COMPAREFUNC_EQUAL;
-   case GL_EQUAL: 
-      return COMPAREFUNC_NOTEQUAL;
-   case GL_ALWAYS: 
-       return COMPAREFUNC_NEVER;
-   }
-
-   fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, func);
-   return COMPAREFUNC_NEVER;
-}
-
-int
-intel_translate_compare_func(GLenum func)
-{
-   switch (func) {
-   case GL_NEVER:
-      return COMPAREFUNC_NEVER;
-   case GL_LESS:
-      return COMPAREFUNC_LESS;
-   case GL_LEQUAL:
-      return COMPAREFUNC_LEQUAL;
-   case GL_GREATER:
-      return COMPAREFUNC_GREATER;
-   case GL_GEQUAL:
-      return COMPAREFUNC_GEQUAL;
-   case GL_NOTEQUAL:
-      return COMPAREFUNC_NOTEQUAL;
-   case GL_EQUAL:
-      return COMPAREFUNC_EQUAL;
-   case GL_ALWAYS:
-      return COMPAREFUNC_ALWAYS;
-   }
-
-   fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, func);
-   return COMPAREFUNC_ALWAYS;
-}
-
-int
-intel_translate_stencil_op(GLenum op)
-{
-   switch (op) {
-   case GL_KEEP:
-      return STENCILOP_KEEP;
-   case GL_ZERO:
-      return STENCILOP_ZERO;
-   case GL_REPLACE:
-      return STENCILOP_REPLACE;
-   case GL_INCR:
-      return STENCILOP_INCRSAT;
-   case GL_DECR:
-      return STENCILOP_DECRSAT;
-   case GL_INCR_WRAP:
-      return STENCILOP_INCR;
-   case GL_DECR_WRAP:
-      return STENCILOP_DECR;
-   case GL_INVERT:
-      return STENCILOP_INVERT;
-   default:
-      return STENCILOP_ZERO;
-   }
-}
-
-int
-intel_translate_blend_factor(GLenum factor)
-{
-   switch (factor) {
-   case GL_ZERO:
-      return BLENDFACT_ZERO;
-   case GL_SRC_ALPHA:
-      return BLENDFACT_SRC_ALPHA;
-   case GL_ONE:
-      return BLENDFACT_ONE;
-   case GL_SRC_COLOR:
-      return BLENDFACT_SRC_COLR;
-   case GL_ONE_MINUS_SRC_COLOR:
-      return BLENDFACT_INV_SRC_COLR;
-   case GL_DST_COLOR:
-      return BLENDFACT_DST_COLR;
-   case GL_ONE_MINUS_DST_COLOR:
-      return BLENDFACT_INV_DST_COLR;
-   case GL_ONE_MINUS_SRC_ALPHA:
-      return BLENDFACT_INV_SRC_ALPHA;
-   case GL_DST_ALPHA:
-      return BLENDFACT_DST_ALPHA;
-   case GL_ONE_MINUS_DST_ALPHA:
-      return BLENDFACT_INV_DST_ALPHA;
-   case GL_SRC_ALPHA_SATURATE:
-      return BLENDFACT_SRC_ALPHA_SATURATE;
-   case GL_CONSTANT_COLOR:
-      return BLENDFACT_CONST_COLOR;
-   case GL_ONE_MINUS_CONSTANT_COLOR:
-      return BLENDFACT_INV_CONST_COLOR;
-   case GL_CONSTANT_ALPHA:
-      return BLENDFACT_CONST_ALPHA;
-   case GL_ONE_MINUS_CONSTANT_ALPHA:
-      return BLENDFACT_INV_CONST_ALPHA;
-   }
-
-   fprintf(stderr, "Unknown value in %s: %x\n", __FUNCTION__, factor);
-   return BLENDFACT_ZERO;
-}
-
-int
-intel_translate_logic_op(GLenum opcode)
-{
-   switch (opcode) {
-   case GL_CLEAR:
-      return LOGICOP_CLEAR;
-   case GL_AND:
-      return LOGICOP_AND;
-   case GL_AND_REVERSE:
-      return LOGICOP_AND_RVRSE;
-   case GL_COPY:
-      return LOGICOP_COPY;
-   case GL_COPY_INVERTED:
-      return LOGICOP_COPY_INV;
-   case GL_AND_INVERTED:
-      return LOGICOP_AND_INV;
-   case GL_NOOP:
-      return LOGICOP_NOOP;
-   case GL_XOR:
-      return LOGICOP_XOR;
-   case GL_OR:
-      return LOGICOP_OR;
-   case GL_OR_INVERTED:
-      return LOGICOP_OR_INV;
-   case GL_NOR:
-      return LOGICOP_NOR;
-   case GL_EQUIV:
-      return LOGICOP_EQUIV;
-   case GL_INVERT:
-      return LOGICOP_INV;
-   case GL_OR_REVERSE:
-      return LOGICOP_OR_RVRSE;
-   case GL_NAND:
-      return LOGICOP_NAND;
-   case GL_SET:
-      return LOGICOP_SET;
-   default:
-      return LOGICOP_SET;
-   }
-}
diff --git a/src/mesa/drivers/dri/intel/intel_syncobj.c b/src/mesa/drivers/dri/intel/intel_syncobj.c
deleted file mode 100644 (file)
index 9657d9a..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright Â© 2008 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- *    Eric Anholt <eric@anholt.net>
- *
- */
-
-/** @file intel_syncobj.c
- *
- * Support for ARB_sync
- *
- * ARB_sync is implemented by flushing the current batchbuffer and keeping a
- * reference on it.  We can then check for completion or wait for completion
- * using the normal buffer object mechanisms.  This does mean that if an
- * application is using many sync objects, it will emit small batchbuffers
- * which may end up being a significant overhead.  In other tests of removing
- * gratuitous batchbuffer syncs in Mesa, it hasn't appeared to be a significant
- * performance bottleneck, though.
- */
-
-#include "main/simple_list.h"
-#include "main/imports.h"
-
-#include "intel_context.h"
-#include "intel_batchbuffer.h"
-#include "intel_reg.h"
-
-static struct gl_sync_object *
-intel_new_sync_object(struct gl_context *ctx, GLuint id)
-{
-   struct intel_sync_object *sync;
-
-   sync = calloc(1, sizeof(struct intel_sync_object));
-
-   return &sync->Base;
-}
-
-static void
-intel_delete_sync_object(struct gl_context *ctx, struct gl_sync_object *s)
-{
-   struct intel_sync_object *sync = (struct intel_sync_object *)s;
-
-   drm_intel_bo_unreference(sync->bo);
-   free(sync);
-}
-
-static void
-intel_fence_sync(struct gl_context *ctx, struct gl_sync_object *s,
-              GLenum condition, GLbitfield flags)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_sync_object *sync = (struct intel_sync_object *)s;
-
-   assert(condition == GL_SYNC_GPU_COMMANDS_COMPLETE);
-   intel_batchbuffer_emit_mi_flush(intel);
-
-   sync->bo = intel->batch.bo;
-   drm_intel_bo_reference(sync->bo);
-
-   intel_flush(ctx);
-}
-
-static void intel_client_wait_sync(struct gl_context *ctx, struct gl_sync_object *s,
-                                GLbitfield flags, GLuint64 timeout)
-{
-   struct intel_sync_object *sync = (struct intel_sync_object *)s;
-
-   if (sync->bo && drm_intel_gem_bo_wait(sync->bo, timeout) == 0) {
-      s->StatusFlag = 1;
-      drm_intel_bo_unreference(sync->bo);
-      sync->bo = NULL;
-   }
-}
-
-/* We have nothing to do for WaitSync.  Our GL command stream is sequential,
- * so given that the sync object has already flushed the batchbuffer,
- * any batchbuffers coming after this waitsync will naturally not occur until
- * the previous one is done.
- */
-static void intel_server_wait_sync(struct gl_context *ctx, struct gl_sync_object *s,
-                                GLbitfield flags, GLuint64 timeout)
-{
-}
-
-static void intel_check_sync(struct gl_context *ctx, struct gl_sync_object *s)
-{
-   struct intel_sync_object *sync = (struct intel_sync_object *)s;
-
-   if (sync->bo && !drm_intel_bo_busy(sync->bo)) {
-      drm_intel_bo_unreference(sync->bo);
-      sync->bo = NULL;
-      s->StatusFlag = 1;
-   }
-}
-
-void intel_init_syncobj_functions(struct dd_function_table *functions)
-{
-   functions->NewSyncObject = intel_new_sync_object;
-   functions->DeleteSyncObject = intel_delete_sync_object;
-   functions->FenceSync = intel_fence_sync;
-   functions->CheckSync = intel_check_sync;
-   functions->ClientWaitSync = intel_client_wait_sync;
-   functions->ServerWaitSync = intel_server_wait_sync;
-}
diff --git a/src/mesa/drivers/dri/intel/intel_tex.c b/src/mesa/drivers/dri/intel/intel_tex.c
deleted file mode 100644 (file)
index 24f13df..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-#include "swrast/swrast.h"
-#include "main/renderbuffer.h"
-#include "main/texobj.h"
-#include "main/teximage.h"
-#include "main/mipmap.h"
-#include "drivers/common/meta.h"
-#include "intel_context.h"
-#include "intel_mipmap_tree.h"
-#include "intel_tex.h"
-#include "intel_fbo.h"
-
-#define FILE_DEBUG_FLAG DEBUG_TEXTURE
-
-static struct gl_texture_image *
-intelNewTextureImage(struct gl_context * ctx)
-{
-   DBG("%s\n", __FUNCTION__);
-   (void) ctx;
-   return (struct gl_texture_image *) CALLOC_STRUCT(intel_texture_image);
-}
-
-static void
-intelDeleteTextureImage(struct gl_context * ctx, struct gl_texture_image *img)
-{
-   /* nothing special (yet) for intel_texture_image */
-   _mesa_delete_texture_image(ctx, img);
-}
-
-
-static struct gl_texture_object *
-intelNewTextureObject(struct gl_context * ctx, GLuint name, GLenum target)
-{
-   struct intel_texture_object *obj = CALLOC_STRUCT(intel_texture_object);
-
-   (void) ctx;
-
-   DBG("%s\n", __FUNCTION__);
-
-   if (obj == NULL)
-      return NULL;
-
-   _mesa_initialize_texture_object(&obj->base, name, target);
-
-   obj->needs_validate = true;
-
-   return &obj->base;
-}
-
-static void 
-intelDeleteTextureObject(struct gl_context *ctx,
-                        struct gl_texture_object *texObj)
-{
-   struct intel_texture_object *intelObj = intel_texture_object(texObj);
-
-   intel_miptree_release(&intelObj->mt);
-   _mesa_delete_texture_object(ctx, texObj);
-}
-
-static GLboolean
-intel_alloc_texture_image_buffer(struct gl_context *ctx,
-                                struct gl_texture_image *image)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_texture_image *intel_image = intel_texture_image(image);
-   struct gl_texture_object *texobj = image->TexObject;
-   struct intel_texture_object *intel_texobj = intel_texture_object(texobj);
-
-   assert(image->Border == 0);
-
-   /* Quantize sample count */
-   if (image->NumSamples) {
-      image->NumSamples = intel_quantize_num_samples(intel->intelScreen, image->NumSamples);
-      if (!image->NumSamples)
-         return false;
-   }
-
-   /* Because the driver uses AllocTextureImageBuffer() internally, it may end
-    * up mismatched with FreeTextureImageBuffer(), but that is safe to call
-    * multiple times.
-    */
-   ctx->Driver.FreeTextureImageBuffer(ctx, image);
-
-   if (!_swrast_init_texture_image(image))
-      return false;
-
-   if (intel_texobj->mt &&
-       intel_miptree_match_image(intel_texobj->mt, image)) {
-      intel_miptree_reference(&intel_image->mt, intel_texobj->mt);
-      DBG("%s: alloc obj %p level %d %dx%dx%d using object's miptree %p\n",
-          __FUNCTION__, texobj, image->Level,
-          image->Width, image->Height, image->Depth, intel_texobj->mt);
-   } else {
-      intel_image->mt = intel_miptree_create_for_teximage(intel, intel_texobj,
-                                                          intel_image,
-                                                          false);
-
-      /* Even if the object currently has a mipmap tree associated
-       * with it, this one is a more likely candidate to represent the
-       * whole object since our level didn't fit what was there
-       * before, and any lower levels would fit into our miptree.
-       */
-      intel_miptree_reference(&intel_texobj->mt, intel_image->mt);
-
-      DBG("%s: alloc obj %p level %d %dx%dx%d using new miptree %p\n",
-          __FUNCTION__, texobj, image->Level,
-          image->Width, image->Height, image->Depth, intel_image->mt);
-   }
-
-   intel_texobj->needs_validate = true;
-
-   return true;
-}
-
-static void
-intel_free_texture_image_buffer(struct gl_context * ctx,
-                               struct gl_texture_image *texImage)
-{
-   struct intel_texture_image *intelImage = intel_texture_image(texImage);
-
-   DBG("%s\n", __FUNCTION__);
-
-   intel_miptree_release(&intelImage->mt);
-
-   _swrast_free_texture_image_buffer(ctx, texImage);
-}
-
-/**
- * Map texture memory/buffer into user space.
- * Note: the region of interest parameters are ignored here.
- * \param mode  bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT
- * \param mapOut  returns start of mapping of region of interest
- * \param rowStrideOut  returns row stride in bytes
- */
-static void
-intel_map_texture_image(struct gl_context *ctx,
-                       struct gl_texture_image *tex_image,
-                       GLuint slice,
-                       GLuint x, GLuint y, GLuint w, GLuint h,
-                       GLbitfield mode,
-                       GLubyte **map,
-                       GLint *stride)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_texture_image *intel_image = intel_texture_image(tex_image);
-   struct intel_mipmap_tree *mt = intel_image->mt;
-
-   /* Our texture data is always stored in a miptree. */
-   assert(mt);
-
-   /* Check that our caller wasn't confused about how to map a 1D texture. */
-   assert(tex_image->TexObject->Target != GL_TEXTURE_1D_ARRAY ||
-         h == 1);
-
-   /* intel_miptree_map operates on a unified "slice" number that references the
-    * cube face, since it's all just slices to the miptree code.
-    */
-   if (tex_image->TexObject->Target == GL_TEXTURE_CUBE_MAP)
-      slice = tex_image->Face;
-
-   intel_miptree_map(intel, mt, tex_image->Level, slice, x, y, w, h, mode,
-                    (void **)map, stride);
-}
-
-static void
-intel_unmap_texture_image(struct gl_context *ctx,
-                         struct gl_texture_image *tex_image, GLuint slice)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_texture_image *intel_image = intel_texture_image(tex_image);
-   struct intel_mipmap_tree *mt = intel_image->mt;
-
-   if (tex_image->TexObject->Target == GL_TEXTURE_CUBE_MAP)
-      slice = tex_image->Face;
-
-   intel_miptree_unmap(intel, mt, tex_image->Level, slice);
-}
-
-void
-intelInitTextureFuncs(struct dd_function_table *functions)
-{
-   functions->NewTextureObject = intelNewTextureObject;
-   functions->NewTextureImage = intelNewTextureImage;
-   functions->DeleteTextureImage = intelDeleteTextureImage;
-   functions->DeleteTexture = intelDeleteTextureObject;
-   functions->AllocTextureImageBuffer = intel_alloc_texture_image_buffer;
-   functions->FreeTextureImageBuffer = intel_free_texture_image_buffer;
-   functions->MapTextureImage = intel_map_texture_image;
-   functions->UnmapTextureImage = intel_unmap_texture_image;
-}
diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c
deleted file mode 100644 (file)
index d018cec..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-#include "main/mtypes.h"
-#include "main/enums.h"
-#include "main/image.h"
-#include "main/teximage.h"
-#include "main/texstate.h"
-#include "main/fbobject.h"
-
-#include "drivers/common/meta.h"
-
-#include "intel_screen.h"
-#include "intel_context.h"
-#include "intel_mipmap_tree.h"
-#include "intel_regions.h"
-#include "intel_fbo.h"
-#include "intel_tex.h"
-#include "intel_blit.h"
-#ifndef I915
-#include "brw_context.h"
-#endif
-
-#define FILE_DEBUG_FLAG DEBUG_TEXTURE
-
-
-static bool
-intel_copy_texsubimage(struct intel_context *intel,
-                       struct intel_texture_image *intelImage,
-                       GLint dstx, GLint dsty, GLint slice,
-                       struct intel_renderbuffer *irb,
-                       GLint x, GLint y, GLsizei width, GLsizei height)
-{
-   const GLenum internalFormat = intelImage->base.Base.InternalFormat;
-
-   intel_prepare_render(intel);
-
-   /* glCopyTexSubImage() can be called on a multisampled renderbuffer (if
-    * that renderbuffer is associated with the window system framebuffer),
-    * however the hardware blitter can't handle this case, so fall back to
-    * meta (which can, since it uses ReadPixels).
-    */
-   if (irb->Base.Base.NumSamples != 0)
-      return false;
-
-   /* glCopyTexSubImage() can't be called on a multisampled texture. */
-   assert(intelImage->base.Base.NumSamples == 0);
-
-   if (!intelImage->mt || !irb || !irb->mt) {
-      if (unlikely(INTEL_DEBUG & DEBUG_PERF))
-        fprintf(stderr, "%s fail %p %p (0x%08x)\n",
-                __FUNCTION__, intelImage->mt, irb, internalFormat);
-      return false;
-   }
-
-   /* blit from src buffer to texture */
-   if (!intel_miptree_blit(intel,
-                           irb->mt, irb->mt_level, irb->mt_layer,
-                           x, y, irb->Base.Base.Name == 0,
-                           intelImage->mt, intelImage->base.Base.Level,
-                           intelImage->base.Base.Face + slice,
-                           dstx, dsty, false,
-                           width, height, GL_COPY)) {
-      return false;
-   }
-
-   return true;
-}
-
-
-static void
-intelCopyTexSubImage(struct gl_context *ctx, GLuint dims,
-                     struct gl_texture_image *texImage,
-                     GLint xoffset, GLint yoffset, GLint slice,
-                     struct gl_renderbuffer *rb,
-                     GLint x, GLint y,
-                     GLsizei width, GLsizei height)
-{
-   struct intel_context *intel = intel_context(ctx);
-
-#ifndef I915
-   /* Try BLORP first.  It can handle almost everything. */
-   if (brw_blorp_copytexsubimage(intel, rb, texImage, slice, x, y,
-                                 xoffset, yoffset, width, height))
-      return;
-#endif
-
-   /* Next, try the BLT engine. */
-   if (intel_copy_texsubimage(intel,
-                              intel_texture_image(texImage),
-                              xoffset, yoffset, slice,
-                              intel_renderbuffer(rb), x, y, width, height)) {
-      return;
-   }
-
-   /* Finally, fall back to meta.  This will likely be slow. */
-   perf_debug("%s - fallback to swrast\n", __FUNCTION__);
-   _mesa_meta_CopyTexSubImage(ctx, dims, texImage,
-                              xoffset, yoffset, slice,
-                              rb, x, y, width, height);
-}
-
-
-void
-intelInitTextureCopyImageFuncs(struct dd_function_table *functions)
-{
-   functions->CopyTexSubImage = intelCopyTexSubImage;
-}
diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c
deleted file mode 100644 (file)
index b91b2b5..0000000
+++ /dev/null
@@ -1,399 +0,0 @@
-
-#include "main/glheader.h"
-#include "main/macros.h"
-#include "main/mtypes.h"
-#include "main/enums.h"
-#include "main/bufferobj.h"
-#include "main/context.h"
-#include "main/formats.h"
-#include "main/image.h"
-#include "main/pbo.h"
-#include "main/renderbuffer.h"
-#include "main/texcompress.h"
-#include "main/texgetimage.h"
-#include "main/texobj.h"
-#include "main/teximage.h"
-#include "main/texstore.h"
-
-#include "intel_context.h"
-#include "intel_mipmap_tree.h"
-#include "intel_buffer_objects.h"
-#include "intel_batchbuffer.h"
-#include "intel_tex.h"
-#include "intel_blit.h"
-#include "intel_fbo.h"
-
-#ifndef I915
-#include "brw_context.h"
-#endif
-
-#define FILE_DEBUG_FLAG DEBUG_TEXTURE
-
-/* Work back from the specified level of the image to the baselevel and create a
- * miptree of that size.
- */
-struct intel_mipmap_tree *
-intel_miptree_create_for_teximage(struct intel_context *intel,
-                                 struct intel_texture_object *intelObj,
-                                 struct intel_texture_image *intelImage,
-                                 bool expect_accelerated_upload)
-{
-   GLuint firstLevel;
-   GLuint lastLevel;
-   int width, height, depth;
-   GLuint i;
-
-   intel_miptree_get_dimensions_for_image(&intelImage->base.Base,
-                                          &width, &height, &depth);
-
-   DBG("%s\n", __FUNCTION__);
-
-   if (intelImage->base.Base.Level > intelObj->base.BaseLevel &&
-       (width == 1 ||
-        (intelObj->base.Target != GL_TEXTURE_1D && height == 1) ||
-        (intelObj->base.Target == GL_TEXTURE_3D && depth == 1))) {
-      /* For this combination, we're at some lower mipmap level and
-       * some important dimension is 1.  We can't extrapolate up to a
-       * likely base level width/height/depth for a full mipmap stack
-       * from this info, so just allocate this one level.
-       */
-      firstLevel = intelImage->base.Base.Level;
-      lastLevel = intelImage->base.Base.Level;
-   } else {
-      /* If this image disrespects BaseLevel, allocate from level zero.
-       * Usually BaseLevel == 0, so it's unlikely to happen.
-       */
-      if (intelImage->base.Base.Level < intelObj->base.BaseLevel)
-        firstLevel = 0;
-      else
-        firstLevel = intelObj->base.BaseLevel;
-
-      /* Figure out image dimensions at start level. */
-      for (i = intelImage->base.Base.Level; i > firstLevel; i--) {
-        width <<= 1;
-        if (height != 1)
-           height <<= 1;
-        if (depth != 1)
-           depth <<= 1;
-      }
-
-      /* Guess a reasonable value for lastLevel.  This is probably going
-       * to be wrong fairly often and might mean that we have to look at
-       * resizable buffers, or require that buffers implement lazy
-       * pagetable arrangements.
-       */
-      if ((intelObj->base.Sampler.MinFilter == GL_NEAREST ||
-          intelObj->base.Sampler.MinFilter == GL_LINEAR) &&
-         intelImage->base.Base.Level == firstLevel &&
-         (intel->gen < 4 || firstLevel == 0)) {
-        lastLevel = firstLevel;
-      } else {
-        lastLevel = (firstLevel +
-                      _mesa_get_tex_max_num_levels(intelObj->base.Target,
-                                                   width, height, depth) - 1);
-      }
-   }
-
-   return intel_miptree_create(intel,
-                              intelObj->base.Target,
-                              intelImage->base.Base.TexFormat,
-                              firstLevel,
-                              lastLevel,
-                              width,
-                              height,
-                              depth,
-                              expect_accelerated_upload,
-                               intelImage->base.Base.NumSamples,
-                               INTEL_MIPTREE_TILING_ANY);
-}
-
-/* XXX: Do this for TexSubImage also:
- */
-static bool
-try_pbo_upload(struct gl_context *ctx,
-               struct gl_texture_image *image,
-               const struct gl_pixelstore_attrib *unpack,
-              GLenum format, GLenum type, const void *pixels)
-{
-   struct intel_texture_image *intelImage = intel_texture_image(image);
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj);
-   GLuint src_offset;
-   drm_intel_bo *src_buffer;
-
-   if (!_mesa_is_bufferobj(unpack->BufferObj))
-      return false;
-
-   DBG("trying pbo upload\n");
-
-   if (intel->ctx._ImageTransferState ||
-       unpack->SkipPixels || unpack->SkipRows) {
-      DBG("%s: image transfer\n", __FUNCTION__);
-      return false;
-   }
-
-   ctx->Driver.AllocTextureImageBuffer(ctx, image);
-
-   if (!intelImage->mt) {
-      DBG("%s: no miptree\n", __FUNCTION__);
-      return false;
-   }
-
-   if (!_mesa_format_matches_format_and_type(intelImage->mt->format,
-                                             format, type, false)) {
-      DBG("%s: format mismatch (upload to %s with format 0x%x, type 0x%x)\n",
-         __FUNCTION__, _mesa_get_format_name(intelImage->mt->format),
-         format, type);
-      return false;
-   }
-
-   if (image->TexObject->Target == GL_TEXTURE_1D_ARRAY ||
-       image->TexObject->Target == GL_TEXTURE_2D_ARRAY) {
-      DBG("%s: no support for array textures\n", __FUNCTION__);
-      return false;
-   }
-
-   src_buffer = intel_bufferobj_source(intel, pbo, 64, &src_offset);
-   /* note: potential 64-bit ptr to 32-bit int cast */
-   src_offset += (GLuint) (unsigned long) pixels;
-
-   int src_stride =
-      _mesa_image_row_stride(unpack, image->Width, format, type);
-
-   struct intel_mipmap_tree *pbo_mt =
-      intel_miptree_create_for_bo(intel,
-                                  src_buffer,
-                                  intelImage->mt->format,
-                                  src_offset,
-                                  image->Width, image->Height,
-                                  src_stride, I915_TILING_NONE);
-   if (!pbo_mt)
-      return false;
-
-   if (!intel_miptree_blit(intel,
-                           pbo_mt, 0, 0,
-                           0, 0, false,
-                           intelImage->mt, image->Level, image->Face,
-                           0, 0, false,
-                           image->Width, image->Height, GL_COPY)) {
-      DBG("%s: blit failed\n", __FUNCTION__);
-      return false;
-   }
-
-   intel_miptree_release(&pbo_mt);
-
-   DBG("%s: success\n", __FUNCTION__);
-   return true;
-}
-
-static void
-intelTexImage(struct gl_context * ctx,
-              GLuint dims,
-              struct gl_texture_image *texImage,
-              GLenum format, GLenum type, const void *pixels,
-              const struct gl_pixelstore_attrib *unpack)
-{
-   bool ok;
-
-   DBG("%s target %s level %d %dx%dx%d\n", __FUNCTION__,
-       _mesa_lookup_enum_by_nr(texImage->TexObject->Target),
-       texImage->Level, texImage->Width, texImage->Height, texImage->Depth);
-
-   ok = intel_texsubimage_tiled_memcpy(ctx, dims, texImage,
-                                       0, 0, 0, /*x,y,z offsets*/
-                                       texImage->Width,
-                                       texImage->Height,
-                                       texImage->Depth,
-                                       format, type, pixels, unpack,
-                                       true /*for_glTexImage*/);
-   if (ok)
-      return;
-
-   /* Attempt to use the blitter for PBO image uploads.
-    */
-   if (dims <= 2 &&
-       try_pbo_upload(ctx, texImage, unpack, format, type, pixels)) {
-      return;
-   }
-
-   DBG("%s: upload image %dx%dx%d pixels %p\n",
-       __FUNCTION__, texImage->Width, texImage->Height, texImage->Depth,
-       pixels);
-
-   _mesa_store_teximage(ctx, dims, texImage,
-                        format, type, pixels, unpack);
-}
-
-
-/**
- * Binds a region to a texture image, like it was uploaded by glTexImage2D().
- *
- * Used for GLX_EXT_texture_from_pixmap and EGL image extensions,
- */
-static void
-intel_set_texture_image_region(struct gl_context *ctx,
-                              struct gl_texture_image *image,
-                              struct intel_region *region,
-                              GLenum target,
-                              GLenum internalFormat,
-                              gl_format format,
-                               uint32_t offset,
-                               GLuint width,
-                               GLuint height,
-                               GLuint tile_x,
-                               GLuint tile_y)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_texture_image *intel_image = intel_texture_image(image);
-   struct gl_texture_object *texobj = image->TexObject;
-   struct intel_texture_object *intel_texobj = intel_texture_object(texobj);
-   bool has_surface_tile_offset = false;
-   uint32_t draw_x, draw_y;
-
-   _mesa_init_teximage_fields(&intel->ctx, image,
-                             width, height, 1,
-                             0, internalFormat, format);
-
-   ctx->Driver.FreeTextureImageBuffer(ctx, image);
-
-   intel_image->mt = intel_miptree_create_layout(intel, target, image->TexFormat,
-                                                 0, 0,
-                                                 width, height, 1,
-                                                 true, 0 /* num_samples */);
-   if (intel_image->mt == NULL)
-       return;
-   intel_region_reference(&intel_image->mt->region, region);
-   intel_image->mt->total_width = width;
-   intel_image->mt->total_height = height;
-   intel_image->mt->level[0].slice[0].x_offset = tile_x;
-   intel_image->mt->level[0].slice[0].y_offset = tile_y;
-
-   intel_miptree_get_tile_offsets(intel_image->mt, 0, 0, &draw_x, &draw_y);
-#ifndef I915
-   has_surface_tile_offset = brw_context(ctx)->has_surface_tile_offset;
-#endif
-
-   /* From "OES_EGL_image" error reporting. We report GL_INVALID_OPERATION
-    * for EGL images from non-tile aligned sufaces in gen4 hw and earlier which has
-    * trouble resolving back to destination image due to alignment issues.
-    */
-   if (!has_surface_tile_offset &&
-       (draw_x != 0 || draw_y != 0)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, __func__);
-      intel_miptree_release(&intel_image->mt);
-      return;
-   }
-
-   intel_texobj->needs_validate = true;
-
-   intel_image->mt->offset = offset;
-   assert(region->pitch % region->cpp == 0);
-   intel_image->base.RowStride = region->pitch / region->cpp;
-
-   /* Immediately validate the image to the object. */
-   intel_miptree_reference(&intel_texobj->mt, intel_image->mt);
-}
-
-void
-intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
-                  GLint texture_format,
-                  __DRIdrawable *dPriv)
-{
-   struct gl_framebuffer *fb = dPriv->driverPrivate;
-   struct intel_context *intel = pDRICtx->driverPrivate;
-   struct gl_context *ctx = &intel->ctx;
-   struct intel_texture_object *intelObj;
-   struct intel_renderbuffer *rb;
-   struct gl_texture_object *texObj;
-   struct gl_texture_image *texImage;
-   int level = 0, internalFormat = 0;
-   gl_format texFormat = MESA_FORMAT_NONE;
-
-   texObj = _mesa_get_current_tex_object(ctx, target);
-   intelObj = intel_texture_object(texObj);
-
-   if (!intelObj)
-      return;
-
-   if (dPriv->lastStamp != dPriv->dri2.stamp ||
-       !pDRICtx->driScreenPriv->dri2.useInvalidate)
-      intel_update_renderbuffers(pDRICtx, dPriv);
-
-   rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
-   /* If the region isn't set, then intel_update_renderbuffers was unable
-    * to get the buffers for the drawable.
-    */
-   if (!rb || !rb->mt)
-      return;
-
-   if (rb->mt->cpp == 4) {
-      if (texture_format == __DRI_TEXTURE_FORMAT_RGB) {
-         internalFormat = GL_RGB;
-         texFormat = MESA_FORMAT_XRGB8888;
-      }
-      else {
-         internalFormat = GL_RGBA;
-         texFormat = MESA_FORMAT_ARGB8888;
-      }
-   } else if (rb->mt->cpp == 2) {
-      internalFormat = GL_RGB;
-      texFormat = MESA_FORMAT_RGB565;
-   }
-
-   _mesa_lock_texture(&intel->ctx, texObj);
-   texImage = _mesa_get_tex_image(ctx, texObj, target, level);
-   intel_miptree_make_shareable(intel, rb->mt);
-   intel_set_texture_image_region(ctx, texImage, rb->mt->region, target,
-                                  internalFormat, texFormat, 0,
-                                  rb->mt->region->width,
-                                  rb->mt->region->height,
-                                  0, 0);
-   _mesa_unlock_texture(&intel->ctx, texObj);
-}
-
-void
-intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
-{
-   /* The old interface didn't have the format argument, so copy our
-    * implementation's behavior at the time.
-    */
-   intelSetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
-}
-
-static void
-intel_image_target_texture_2d(struct gl_context *ctx, GLenum target,
-                             struct gl_texture_object *texObj,
-                             struct gl_texture_image *texImage,
-                             GLeglImageOES image_handle)
-{
-   struct intel_context *intel = intel_context(ctx);
-   __DRIscreen *screen;
-   __DRIimage *image;
-
-   screen = intel->intelScreen->driScrnPriv;
-   image = screen->dri2.image->lookupEGLImage(screen, image_handle,
-                                             screen->loaderPrivate);
-   if (image == NULL)
-      return;
-
-   /* Disallow depth/stencil textures: we don't have a way to pass the
-    * separate stencil miptree of a GL_DEPTH_STENCIL texture through.
-    */
-   if (image->has_depthstencil) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, __func__);
-      return;
-   }
-
-   intel_set_texture_image_region(ctx, texImage, image->region,
-                                 target, image->internal_format,
-                                  image->format, image->offset,
-                                  image->width,  image->height,
-                                  image->tile_x, image->tile_y);
-}
-
-void
-intelInitTextureImageFuncs(struct dd_function_table *functions)
-{
-   functions->TexImage = intelTexImage;
-   functions->EGLImageTargetTexture2D = intel_image_target_texture_2d;
-}
diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c
deleted file mode 100644 (file)
index fbb6520..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
- /*
-  * Authors:
-  *   Keith Whitwell <keith@tungstengraphics.com>
-  *   Michel Dänzer <michel@tungstengraphics.com>
-  */
-
-#include "intel_mipmap_tree.h"
-#include "intel_tex_layout.h"
-#include "intel_context.h"
-
-#include "main/image.h"
-#include "main/macros.h"
-
-static unsigned int
-intel_horizontal_texture_alignment_unit(struct intel_context *intel,
-                                       gl_format format)
-{
-   /**
-    * From the "Alignment Unit Size" section of various specs, namely:
-    * - Gen3 Spec: "Memory Data Formats" Volume,         Section 1.20.1.4
-    * - i965 and G45 PRMs:             Volume 1,         Section 6.17.3.4.
-    * - Ironlake and Sandybridge PRMs: Volume 1, Part 1, Section 7.18.3.4
-    * - BSpec (for Ivybridge and slight variations in separate stencil)
-    *
-    * +----------------------------------------------------------------------+
-    * |                                        | alignment unit width  ("i") |
-    * | Surface Property                       |-----------------------------|
-    * |                                        | 915 | 965 | ILK | SNB | IVB |
-    * +----------------------------------------------------------------------+
-    * | YUV 4:2:2 format                       |  8  |  4  |  4  |  4  |  4  |
-    * | BC1-5 compressed format (DXTn/S3TC)    |  4  |  4  |  4  |  4  |  4  |
-    * | FXT1  compressed format                |  8  |  8  |  8  |  8  |  8  |
-    * | Depth Buffer (16-bit)                  |  4  |  4  |  4  |  4  |  8  |
-    * | Depth Buffer (other)                   |  4  |  4  |  4  |  4  |  4  |
-    * | Separate Stencil Buffer                | N/A | N/A |  8  |  8  |  8  |
-    * | All Others                             |  4  |  4  |  4  |  4  |  4  |
-    * +----------------------------------------------------------------------+
-    *
-    * On IVB+, non-special cases can be overridden by setting the SURFACE_STATE
-    * "Surface Horizontal Alignment" field to HALIGN_4 or HALIGN_8.
-    */
-    if (_mesa_is_format_compressed(format)) {
-       /* The hardware alignment requirements for compressed textures
-        * happen to match the block boundaries.
-        */
-      unsigned int i, j;
-      _mesa_get_format_block_size(format, &i, &j);
-      return i;
-    }
-
-   if (format == MESA_FORMAT_S8)
-      return 8;
-
-   /* The depth alignment requirements in the table above are for rendering to
-    * depth miplevels using the LOD control fields.  We don't use LOD control
-    * fields, and instead use page offsets plus intra-tile x/y offsets, which
-    * require that the low 3 bits are zero.  To reduce the number of x/y
-    * offset workaround blits we do, align the X to 8, which depth texturing
-    * can handle (sadly, it can't handle 8 in the Y direction).
-    */
-   if (intel->gen >= 7 &&
-       _mesa_get_format_base_format(format) == GL_DEPTH_COMPONENT)
-      return 8;
-
-   return 4;
-}
-
-static unsigned int
-intel_vertical_texture_alignment_unit(struct intel_context *intel,
-                                     gl_format format)
-{
-   /**
-    * From the "Alignment Unit Size" section of various specs, namely:
-    * - Gen3 Spec: "Memory Data Formats" Volume,         Section 1.20.1.4
-    * - i965 and G45 PRMs:             Volume 1,         Section 6.17.3.4.
-    * - Ironlake and Sandybridge PRMs: Volume 1, Part 1, Section 7.18.3.4
-    * - BSpec (for Ivybridge and slight variations in separate stencil)
-    *
-    * +----------------------------------------------------------------------+
-    * |                                        | alignment unit height ("j") |
-    * | Surface Property                       |-----------------------------|
-    * |                                        | 915 | 965 | ILK | SNB | IVB |
-    * +----------------------------------------------------------------------+
-    * | BC1-5 compressed format (DXTn/S3TC)    |  4  |  4  |  4  |  4  |  4  |
-    * | FXT1  compressed format                |  4  |  4  |  4  |  4  |  4  |
-    * | Depth Buffer                           |  2  |  2  |  2  |  4  |  4  |
-    * | Separate Stencil Buffer                | N/A | N/A | N/A |  4  |  8  |
-    * | Multisampled (4x or 8x) render target  | N/A | N/A | N/A |  4  |  4  |
-    * | All Others                             |  2  |  2  |  2  |  2  |  2  |
-    * +----------------------------------------------------------------------+
-    *
-    * On SNB+, non-special cases can be overridden by setting the SURFACE_STATE
-    * "Surface Vertical Alignment" field to VALIGN_2 or VALIGN_4.
-    *
-    * We currently don't support multisampling.
-    */
-   if (_mesa_is_format_compressed(format))
-      return 4;
-
-   if (format == MESA_FORMAT_S8)
-      return intel->gen >= 7 ? 8 : 4;
-
-   GLenum base_format = _mesa_get_format_base_format(format);
-
-   if (intel->gen >= 6 &&
-       (base_format == GL_DEPTH_COMPONENT ||
-       base_format == GL_DEPTH_STENCIL)) {
-      return 4;
-   }
-
-   return 2;
-}
-
-void
-intel_get_texture_alignment_unit(struct intel_context *intel,
-                                gl_format format,
-                                unsigned int *w, unsigned int *h)
-{
-   *w = intel_horizontal_texture_alignment_unit(intel, format);
-   *h = intel_vertical_texture_alignment_unit(intel, format);
-}
-
-void i945_miptree_layout_2d(struct intel_mipmap_tree *mt)
-{
-   GLuint level;
-   GLuint x = 0;
-   GLuint y = 0;
-   GLuint width = mt->physical_width0;
-   GLuint height = mt->physical_height0;
-   GLuint depth = mt->physical_depth0; /* number of array layers. */
-
-   mt->total_width = mt->physical_width0;
-
-   if (mt->compressed) {
-       mt->total_width = ALIGN(mt->physical_width0, mt->align_w);
-   }
-
-   /* May need to adjust width to accomodate the placement of
-    * the 2nd mipmap.  This occurs when the alignment
-    * constraints of mipmap placement push the right edge of the
-    * 2nd mipmap out past the width of its parent.
-    */
-   if (mt->first_level != mt->last_level) {
-       GLuint mip1_width;
-
-       if (mt->compressed) {
-          mip1_width = ALIGN(minify(mt->physical_width0, 1), mt->align_w) +
-             ALIGN(minify(mt->physical_width0, 2), mt->align_w);
-       } else {
-          mip1_width = ALIGN(minify(mt->physical_width0, 1), mt->align_w) +
-             minify(mt->physical_width0, 2);
-       }
-
-       if (mip1_width > mt->total_width) {
-           mt->total_width = mip1_width;
-       }
-   }
-
-   mt->total_height = 0;
-
-   for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
-      GLuint img_height;
-
-      intel_miptree_set_level_info(mt, level, x, y, width,
-                                  height, depth);
-
-      img_height = ALIGN(height, mt->align_h);
-      if (mt->compressed)
-        img_height /= mt->align_h;
-
-      /* Because the images are packed better, the final offset
-       * might not be the maximal one:
-       */
-      mt->total_height = MAX2(mt->total_height, y + img_height);
-
-      /* Layout_below: step right after second mipmap.
-       */
-      if (level == mt->first_level + 1) {
-        x += ALIGN(width, mt->align_w);
-      }
-      else {
-        y += img_height;
-      }
-
-      width  = minify(width, 1);
-      height = minify(height, 1);
-   }
-}
diff --git a/src/mesa/drivers/dri/intel/intel_tex_subimage.c b/src/mesa/drivers/dri/intel/intel_tex_subimage.c
deleted file mode 100644 (file)
index f936e9b..0000000
+++ /dev/null
@@ -1,335 +0,0 @@
-
-/**************************************************************************
- * 
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-#include "main/bufferobj.h"
-#include "main/macros.h"
-#include "main/mtypes.h"
-#include "main/pbo.h"
-#include "main/texobj.h"
-#include "main/texstore.h"
-#include "main/texcompress.h"
-#include "main/enums.h"
-
-#include "intel_batchbuffer.h"
-#include "intel_context.h"
-#include "intel_tex.h"
-#include "intel_mipmap_tree.h"
-#include "intel_blit.h"
-
-#define FILE_DEBUG_FLAG DEBUG_TEXTURE
-
-static bool
-intel_blit_texsubimage(struct gl_context * ctx,
-                      struct gl_texture_image *texImage,
-                      GLint xoffset, GLint yoffset,
-                      GLint width, GLint height,
-                      GLenum format, GLenum type, const void *pixels,
-                      const struct gl_pixelstore_attrib *packing)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_texture_image *intelImage = intel_texture_image(texImage);
-
-   /* Try to do a blit upload of the subimage if the texture is
-    * currently busy.
-    */
-   if (!intelImage->mt)
-      return false;
-
-   /* The blitter can't handle Y tiling */
-   if (intelImage->mt->region->tiling == I915_TILING_Y)
-      return false;
-
-   if (texImage->TexObject->Target != GL_TEXTURE_2D)
-      return false;
-
-   /* On gen6, it's probably not worth swapping to the blit ring to do
-    * this because of all the overhead involved.
-    */
-   if (intel->gen >= 6)
-      return false;
-
-   if (!drm_intel_bo_busy(intelImage->mt->region->bo))
-      return false;
-
-   DBG("BLT subimage %s target %s level %d offset %d,%d %dx%d\n",
-       __FUNCTION__,
-       _mesa_lookup_enum_by_nr(texImage->TexObject->Target),
-       texImage->Level, xoffset, yoffset, width, height);
-
-   pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1,
-                                       format, type, pixels, packing,
-                                       "glTexSubImage");
-   if (!pixels)
-      return false;
-
-   struct intel_mipmap_tree *temp_mt =
-      intel_miptree_create(intel, GL_TEXTURE_2D, texImage->TexFormat,
-                           0, 0,
-                           width, height, 1,
-                           false, 0, INTEL_MIPTREE_TILING_NONE);
-   if (!temp_mt)
-      goto err;
-
-   GLubyte *dst = intel_miptree_map_raw(intel, temp_mt);
-   if (!dst)
-      goto err;
-
-   if (!_mesa_texstore(ctx, 2, texImage->_BaseFormat,
-                      texImage->TexFormat,
-                      temp_mt->region->pitch,
-                      &dst,
-                      width, height, 1,
-                      format, type, pixels, packing)) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
-   }
-
-   intel_miptree_unmap_raw(intel, temp_mt);
-
-   bool ret;
-
-   ret = intel_miptree_blit(intel,
-                            temp_mt, 0, 0,
-                            0, 0, false,
-                            intelImage->mt, texImage->Level, texImage->Face,
-                            xoffset, yoffset, false,
-                            width, height, GL_COPY);
-   assert(ret);
-
-   intel_miptree_release(&temp_mt);
-   _mesa_unmap_teximage_pbo(ctx, packing);
-
-   return ret;
-
-err:
-   _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
-   intel_miptree_release(&temp_mt);
-   _mesa_unmap_teximage_pbo(ctx, packing);
-   return false;
-}
-
-/**
- * \brief A fast path for glTexImage and glTexSubImage.
- *
- * \param for_glTexImage Was this called from glTexImage or glTexSubImage?
- *
- * This fast path is taken when the hardware natively supports the texture
- * format (such as GL_BGRA) and when the texture memory is X-tiled. It uploads
- * the texture data by mapping the texture memory without a GTT fence, thus
- * acquiring a tiled view of the memory, and then memcpy'ing sucessive
- * subspans within each tile.
- *
- * This is a performance win over the conventional texture upload path because
- * it avoids the performance penalty of writing through the write-combine
- * buffer. In the conventional texture upload path,
- * texstore.c:store_texsubimage(), the texture memory is mapped through a GTT
- * fence, thus acquiring a linear view of the memory, then each row in the
- * image is memcpy'd. In this fast path, we replace each row's memcpy with
- * a sequence of memcpy's over each bit6 swizzle span in the row.
- *
- * This fast path's use case is Google Chrome's paint rectangles.  Chrome (as
- * of version 21) renders each page as a tiling of 256x256 GL_BGRA textures.
- * Each page's content is initially uploaded with glTexImage2D and damaged
- * regions are updated with glTexSubImage2D. On some workloads, the
- * performance gain of this fastpath on Sandybridge is over 5x.
- */
-bool
-intel_texsubimage_tiled_memcpy(struct gl_context * ctx,
-                               GLuint dims,
-                               struct gl_texture_image *texImage,
-                               GLint xoffset, GLint yoffset, GLint zoffset,
-                               GLsizei width, GLsizei height, GLsizei depth,
-                               GLenum format, GLenum type,
-                               const GLvoid *pixels,
-                               const struct gl_pixelstore_attrib *packing,
-                               bool for_glTexImage)
-{
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_texture_image *image = intel_texture_image(texImage);
-
-   /* The miptree's buffer. */
-   drm_intel_bo *bo;
-
-   int error = 0;
-
-   /* This fastpath is restricted to a specific texture type: level 0 of
-    * a 2D BGRA texture. It could be generalized to support more types by
-    * varying the arithmetic loop below.
-    */
-   if (!intel->has_llc ||
-       format != GL_BGRA ||
-       type != GL_UNSIGNED_BYTE ||
-       texImage->TexFormat != MESA_FORMAT_ARGB8888 ||
-       texImage->TexObject->Target != GL_TEXTURE_2D ||
-       texImage->Level != 0 ||
-       pixels == NULL ||
-       _mesa_is_bufferobj(packing->BufferObj) ||
-       packing->Alignment > 4 ||
-       packing->SkipPixels > 0 ||
-       packing->SkipRows > 0 ||
-       (packing->RowLength != 0 && packing->RowLength != width) ||
-       packing->SwapBytes ||
-       packing->LsbFirst ||
-       packing->Invert)
-      return false;
-
-   if (for_glTexImage)
-      ctx->Driver.AllocTextureImageBuffer(ctx, texImage);
-
-   if (!image->mt ||
-       image->mt->region->tiling != I915_TILING_X) {
-      /* The algorithm below is written only for X-tiled memory. */
-      return false;
-   }
-
-   /* Since we are going to write raw data to the miptree, we need to resolve
-    * any pending fast color clears before we start.
-    */
-   intel_miptree_resolve_color(intel, image->mt);
-
-   bo = image->mt->region->bo;
-
-   if (drm_intel_bo_references(intel->batch.bo, bo)) {
-      perf_debug("Flushing before mapping a referenced bo.\n");
-      intel_batchbuffer_flush(intel);
-   }
-
-   if (unlikely(intel->perf_debug)) {
-      if (drm_intel_bo_busy(bo)) {
-         perf_debug("Mapping a busy BO, causing a stall on the GPU.\n");
-      }
-   }
-
-   error = drm_intel_bo_map(bo, true /*write_enable*/);
-   if (error || bo->virtual == NULL) {
-      DBG("%s: failed to map bo\n", __FUNCTION__);
-      return false;
-   }
-
-   /* We postponed printing this message until having committed to executing
-    * the function.
-    */
-   DBG("%s: level=%d offset=(%d,%d) (w,h)=(%d,%d)\n",
-       __FUNCTION__, texImage->Level, xoffset, yoffset, width, height);
-
-   /* In the tiling algorithm below, some variables are in units of pixels,
-    * others are in units of bytes, and others (such as height) are unitless.
-    * Each variable name is suffixed with its units.
-    */
-
-   const uint32_t x_max_pixels = xoffset + width;
-   const uint32_t y_max_pixels = yoffset + height;
-
-   const uint32_t tile_size_bytes = 4096;
-
-   const uint32_t tile_width_bytes = 512;
-   const uint32_t tile_width_pixels = 128;
-
-   const uint32_t tile_height = 8;
-
-   const uint32_t cpp = 4; /* chars per pixel of GL_BGRA */
-   const uint32_t swizzle_width_pixels = 16;
-
-   const uint32_t stride_bytes = image->mt->region->pitch;
-   const uint32_t width_tiles = stride_bytes / tile_width_bytes;
-
-   for (uint32_t y_pixels = yoffset; y_pixels < y_max_pixels; ++y_pixels) {
-      const uint32_t y_offset_bytes = (y_pixels / tile_height) * width_tiles * tile_size_bytes
-                                    + (y_pixels % tile_height) * tile_width_bytes;
-
-      for (uint32_t x_pixels = xoffset; x_pixels < x_max_pixels; x_pixels += swizzle_width_pixels) {
-         const uint32_t x_offset_bytes = (x_pixels / tile_width_pixels) * tile_size_bytes
-                                       + (x_pixels % tile_width_pixels) * cpp;
-
-         intptr_t offset_bytes = y_offset_bytes + x_offset_bytes;
-         if (intel->has_swizzling) {
-#if 0
-            /* Clear, unoptimized version. */
-            bool bit6 = (offset_bytes >> 6) & 1;
-            bool bit9 = (offset_bytes >> 9) & 1;
-            bool bit10 = (offset_bytes >> 10) & 1;
-
-            if (bit9 ^ bit10)
-               offset_bytes ^= (1 << 6);
-#else
-            /* Optimized, obfuscated version. */
-            offset_bytes ^= ((offset_bytes >> 3) ^ (offset_bytes >> 4))
-                          & (1 << 6);
-#endif
-         }
-
-         const uint32_t swizzle_bound_pixels = ALIGN(x_pixels + 1, swizzle_width_pixels);
-         const uint32_t memcpy_bound_pixels = MIN2(x_max_pixels, swizzle_bound_pixels);
-         const uint32_t copy_size = cpp * (memcpy_bound_pixels - x_pixels);
-
-         memcpy(bo->virtual + offset_bytes, pixels, copy_size);
-         pixels += copy_size;
-         x_pixels -= (x_pixels % swizzle_width_pixels);
-      }
-   }
-
-   drm_intel_bo_unmap(bo);
-   return true;
-}
-
-static void
-intelTexSubImage(struct gl_context * ctx,
-                 GLuint dims,
-                 struct gl_texture_image *texImage,
-                 GLint xoffset, GLint yoffset, GLint zoffset,
-                 GLsizei width, GLsizei height, GLsizei depth,
-                 GLenum format, GLenum type,
-                 const GLvoid * pixels,
-                 const struct gl_pixelstore_attrib *packing)
-{
-   bool ok;
-
-   ok = intel_texsubimage_tiled_memcpy(ctx, dims, texImage,
-                                       xoffset, yoffset, zoffset,
-                                       width, height, depth,
-                                       format, type, pixels, packing,
-                                       false /*for_glTexImage*/);
-   if (ok)
-     return;
-
-   /* The intel_blit_texsubimage() function only handles 2D images */
-   if (dims != 2 || !intel_blit_texsubimage(ctx, texImage,
-                              xoffset, yoffset,
-                              width, height,
-                              format, type, pixels, packing)) {
-      _mesa_store_texsubimage(ctx, dims, texImage,
-                              xoffset, yoffset, zoffset,
-                              width, height, depth,
-                              format, type, pixels, packing);
-   }
-}
-
-void
-intelInitTextureSubImageFuncs(struct dd_function_table *functions)
-{
-   functions->TexSubImage = intelTexSubImage;
-}
diff --git a/src/mesa/drivers/dri/intel/intel_tex_validate.c b/src/mesa/drivers/dri/intel/intel_tex_validate.c
deleted file mode 100644 (file)
index a8a8647..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-#include "main/mtypes.h"
-#include "main/macros.h"
-#include "main/samplerobj.h"
-#include "main/texobj.h"
-
-#include "intel_context.h"
-#include "intel_mipmap_tree.h"
-#include "intel_blit.h"
-#include "intel_tex.h"
-#include "intel_tex_layout.h"
-
-#define FILE_DEBUG_FLAG DEBUG_TEXTURE
-
-/**
- * When validating, we only care about the texture images that could
- * be seen, so for non-mipmapped modes we want to ignore everything
- * but BaseLevel.
- */
-static void
-intel_update_max_level(struct intel_texture_object *intelObj,
-                      struct gl_sampler_object *sampler)
-{
-   struct gl_texture_object *tObj = &intelObj->base;
-   int maxlevel;
-
-   if (sampler->MinFilter == GL_NEAREST ||
-       sampler->MinFilter == GL_LINEAR) {
-      maxlevel = tObj->BaseLevel;
-   } else {
-      maxlevel = tObj->_MaxLevel;
-   }
-
-   if (intelObj->_MaxLevel != maxlevel) {
-      intelObj->_MaxLevel = maxlevel;
-      intelObj->needs_validate = true;
-   }
-}
-
-/*  
- */
-GLuint
-intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit)
-{
-   struct gl_context *ctx = &intel->ctx;
-   struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current;
-   struct intel_texture_object *intelObj = intel_texture_object(tObj);
-   struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit);
-   GLuint face, i;
-   GLuint nr_faces = 0;
-   struct intel_texture_image *firstImage;
-   int width, height, depth;
-
-   /* TBOs require no validation -- they always just point to their BO. */
-   if (tObj->Target == GL_TEXTURE_BUFFER)
-      return true;
-
-   /* We know/require this is true by now: 
-    */
-   assert(intelObj->base._BaseComplete);
-
-   /* What levels must the tree include at a minimum?
-    */
-   intel_update_max_level(intelObj, sampler);
-   if (intelObj->mt && intelObj->mt->first_level != tObj->BaseLevel)
-      intelObj->needs_validate = true;
-
-   if (!intelObj->needs_validate)
-      return true;
-
-   firstImage = intel_texture_image(tObj->Image[0][tObj->BaseLevel]);
-
-   /* Check tree can hold all active levels.  Check tree matches
-    * target, imageFormat, etc.
-    *
-    * For pre-gen4, we have to match first_level == tObj->BaseLevel,
-    * because we don't have the control that gen4 does to make min/mag
-    * determination happen at a nonzero (hardware) baselevel.  Because
-    * of that, we just always relayout on baselevel change.
-    */
-   if (intelObj->mt &&
-       (!intel_miptree_match_image(intelObj->mt, &firstImage->base.Base) ||
-       intelObj->mt->first_level != tObj->BaseLevel ||
-       intelObj->mt->last_level < intelObj->_MaxLevel)) {
-      intel_miptree_release(&intelObj->mt);
-   }
-
-
-   /* May need to create a new tree:
-    */
-   if (!intelObj->mt) {
-      intel_miptree_get_dimensions_for_image(&firstImage->base.Base,
-                                            &width, &height, &depth);
-
-      perf_debug("Creating new %s %dx%dx%d %d..%d miptree to handle finalized "
-                 "texture miptree.\n",
-                 _mesa_get_format_name(firstImage->base.Base.TexFormat),
-                 width, height, depth, tObj->BaseLevel, intelObj->_MaxLevel);
-
-      intelObj->mt = intel_miptree_create(intel,
-                                          intelObj->base.Target,
-                                         firstImage->base.Base.TexFormat,
-                                          tObj->BaseLevel,
-                                          intelObj->_MaxLevel,
-                                          width,
-                                          height,
-                                          depth,
-                                         true,
-                                          0 /* num_samples */,
-                                          INTEL_MIPTREE_TILING_ANY);
-      if (!intelObj->mt)
-         return false;
-   }
-
-   /* Pull in any images not in the object's tree:
-    */
-   nr_faces = _mesa_num_tex_faces(intelObj->base.Target);
-   for (face = 0; face < nr_faces; face++) {
-      for (i = tObj->BaseLevel; i <= intelObj->_MaxLevel; i++) {
-         struct intel_texture_image *intelImage =
-            intel_texture_image(intelObj->base.Image[face][i]);
-        /* skip too small size mipmap */
-        if (intelImage == NULL)
-                break;
-
-         if (intelObj->mt != intelImage->mt) {
-            intel_miptree_copy_teximage(intel, intelImage, intelObj->mt,
-                                        false /* invalidate */);
-         }
-
-         /* After we're done, we'd better agree that our layout is
-          * appropriate, or we'll end up hitting this function again on the
-          * next draw
-          */
-         assert(intel_miptree_match_image(intelObj->mt, &intelImage->base.Base));
-      }
-   }
-
-   intelObj->needs_validate = false;
-
-   return true;
-}